Chrome 65 blocks cross-origin <a download>. Client-side workaround to force download?
Solution 1:
According to the discussion blob:
and data:
URLs are unaffected, so here is a workaround using fetch
and Blobs.
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:
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:
ModHeader - Chrome Web Store
(But setting Access-Control-Allow-Origin: *
broke YouTube for me)
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.
Violentmonkey / Tampermonkey
If your use case is userscripts, there's 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
Solution 2:
Apparently, the web specification changed at some point to disallow cross-origin downloads. Add content-disposition: attachment
header in the response and cross-origin downloads may work again.