Chrome 65阻止跨域<a download>.强制下载的客户端解决方法?

Lee*_*roy 17 javascript frontend google-chrome tampermonkey

Chrome 65删除了对具有跨源s的锚元素download属性的支持:href

阻止跨源<a download>

为了避免本质上是用户介导的跨源信息泄漏,Blink现在将忽略具有交叉原点属性的锚元素上的下载属性的存在.请注意,这适用于HTMLAnchorElement.download元素本身.

意图删除 | Chromestatus Tracker | Chromium Bug

这打破了无服务器下载(对于跨源资源).它还破坏了Reddit Enhancement Suite的保存图像按钮(.res-media-controls-download) RES v5.12.0,通过使用chrome.downloads API 解决了这个问题(该扩展现在请求您管理下载的权限)

任何解决方法?

Lee*_*roy 26

根据讨论 blob:data:URL不受影响,因此这里是一个使用fetch和Blob 的解决方法.

客户端强制下载媒体

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');
Run Code Online (Sandbox Code Playgroud)

但是,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.

有一些扩展可让您拦截,修改或删除网站的安全标头:

UnXSS - Chrome网上应用店

(但是Access-Control-Allow-Origin: *为我设置了YouTube)

性能

请注意,这种方法效率不高!有时我的下载速度<1分钟.在此期间,页面的其余部分都是响应式的.我没有调查过这个,但我想创建大型Blob是资源密集型的.

Violentmonkey/Tampermonkey

如果您的用例是userscripts,那就是 GM_download(options), GM_download(url, name)

⚠在Tampermonkey中,这是一个测试版功能,您必须首先在Tampermonkey Dashboard> Settings中设置下载模式: [ BrowserAPI▾ ]

防篡改仪表板>设置>下载

  • 想知道如果文件大小超过 500MB 怎么办?我有什么选择?我需要使用 StreamSaver.js 吗?我还有哪些其他选择?谢谢! (2认同)

jbm*_*rom 13

显然,Web 规范在某些时候更改为禁止跨域下载。content-disposition: attachment在响应中添加标头,跨域下载可能会再次工作。

  • nginx 示例:`add_header Content-Disposition "attachment;"; ` (2认同)