Reputation: 452
I've got a Google Chrome App (Windows & Mac) written in JavaScript with a menu item to automatically download a log file. I've been successfully using https://github.com/eligrey/FileSaver.js with no problems up until Chrome 65. Now, when the user clicks on the menu item, I get the following console error:
Can't open same-window link to "blob:chrome-extension://lcgcc...1904"; try target="_blank"
So I tried adding target="_blank" and now when I click on the menu item I get a dialog:
There is no application set to open the URL blob:chrome-extension://lcgc...6b11.
Search the App Store for an application that can open this document,
or choose an existing application on your computer.
Clicking "Cancel" on the dialog makes it go away but of course the file isn't downloaded.
Here is a simple jsfiddle from another question (not mine) which has similar code: http://jsfiddle.net/koldev/cW7W5/
var saveData = (function () {
var a = document.createElement("a");
document.body.appendChild(a);
a.style = "display: none";
return function (data, fileName) {
var json = JSON.stringify(data),
blob = new Blob([json], {type: "octet/stream"}),
url = window.URL.createObjectURL(blob);
a.href = url;
a.download = fileName;
a.click();
window.URL.revokeObjectURL(url);
};
}());
var data = { x: 42, s: "hello, world", d: new Date() },
fileName = "my-download.json";
saveData(data, fileName);
I've tried this sample code within my app and it shows the same behavior: an error message without target="_blank" and a dialog with target="_blank".
Note that this code will work fine in the Chrome browser - it automatically downloads the blob file. It's only a problem in Google Chrome apps, and only since I upgraded to Chrome 65.
I know that Google Chrome apps are going away "soon" but in the meantime, until I can find someone to rewrite the entire application, I really need a solution for all of my users (short of telling them to not upgrade Chrome...).
Does anyone know of a different way to automatically download a blob file that won't run into these problems on Chrome Apps? It doesn't need to be cross-browser because it's a Chrome App.
Thanks in advance!
Upvotes: 5
Views: 5993
Reputation: 18700
Ran into the same problem, here is how I solved it and my notes.
Chrome 65 made a change where anchor download attribute is ignored. This causes anchor click to do a redirect instead of a download. This only happens if clicked URL is cross-origin. Apparently the blob: protocol at start of url makes it cross-origin or something.
So, to get around it, use the chrome-platform-only APIs available to chrome apps and extensions. Turns out they added a new API and did not mention it some time ago called chrome.downloads.
So let's say you have a blob object to start. First, add the "downloads" permission to the app in its manifest. This will enable the "chrome.downloads" api.
Then do the following:
const url = URL.createObjectURL(blob);
const args = {url: url};
const callback = function() {};
chrome.downloads.download(args, callback);
URL.revokeObjectURL(url);
I can confirm that I just did this in Chrome 66 on Mac and it now shows the save as dialog as desired.
I am very unhappy with this solution because it is not cross-platform, but at least it works.
API Docs: https://developer.chrome.com/extensions/downloads
Upvotes: 2