javascript Chrome 65 阻止跨源<a download>。强制下载的客户端解决方法?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/49474775/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Chrome 65 blocks cross-origin <a download>. Client-side workaround to force download?
提问by Leeroy
Chrome 65 removed support for the downloadattribute on anchor elements with cross-origin hrefs:
Chrome 65 移除了对具有 cross-origin s 的锚元素上的download属性的支持:href
Block cross-origin <a download>
To avoid what is essentially a user-mediated cross-origin information leakage, Blink will now ignore the presence of the download attribute on anchor elements with cross origin attributes. Note that this applies to
HTMLAnchorElement.downloadas well as to the element itself.
阻止跨域 <a 下载>
为了避免本质上是用户介导的跨源信息泄漏,Blink 现在将忽略具有跨源属性的锚元素上的下载属性的存在。请注意,这既适用于
HTMLAnchorElement.download元素本身,也适用于元素本身。
This breaks serverless downloads(for cross-origin resources). It has also broken Reddit Enhancement Suite's save image button (RES v5.12.0 fixed thisby using the chrome.downloads API(the extension now requests your permission to Manage downloads).res-media-controls-download)
这会破坏无服务器下载(对于跨源资源)。它还破坏了 Reddit Enhancement Suite 的保存图像按钮 ( RES v5.12.0通过使用chrome.downloads API修复了这个问题(扩展现在请求您的管理下载权限).res-media-controls-download)
Any workaround?
任何解决方法?
More details in the Web spec, thanks @jbmilgrom
Web 规范中的更多详细信息,感谢@jbmilgrom
回答by Leeroy
According to the discussionblob:and data:URLs are unaffected, so here is a workaround using fetchand Blobs.
根据讨论blob:,data:URL 不受影响,因此这里是使用fetchBlob的解决方法。
Client-side force download media
客户端强制下载媒体
function forceDownload(blob, filename) {
var a = document.createElement('a');
a.download = filename;
a.href = blob;
// For Firefox https://stackoverflow.com/a/32226068
document.body.appendChild(a);
a.click();
a.remove();
}
// Current blob size limit is around 500MB for browsers
function downloadResource(url, filename) {
if (!filename) filename = url.split('\').pop().split('/').pop();
fetch(url, {
headers: new Headers({
'Origin': location.origin
}),
mode: 'cors'
})
.then(response => response.blob())
.then(blob => {
let blobUrl = window.URL.createObjectURL(blob);
forceDownload(blobUrl, filename);
})
.catch(e => console.error(e));
}
downloadResource('https://giant.gfycat.com/RemoteBlandBlackrussianterrier.webm');
However, fetch only works on some URLs. You may get a CORS error:
但是,fetch 仅适用于某些 URL。您可能会收到 CORS 错误:
Failed to load https://i.redd.it/l53mxu6n14o01.jpg: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://redditp.com' is therefore not allowed access.
Failed to load https://i.redd.it/l53mxu6n14o01.jpg: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://redditp.com' is therefore not allowed access.
There are extensions that let you intercept and modify or delete websites' security headers:
有一些扩展程序可让您拦截和修改或删除网站的安全标头:
(But setting Access-Control-Allow-Origin: *broke YouTube for me)
(但设置Access-Control-Allow-Origin: *对我来说破坏了 YouTube)
Performance
表现
Please note that this approach isn't very performant! At times I've had downloads stall for <1min. The rest of the page was responsive during this time though. I haven't looked into this, but I imagine creating large Blobs is resource intensive.
请注意,这种方法的性能不是很好!有时我的下载停止了 <1 分钟。不过,页面的其余部分在这段时间内是响应式的。我没有研究过这个,但我认为创建大型 Blob 是资源密集型的。
Violentmonkey / Tampermonkey
暴力猴子 / 篡改猴子
If your use case is userscripts, there's GM_download(options), GM_download(url, name)
如果您的用例是用户脚本,则有 GM_download(options), GM_download(url, name)
? In Tampermonkey this is a beta feature, and you must first set Download Mode:[Browser API ?] in Tampermonkey Dashboard > Settings
? 在 Tampermonkey 中,这是一个测试版功能,您必须首先在Tampermonkey 仪表板 > 设置中设置下载模式:[浏览器 API ?]
回答by jbmilgrom
Apparently, the web specificationchanged at some point to disallow cross-origin downloads. Add content-disposition: attachmentheader in the response and cross-origin downloads may work again.
显然,Web 规范在某些时候更改为禁止跨域下载。content-disposition: attachment在响应中添加标头,跨域下载可能会再次工作。


