2

In react, I am testing my file download based on John Culviner's solution mentioned in this post

axios.post('api/downloadMyFile', 
            data
           ).then((response) => {
            
             const url = window.URL.createObjectURL(new Blob([response.data])) 

             const a = document.createElement('a');

             a.href = url;
             a.download = "test.zip"  
             document.body.appendChild(a);
             a.click();
             window.URL.revokeObjectURL(url);


           
        }).catch((err) => {
            
        } 

So file test.zip is getting downloaded. but when I tried to open it after saving it I am getting Compressed Zip folder error in windows.

Also, I noticed that I don't need to specify the name of the file in the line a.download = "test.zip" because the webservice is getting the file from shared storage and it already has a name. So in this case, do I need to have the filename also in the response object? something like response.filename so that I could use it in the following line instead of naming it manually:

a.download = response.filename

4
  • You're making us assume the file retrieved via axios is a valid zip file. It does seem that it is. Commented Nov 18, 2020 at 16:49
  • Yeah, I am not sure why it is complaining then. Commented Nov 18, 2020 at 17:10
  • Whoops - I meant it does not seem the zip file retrieved via axios is valid. Commented Nov 18, 2020 at 17:11
  • Hmm. Anything wrong with my approach? Commented Nov 18, 2020 at 17:11

2 Answers 2

2

The response.data returned from Axios is a JSON string. So creating a Blob from that JSON doesn't produce the correct object. From the Axios docs:

// responseType indicates the type of data that the server will respond with
// options are: 'arraybuffer', 'document', 'json', 'text', 'stream'
// browser only: 'blob'
responseType: 'json', // default

The simple fix is to tell Axios to provide the response in the form of a Blob. Then the URL.createObjectURL() will produce a URL to a file that is in the correct format.

axios.post('api/downloadMyFile', data, { responseType: 'blob' })
.then(blob=>{
  const url = window.URL.createObjectURL(blob.data); 
  const a = document.createElement('a');
  a.href = url;
  a.download = "download.zip"  
  document.body.appendChild(a);
  a.click();
  window.URL.revokeObjectURL(url);
})
Sign up to request clarification or add additional context in comments.

7 Comments

Thanks Randy. Doing this worked but my response object is no longer showing in console log and doing this console.log(blob); showed me this. i.sstatic.net/uqABh.png . So I am unable to use the information that was getting returned with the response object.
You can use the URL you created. For example if it is an image like in your comment, the the img.src equal to the URL. The image will appear.
Sorry, I didn't get it. Initially, response.data was showing an info like NOT AUTHORIZED if someone is not authorized to download the file. But since we have told the axios to provide info in the form of a blob, it's showing as shown in the image above.
I mean it was showing like this before blob conversion Object { data: "NOT_AUTHORIZED: you are not allowed to download this file", status: 200, statusText: "", headers: {…}, config: {…}, request: XMLHttpRequest }. After blob conversion, it only shows like shown in above image
That's a different question, I have answered your original question. You should post that as a new question. Otherwise, what happens is these questions/answers continue to get extended forever. In your new question, you should be prepared to be told that your server should NOT return an HTTP status code of 200 when it should be 401 or 403. Good luck.
|
0

try this two lines to get the file name from the response object

var filename = response.headers.get("content-disposition");
filename = filename.match(/(?<=")(?:\\.|[^"\\])*(?=")/)[0];

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.