Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Problem saving in Safari #242

Closed
jimmywarting opened this issue Jun 21, 2016 · 11 comments
Closed

Problem saving in Safari #242

jimmywarting opened this issue Jun 21, 2016 · 11 comments

Comments

@jimmywarting
Copy link
Collaborator

Moving this away from #12 @prafulc

I am using this package to save an excel file. It is working well with mozilla and chrome but it is not downloading file in safari. Here is my code:

saveAs(new Blob([s2ab(response)],{type:"application/octet-stream"}), fileName)

I'm call this async with meteor.call

@jimmywarting
Copy link
Collaborator Author

jimmywarting commented Jun 21, 2016

Didn't want to bother everyone else with useless notification as it's more specific to you. It also didn't bring any useful information how to solve #12

If you are calling the saveAs method after 1 sec after a user interaction, then you will have problem saving the blob.

Could you maybe try something simpler like this?

window.onclick = function(){
    var blob = new Blob(["Save on user interaction"], {type:"application/octet-stream"})
    saveAs(blob, "filename.txt")
}

@prafulc
Copy link

prafulc commented Jun 21, 2016

@jimmywarting Do you want to say that if saveAs() is getting called after 1sec its not going to work? But in my case its not possible to call it just after click event. It is going to take response from server.

@jimmywarting
Copy link
Collaborator Author

jimmywarting commented Jun 21, 2016

An alternative method would be to get the response from the server, wait until it has finish and then provide them with a save button.

FileSaver is useful for client side generated data. Since your file comes from the server it probably would be best if you could send content-disposition header from the server directly. A server is the only solution where you will be able to specify a filename in Safari. ATM

@jimmywarting
Copy link
Collaborator Author

jimmywarting commented Jun 21, 2016

The behavior of the 1 sec rule is that it's not possible to open up a new window with window.open unless it's made from a user interaction.

We try window.open first of all, but if the window didn't load then we replace the curent window with the response.

But this only applies to safari since it dosen't have support for download attribute

@prafulc
Copy link

prafulc commented Jun 21, 2016

In my case it is not possible to get the data first and then call saveAs(). Does it work if I get data synchronously and then call saveAs(). In both cases data will need some time to get collected. Here is my code of asynchronous function:

Meteor.call( 'exportData',ws ,ref, ( error, response ) => {
    if ( error ) {
        // Bert.alert( error.reason, 'warning' );
    } else {
        if ( response ) {
            function s2ab(s) {
                var buf = new ArrayBuffer(s.length);
                var view = new Uint8Array(buf);
                for (var i=0; i!=s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;
                return buf;
            }
            // the saveAs call downloads a file on the local machine
            saveAs(new Blob([s2ab(response)],{type:"application/octet-stream"}), fileName)
        }
    }
});

It is downloading undefined files all the time

@prafulc
Copy link

prafulc commented Jun 21, 2016

@jimmywarting I have just checked renaming the file and it works perfectly. I just need to change the name of that file. Any suggestions?

@jimmywarting
Copy link
Collaborator Author

Sorry, there is no way we can rename the file. It always downloads as Unknown for me.
What it essentially comes down to is that safari tries to open

data:attachment/file;[base64 response of s2ab(response)]

That is the only way we can trigger safari to download the file but with the cost of not being able specify a filename.

A other decent alternative is just to show the response in a new tab and let the user just hit cmd+s to save the file. But it only works best if it's just plain text where the user knows that it can be saved as .html .js or .txt or whatever. Then they can specify the filename by them self.

If you insist on having a filename, then there is only three things left to do...

  1. Using flash based Downloadify which i hate...
  2. Use a server to force the download to happen while specifying a filename like I talked about
  3. Wait until safari either support download attribute or service worker.

@RaviTejaKaruturi
Copy link

RaviTejaKaruturi commented Mar 29, 2017

Hi @jimmywarting ,

In one of the comments, you said

Since your file comes from the server it probably would be best if you could send content-disposition header from the server directly. A server is the only solution where you will be able to specify a filename in Safari.

One of the article am looking into does the same (sets content-disposition header). But, still this does not work in Safari. Can you please take a look at the article and conform?

@jimmywarting
Copy link
Collaborator Author

Hi @RaviTejaKaruturi

After you have added the content-disposition header how do you download the file afterwards?
Do you download the file with ajax first? If so, that won't work... You need to navigate to that page/file for it to work

@RaviTejaKaruturi
Copy link

Currently, I send a ajax call and server returns the file with content-disposition header. Can you please explain

You need to navigate to that page/file for it to work

@jimmywarting
Copy link
Collaborator Author

jimmywarting commented Mar 29, 2017

Instead of doing ajax you should just navigate to the url

window.location.href = url

If you are doing something other then a GET request then you need to use a (hidden) form element that is appended to body and make a submit

The drawback with using the server method is that you can not control all the request headers

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants