简体   繁体   English

如何下载我从 HTTP 响应(axios PUT 请求)收到的 .zip 文件

[英]How to download .zip file that i recieve from a HTTP response (axios PUT request)

So the API's response contains data property which should contain the.zip file that i need.因此 API 的响应包含data属性,该属性应包含我需要的 .zip 文件。 Its written in a format i do not understand.它以我不理解的格式编写。

The format:格式: 在此处输入图像描述

I tried using .blob() as referenced in similar questions here on Stackoverflow, but it doesn't seem to work.我尝试使用.blob()作为 Stackoverflow 上类似问题中引用的内容,但它似乎不起作用。

The ideal solution is this: when client presses the button, he should be prompted to download said.zip file (the one from the HTTP response) locally.理想的解决方案是这样的:当客户端按下按钮时,应该提示他在本地下载 said.zip 文件(来自 HTTP 响应的那个)。 I'm using axios and the request type is PUT .我正在使用 axios 并且请求类型是PUT

My code example so far:到目前为止我的代码示例:

  const exportCards = () => {
    axios
      .put(url, {
        ids: ids,
      })
      .then((res) => {
        return res.data.blob();
      })
      .then((blob) => {
        var file = window.URL.createObjectURL(blob);
        window.location.assign(file);
      })
      .catch((e) => console.log(e));
  };

a tag has download attribute, in .then you can try something like that a标签有download属性,在.then你可以尝试类似的东西

const url = new Blob([response.data],{type:'application/zip'});
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', 'file.zip'); //set download attribute to link
document.body.appendChild(link);
link.click(); // this will download file.zip

I would suggest fetch over axios in concern of zip file because sometimes the response in axios request is not accurate and you might fall into currupted zip file while downloading, the best might be using a package called file-saver and fetch. I would suggest fetch over axios in concern of zip file because sometimes the response in axios request is not accurate and you might fall into currupted zip file while downloading, the best might be using a package called file-saver and fetch. I am posting this answer to help the developers to grab the concept only, the code is tested in React.我发布这个答案是为了帮助开发人员抓住这个概念,代码是在 React 中测试的。

package file-saver : https://www.npmjs.com/package/file-saver package文件保护程序https://www.npmjs.com/package/file-saver

Now make any function according to your choice in react, I am assuming functional component so will write method according to functional component syntax.现在根据您在反应中的选择制作任何 function,我假设功能组件,因此将根据功能组件语法编写方法。 note before using saveAs function you need to import from the installed package file-saver.请注意,在使用 saveAs function 之前,您需要从已安装的 package 文件保护程序中导入。

import { saveAs } from 'file-saver';

const downloadZipFileFromLaravel=()=>{
 fetch(`your url`)
           
                    .then(res => res.blob())
                    .then(blob => saveAs(blob, 'Auto Photos.zip')) // saveAs is a function from the file-saver package. 
              .catch((err) => {
                console.log(err.message);
              });
}

at the end you need to connect the function with a button with onClick.最后,您需要将 function 与 onClick 的按钮连接起来。 example例子

<button onClick={()=>downloadZipFileFromLaravel()}> </button>

Note: usage of file saver in pure javascript, you can check this: How to use filesaver.js注意:在纯 javascript 中使用文件保护程序,您可以查看: 如何使用 filesaver.js

For more information you can see the below discussion: Reference: https://github.com/eligrey/FileSaver.js/issues/156有关更多信息,您可以查看以下讨论:参考: https://github.com/eligrey/FileSaver.js/issues/156

What I wanted:我想要什么:

  • send files of any formats from the back-end to the front-end将任何格式的文件从后端发送到前端

My tools:我的工具:

  • axios, express, saveAs axios,快递,另存为

The problem I faced with:我面临的问题:

Nothing helped me, probably because I did something wrong.没有什么能帮到我,可能是因为我做错了什么。 But here is a simple and quick solution that I came up with:但这是我想出的一个简单快捷的解决方案:

//BE
const filename = "my-file-name.json";

const zip = new AdmZip();
zip.addFile(filename, body);
const content = zip.toBuffer();

res.set({
            "Content-Length": Buffer.byteLength(content), //I'm not sure if this is necessary, but it's better to let it be :-)
            "Content-Type": "text/plain",
            "Content-Disposition": `attachment; filename=${filename}.${format}`,
          });
res.status(200).send(content.toString("hex")); //my solution to the problem

//FE
const { headers, data } = await axios.post(myEndpoint);
const headerLine = headers["content-disposition"];
const filename = headerLine.replace(/[\w; ]+filename=/g, "");

const content = Buffer.from(data, "hex");
const blob = new Blob([content], { type: "application/zip" });
saveAs(blob, filename); //file-saver npm package

Your problem is that you didn't explicitly specify the response type in your PUT request.您的问题是您没有在PUT请求中明确指定响应类型。 This should work:这应该工作:

const exportCards = () => {
  axios
    .put(url, {
      ids: ids,
    }, {
      responseType: 'blob'
    })
    .then((res) => { // Now 'res.data' is Blob, not a string
      var file = window.URL.createObjectURL(res.data);
      window.location.assign(file);
    })
    .catch((e) => console.log(e));
};

在此处输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM