Edit by @eligrey: Please tell Apple how this bug is affecting you in https://bugs.webkit.org/show_bug.cgi?id=102914 if you want this fixed.
Edit by @jimmywarting
The safari bug #102914 has been marked as fixed now
according to the commit position, download attribute is fixed in WebKit v602.1.27.
The latest beta build (Safari Technology Preview) is based on WebKit v602.1.25, and of course doesn't contain this patch, so there's no simple way to test.
In the meantime, if you want to support Safari 7, you'll probably want to use Downloadify (uses Flash, not HTML5).
Issues we have had with Safari
The page you opened redirected you to a page that isn't supported by safari
Safari can't open the page becuse Safari can't be redirected to address that begin with "blob:".
window.onclick = function(){
var blob = new Blob(["Hi"], {type: 'application/octet-stream'});
var url = URL.createObjectURL(url);
window.open(url);
}
If you replace window.open with location.href = you will get the Failed to load resource: Frame load interrupted and be unable to save the file that is not the case for all mimetype, mimetypes that Safari can display can be opened this way
A little side note here is that window.open only works on trusted events meaning:
- It will only be able to open the url when user interacts with the website like a
onclick event (more about isTrusted event here - almost pointless becuse browser support)
I have also found out that the trusted event persist for 1000 ms, so you could do:
window.onclick = function(){
setTimeout(function(){
var blob = new Blob(["Hi"], {type: 'application/octet-stream'});
var url = URL.createObjectURL(url);
window.open(url);
}, 950); // Any longer then 1sec will make the window.open blocked again
}
So the conclusion here about safari is
- download attribute in safari is not supported
- It will try other means to save the blob by opening a new url
- If the mimetype can be rendered by safari it will be able to display it in a new tab
- If the mimetype is application/octet-stream:
4.1 Create a base64 link with FileReader api
4.2 try to open a new tab using window.open + base64 url
4.3 if it was more then 1 sec before the user interaction happened it will use the current page instead
but that is likely going to fail because (see first example using location.href) Failed to load resource: Frame load interrupted This may still work if the mimetype is not application/octet-stream and the saveAs was not called synchronous
- Safari don't have anything like
msSaveAs()
- safest way to force the file to be saved is to have a
data:attachment/file" + base64 ready and open that link using window.open() when the user interacts with the website (or at least to it under 1 second)
- when saving it as a attachment filename will be "unknown"
Edit by @eligrey: Please tell Apple how this bug is affecting you in https://bugs.webkit.org/show_bug.cgi?id=102914 if you want this fixed.
Edit by @jimmywarting
The safari bug #102914 has been marked as fixed now
In the meantime, if you want to support Safari 7, you'll probably want to use Downloadify (uses Flash, not HTML5).
Issues we have had with Safari
This has been solved with Blob.js using BlobBuilder as fallback and then base64 data uri if that are not supported either
Has been covered by both FileSaver.js and blob.js
Blob.js overrule createObjectUrl with it's own base64 url constructor only if it's a "fake blob" (i.e not a File or Blob representation) it will use
window.URL, fallback towindow.webkitURLor use it's own base64 function to create those "fake blobs" data-uriplain/textor a common image likeimage/png.application/octet-stream(wish is commonly used to force saving files from the server)If it's then it read the blob as base64 using FileReader to open a
data:attachment/file" + base64url in order to save it.attachment/filetype directly and open it, then you will get errors like this:Failed to load resource: Frame load interruptedit has to be base64 for some reason...This can easily be reproduced by doing:
If you replace
window.openwithlocation.href =you will get theFailed to load resource: Frame load interruptedand be unable to save the file that is not the case for all mimetype, mimetypes that Safari can display can be opened this wayA little side note here is that window.open only works on trusted events meaning:
onclickevent (more about isTrusted event here - almost pointless becuse browser support)I have also found out that the trusted event persist for 1000 ms, so you could do:
So the conclusion here about safari is
4.1 Create a base64 link with FileReader api
4.2 try to open a new tab using window.open + base64 url
4.3 if it was more then 1 sec before the user interaction happened it will use the current page instead
but that is likely going to fail because (see first example using location.href)
Failed to load resource: Frame load interruptedThis may still work if the mimetype is notapplication/octet-streamand the saveAs was not called synchronousmsSaveAs()data:attachment/file" + base64ready and open that link using window.open() when the user interacts with the website (or at least to it under 1 second)