最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - handling file download from api call - Stack Overflow

programmeradmin0浏览0评论

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

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

Share Improve this question asked Nov 18, 2020 at 16:42 TanTan 1,5938 gold badges28 silver badges63 bronze badges 4
  • You're making us assume the file retrieved via axios is a valid zip file. It does seem that it is. – Randy Casburn Commented Nov 18, 2020 at 16:49
  • Yeah, I am not sure why it is plaining then. – Tan Commented Nov 18, 2020 at 17:10
  • Whoops - I meant it does not seem the zip file retrieved via axios is valid. – Randy Casburn Commented Nov 18, 2020 at 17:11
  • Hmm. Anything wrong with my approach? – Tan Commented Nov 18, 2020 at 17:11
Add a ment  | 

2 Answers 2

Reset to default 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);
})

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

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

评论列表(0)

  1. 暂无评论