Chrome 65阻止了来源<a download="">. Client-side workaround to force download?

时间:2018-03-25 10:24:35

标签: javascript google-chrome frontend tampermonkey

Chrome 65 removed support for the download attribute on anchor elements with cross-origin hrefs:

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.download以及元素本身。

     

Intent to Remove | Chromestatus Tracker | Chromium Bug

这会中断serverless downloads(对于跨源资源)。 它还使用fixed this破坏了Reddit Enhancement Suite的保存图像按钮(.res-media-controls-download RES v5.12.0 chrome.downloads API(扩展现在请求您是管理下载)的权限

任何解决方法?

Web spec中的更多详情,谢谢@jbmilgrom

2 个答案:

答案 0 :(得分:21)

根据discussion blob:data:网址不受影响,因此这里是使用fetch和Blob的解决方法。

客户端强制下载媒体

&#13;
&#13;
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');
&#13;
&#13;
&#13;

但是,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 Web Store

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

性能

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

Violentmonkey / Tampermonkey

如果您的用例是用户脚本,那么GM_download(options), GM_download(url, name)

⚠在Tampermonkey中,这是一项测试版功能,您必须先在 Tampermonkey Dashboard&gt;中设置下载模式 [浏览器API▾]。设置

Tampermonkey Dashboard > Settings > Downloads

答案 1 :(得分:2)

很明显,web specification有所更改,以禁止跨域下载。在响应中添加content-disposition: attachment标头,跨域下载可能会再次起作用。