【问题标题】:How to download files using axios如何使用 axios 下载文件
【发布时间】:2017-06-15 18:37:50
【问题描述】:

我将 axios 用于基本的 http 请求,如 GET 和 POST,它运行良好。现在我也需要能够下载 Excel 文件。 axios可以做到这一点吗?如果是这样,有人有一些示例代码吗?如果没有,我还能在 React 应用程序中使用什么来做同样的事情?

【问题讨论】:

标签: axios


【解决方案1】:

更通用的解决方案

axios({
    url: 'http://api.dev/file-download', //your url
    method: 'GET',
    responseType: 'blob', // important
}).then((response) => {
    const url = window.URL.createObjectURL(new Blob([response.data]));
    const link = document.createElement('a');
    link.href = url;
    link.setAttribute('download', 'file.pdf'); //or any other extension
    document.body.appendChild(link);
    link.click();
});

https://gist.github.com/javilobo8/097c30a233786be52070986d8cdb1743查看怪癖

完整致谢:https://gist.github.com/javilobo8

【讨论】:

  • 感谢您的解决方案。对其他人的几点说明:虽然这可能适用于很多用例,但对于大文件大小,您将无法看到下载进度。它会在浏览器中占用额外的内存。正如在其他解决方案中提到但未详细说明的那样,一般方法是使用标题“Content-Disposition:附件;”所以浏览器会将其视为原生下载(上述下载进度+直接下载到磁盘)。
  • 在服务器端,即使我设置了 Content-Desposition 标头,它似乎也不允许下载进度。
  • 谢谢。想知道为什么文件内容没有正确显示。原来我错过了responseType: 'blob'
  • @Ricky-U 是的,您是对的,xhr 请求将被发送,当响应到达时,它将被缓冲在内存中,稍后,完成后存储在变量 response 中。然后createObjectURL 为该数据创建一个本地 URL, 可以导航到该 URL。
  • 我们需要document.body.appendChild(link);这一行吗?没有那个解决方案对我有用(Chrome)
【解决方案2】:

当响应带有可下载文件时,响应标头将类似于

Content-Disposition: "attachment;filename=report.xls"
Content-Type: "application/octet-stream" // or Content-type: "application/vnd.ms-excel"

您可以做的是创建一个单独的组件,其中将包含一个隐藏的 iframe。

  import * as React from 'react';

  var MyIframe = React.createClass({

     render: function() {
         return (
           <div style={{display: 'none'}}>
               <iframe src={this.props.iframeSrc} />
           </div>
         );
     }
  });

现在,您可以将可下载文件的 url 作为 prop 传递给该组件,因此当该组件收到 prop 时,它将重新渲染并下载文件。

编辑:您也可以使用js-file-download 模块。 Link to Github repo

const FileDownload = require('js-file-download');

Axios({
  url: 'http://localhost/downloadFile',
  method: 'GET',
  responseType: 'blob', // Important
}).then((response) => {
    FileDownload(response.data, 'report.csv');
});

希望这会有所帮助:)

【讨论】:

  • 谢谢。你能告诉我这是否是ajax风格。最好不要屏蔽该页面。
  • 是的,页面不会被阻止。当您将 url 作为 prop 传递给该组件时,文件将自动下载。你不需要做任何事情。
  • 还有一个问题。在我的情况下,正在下载的文件是动态创建的,并传递了一些参数。所以它实际上并没有一个一致的位置。我为这种情况发送的 url 是什么?例如,如果我调用 axios.post('api/getmyexcelfile', params);
  • this 回答中所述。在axios响应对象中,request里面有个字段叫AsresponseURL,也许这就是你想要的URL。
  • 我遵循了这个并且能够下载该文件。但是文件已损坏(不起作用)。但是,如果我使用重定向( window.location.href ),文件会下载并完美运行。有人可以帮我解决这个问题吗? (stackoverflow.com/questions/56306008/…)
【解决方案3】:

下载文件(使用 Axios 和安全)

当您想使用 Axios 和某些安全手段下载文件时,这实际上更加复杂。为了防止其他人花费太多时间来解决这个问题,让我带您了解一下。

你需要做三件事:

  1. 配置您的服务器以允许浏览器查看所需的 HTTP 标头
  2. 实现服务器端服务,并使其为下载的文件通告正确的文件类型。
  3. 实现 Axios 处理程序以在浏览器中触发 FileDownload 对话框

这些步骤大多是可行的 - 但由于浏览器与 CORS 的关系而变得相当复杂。一步一个脚印:

1。配置您的 (HTTP) 服务器

在采用传输安全性时,在浏览器中执行的 JavaScript [按设计] 只能访问 HTTP 服务器实际发送的 6 个 HTTP 标头。如果我们希望服务器为下载建议一个文件名,我们必须通知浏览器,允许 JavaScript 访问将传输建议文件名的其他标头是“OK”的。

让我们假设 - 为了讨论起见 - 我们希望服务器在名为 X-Suggested-Filename 的 HTTP 标头中传输建议的文件名。 HTTP 服务器告诉浏览器 OK 可以使用以下标头将收到的自定义标头公开给 JavaScript/Axios:

Access-Control-Expose-Headers: X-Suggested-Filename

配置 HTTP 服务器以设置此标头的确切方法因产品而异。

请参阅https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Expose-Headers,了解这些标准标头的完整说明和详细说明。

2。实现服务端服务

您的服务器端服务实现现在必须执行 2 件事:

  1. 创建(二进制)文档并将正确的 ContentType 分配给响应
  2. 为客户端分配包含建议文件名的自定义标头 (X-Suggested-Filename)

这取决于您选择的技术堆栈以不同的方式完成。我将使用 JavaEE 7 标准绘制一个示例,该示例应该会发出 Excel 报告:

    @GET
    @Path("/report/excel")
    @Produces("application/vnd.ms-excel")
    public Response getAllergyAndPreferencesReport() {

        // Create the document which should be downloaded
        final byte[] theDocumentData = .... 

        // Define a suggested filename
        final String filename = ... 
     
        // Create the JAXRS response
        // Don't forget to include the filename in 2 HTTP headers: 
        //
        // a) The standard 'Content-Disposition' one, and
        // b) The custom 'X-Suggested-Filename'  
        //
        final Response.ResponseBuilder builder = Response.ok(
                theDocumentData, "application/vnd.ms-excel")
                .header("X-Suggested-Filename", fileName);
        builder.header("Content-Disposition", "attachment; filename=" + fileName);

        // All Done.
        return builder.build();
    }

该服务现在发出二进制文档(在本例中为 Excel 报告),设置正确的内容类型 - 并发送包含建议文件名的自定义 HTTP 标头,以在保存文档时使用。

3。为收到的文档实现一个 Axios 处理程序

这里有一些陷阱,所以让我们确保所有细节都正确配置:

  1. 服务响应@GET(即HTTP GET),所以Axios调用必须是'axios.get(...)'。
  2. 文档以字节流的形式传输,因此您必须告诉 Axios 将响应视为 HTML5 Blob。 (即 responseType: 'blob')。
  3. 在这种情况下,文件保护 JavaScript 库用于弹出打开的浏览器对话框。不过,您可以选择其他。

Axios 的框架实现将类似于以下内容:

     // Fetch the dynamically generated excel document from the server.
     axios.get(resource, {responseType: 'blob'}).then((response) => {

        // Log somewhat to show that the browser actually exposes the custom HTTP header
        const fileNameHeader = "x-suggested-filename";
        const suggestedFileName = response.headers[fileNameHeader];
        const effectiveFileName = (suggestedFileName === undefined
                    ? "allergierOchPreferenser.xls"
                    : suggestedFileName);
        console.log(`Received header [${fileNameHeader}]: ${suggestedFileName}, effective fileName: ${effectiveFileName}`);

        // Let the user save the file.
        FileSaver.saveAs(response.data, effectiveFileName);

        }).catch((response) => {
            console.error("Could not Download the Excel report from the backend.", response);
        });

【讨论】:

  • 什么是“FileSaver”?
  • 这是一个处理下载文件的库,github.com/eligrey/FileSaver.js/#filesaverjs
  • 这可行,但建议使用content-disposition 标头而不是x-suggested-filename
  • 这很好,但它错过了一个核心点,即在使用 blob 作为 responseType 执行 axios.get(resource, {responseType: 'blob'}).then((response) =&gt; () =&gt; {}) 时,整个文件被加载到内存并然后处理,即使服务器正在以块的形式传输数据。这很关键,因为您最终必须实现自己的进度条,因为您无法使用浏览器提供的原生进度条。这是 xhr 本身的一个缺点。
【解决方案4】:

使用 IE 和其他浏览器的 Axios.post 解决方案

我在这里找到了一些令人难以置信的解决方案。但他们经常不考虑 IE 浏览器的问题。也许它会为其他人节省一些时间。

axios.post("/yourUrl",
    data,
    { responseType: 'blob' }
).then(function (response) {
    let fileName = response.headers["content-disposition"].split("filename=")[1];
    if (window.navigator && window.navigator.msSaveOrOpenBlob) { // IE variant
        window.navigator.msSaveOrOpenBlob(new Blob([response.data],
                { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' }
            ),
            fileName
        );
    } else {
        const url = window.URL.createObjectURL(new Blob([response.data],
            { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' }));
        const link = document.createElement('a');
        link.href = url;
        link.setAttribute('download',
            response.headers["content-disposition"].split("filename=")[1]);
        document.body.appendChild(link);
        link.click();
    }
    }
);

以上示例适用于 excel 文件,但只需稍作改动即可应用于任何格式。

在服务器上,我这样做是为了发送一个 excel 文件。

response.contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"

response.addHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=exceptions.xlsx")

【讨论】:

    【解决方案5】:

    使用 axios 进行 API 调用的函数:

    function getFileToDownload (apiUrl) {
       return axios.get(apiUrl, {
         responseType: 'arraybuffer',
         headers: {
           'Content-Type': 'application/json'
         }
       })
    }
    

    调用函数然后下载你得到的excel文件:

    getFileToDownload('putApiUrlHere')
      .then (response => {
          const type = response.headers['content-type']
          const blob = new Blob([response.data], { type: type, encoding: 'UTF-8' })
          const link = document.createElement('a')
          link.href = window.URL.createObjectURL(blob)
          link.download = 'file.xlsx'
          link.click()
      })
    

    【讨论】:

    • 嘿,我正在这样做,但我的 excel 文件已损坏,知道为什么吗?
    • @habiba 后端的响应文件可能有误
    • 我使用 drf 作为后端,当我使用邮递员保存响应时。它将它保存到一个 excel 文件中,并完美地打开所有数据@roli roli
    • @habiba 它对我来说非常有效。也许您必须将编码更改为文件的编码。
    • "对象字面量可能只指定已知属性,但类型'BlobPropertyBag'中不存在'encoding'。你的意思是写'endings'吗?"
    【解决方案6】:
            axios.get(
                '/app/export'
            ).then(response => {    
                const url = window.URL.createObjectURL(new Blob([response]));
                const link = document.createElement('a');
                link.href = url;
                const fileName = `${+ new Date()}.csv`// whatever your file name .
                link.setAttribute('download', fileName);
                document.body.appendChild(link);
                link.click();
                link.remove();// you need to remove that elelment which is created before.
    })
    

    【讨论】:

      【解决方案7】:

      这是触发用户下载的非常简单的 javascript 代码:

      window.open("<insert URL here>")
      

      您不需要/不需要 axios 进行此操作;让浏览器做这件事应该是标准的。

      注意:如果您需要授权才能下载,那么这可能不起作用。我很确定您可以使用 cookie 来授权这样的请求,前提是它在同一个域中,但无论如何,在这种情况下这可能不会立即起作用。


      至于是否可能...not with the in-built file downloading mechanism, no.

      【讨论】:

      • 授权标头?
      • 如果需要发送令牌怎么办?
      • 如果您控制服务器,那么您可以简单地将访问令牌存储为 cookie,浏览器会将其添加到对您服务器的任何请求中。 medium.com/@ryanchenkie_40935/…
      • 这为 IMO 提供了最佳的用户体验。在 cookie 中设置授权很麻烦,但值得。客户端你需要axios.defaults.withCredentials = true。服务器端是完成繁重工作的地方。
      【解决方案8】:

      诀窍是在render() 中创建一个不可见的锚标记,并添加一个 React ref 允许在我们获得 axios 响应后触发点击:

      class Example extends Component {
          state = {
              ref: React.createRef()
          }
      
          exportCSV = () => {
              axios.get(
                  '/app/export'
              ).then(response => {
                  let blob = new Blob([response.data], {type: 'application/octet-stream'})
                  let ref = this.state.ref
                  ref.current.href = URL.createObjectURL(blob)
                  ref.current.download = 'data.csv'
                  ref.current.click()
              })
          }
      
          render(){
              return(
                  <div>
                      <a style={{display: 'none'}} href='empty' ref={this.state.ref}>ref</a>
                      <button onClick={this.exportCSV}>Export CSV</button>
                  </div>
              )
          }
      }
      

      这里是文档:https://reactjs.org/docs/refs-and-the-dom.html。你可以在这里找到类似的想法:https://thewebtier.com/snippets/download-files-with-axios/

      【讨论】:

        【解决方案9】:

        这对我有用。我在 reactJS 中实现了这个解决方案

        const requestOptions = {`enter code here`
        method: 'GET',
        headers: { 'Content-Type': 'application/json' }
        };
        
        fetch(`${url}`, requestOptions)
        .then((res) => {
            return res.blob();
        })
        .then((blob) => {
            const href = window.URL.createObjectURL(blob);
            const link = document.createElement('a');
            link.href = href;
            link.setAttribute('download', 'config.json'); //or any other extension
            document.body.appendChild(link);
            link.click();
        })
        .catch((err) => {
            return Promise.reject({ Error: 'Something Went Wrong', err });
        })
        

        【讨论】:

          【解决方案10】:

          您需要将 File({file_to_download}, "application/vnd.ms-excel") 从后端返回到前端,并在您的 js 文件中更新下面编写的代码:

          function exportToExcel() {
                  
                  axios.post({path to call your controller}, null,
                      {
                          headers:
                          {
                              'Content-Disposition': "attachment; filename=XYZ.xlsx",
                              'Content-Type': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
                          },
                          responseType: 'arraybuffer',
                      }
                  ).then((r) => {
                      const path= window.URL.createObjectURL(new Blob([r.data]));
                      const link = document.createElement('a');
                      link.href = path;
                      link.setAttribute('download', 'XYZ.xlsx');
                      document.body.appendChild(link);
                      link.click();
                  }).catch((error) => console.log(error));
              }
          

          【讨论】:

            【解决方案11】:

            大部分答案都遗漏了几个关键点。

            我会在这里尝试更深入的解释。

            TLDR;

            如果您正在创建a 标签链接并通过浏览器请求启动下载,那么

            1. 请始终致电window.URL.revokeObjectURL(url);。否则可以有 不必要的内存峰值。

            2. 无需使用document.body.appendChild(link); 将创建的链接附加到文档正文,防止以后不必要地删除子。


            有关组件代码和更深入的分析,请进一步阅读

            首先要确定您尝试从中下载数据的 API 端点是公共的还是私有的。您是否可以控制服务器?


            如果服务器响应

            Content-Disposition: attachment; filename=dummy.pdf
            Content-Type: application/pdf
            

            浏览器总是会尝试下载名为“dummy.pdf”的文件


            如果服务器响应

            Content-Disposition: inline; filename=dummy.pdf
            Content-Type: application/pdf
            

            浏览器将首先尝试打开名为“dummy.pdf”的本机文件阅读器,否则它将开始文件下载。


            如果服务器以 上述两个标头中的任何一个响应

            如果未设置下载属性,浏览器(至少 chrome)将尝试打开文件。如果设置,它将下载文件。在 url 不是 blob 的情况下,文件的名称将是最后一个路径参数的值。


            除此之外,请记住使用来自服务器的Transfer-Encoding: chunked 从服务器传输大量数据。这将确保客户端知道在没有Content-Length 标头的情况下何时停止读取当前请求

            对于私人文件

            import { useState, useEffect } from "react";
            import axios from "axios";
            
            export default function DownloadPrivateFile(props) {
              const [download, setDownload] = useState(false);
            
              useEffect(() => {
                async function downloadApi() {
                  try {
                    // It doesn't matter whether this api responds with the Content-Disposition header or not
                    const response = await axios.get(
                      "http://localhost:9000/api/v1/service/email/attachment/1mbdoc.docx",
                      {
                        responseType: "blob", // this is important!
                        headers: { Authorization: "sometoken" },
                      }
                    );
                    const url = window.URL.createObjectURL(new Blob([response.data])); // you can mention a type if you wish
                    const link = document.createElement("a");
                    link.href = url;
                    link.setAttribute("download", "dummy.docx"); //this is the name with which the file will be downloaded
                    link.click();
                    // no need to append link as child to body.
                    setTimeout(() => window.URL.revokeObjectURL(url), 0); // this is important too, otherwise we will be unnecessarily spiking memory!
                    setDownload(false);
                  } catch (e) {} //error handling }
                }
            
                if (download) {
                  downloadApi();
                }
              }, [download]);
            
              return <button onClick={() => setDownload(true)}>Download Private</button>;
            }
            
            
            

            对于公共文件

            import { useState, useEffect } from "react";
            export default function DownloadPublicFile(props) {
              const [download, setDownload] = useState(false);
            
              useEffect(() => {
                if (download) {
                  const link = document.createElement("a");
                  link.href =
                    "http://localhost:9000/api/v1/service/email/attachment/dummy.pdf";
                  link.setAttribute("download", "dummy.pdf");
                  link.click();
                  setDownload(false);
                }
              }, [download]);
            
              return <button onClick={() => setDownload(true)}>Download Public</button>;
            }
            
            

            很高兴知道:

            1. 始终控制从服务器下载文件。

            2. 浏览器中的 Axios 在底层使用 XHR,其中流式响应 不支持。

            3. 使用Axios的onDownloadProgress方法实现进度条。

            4. 来自服务器的分块响应不(不能)指示内容长度。因此,如果您在构建进度条时使用它们,则需要某种方式来了解响应大小。

            5. &lt;a&gt; 标签链接只能发出 GET HTTP 请求,而不能发送标头或 cookie 到服务器(非常适合从公共端点下载)

            6. 浏览器请求与代码中的 XHR 请求略有不同。

            参考:Difference between AJAX request and a regular browser request

            【讨论】:

              【解决方案12】:

              带有自定义标头请求的文件下载。在此示例中,它显示了如何使用不记名令牌发送文件下载请求。适用于经过授权的可下载内容。

                  download(urlHere) {
               
                  axios.get(urlHere, {
                    headers: {
                      "Access-Control-Allow-Origin": "*",
                      Authorization: `Bearer ${sessionStorage.getItem("auth-token")}`,
                    }
                  }).then((response) => {
                  const temp = window.URL.createObjectURL(new Blob([response.data]));
                  const link = document.createElement('a');
                  link.href = temp;
                  link.setAttribute('download', 'file.csv'); //or any other extension
                  document.body.appendChild(link);
                  link.click();
              });
                }

              【讨论】:

              • 这对我来说非常有效。在我的网站中添加 a 不会影响性能吗?
              【解决方案13】:

              为 Received 文档实现一个Axios 处理程序,数据格式为octect-stream, data 可能看起来很奇怪 PK something JbxfFGvddvbdfbVVH34365436fdkln 作为它的八位字节流格式,您最终可能会使用此数据创建文件可能已损坏,{responseType: 'blob'} 会将数据转换为可读格式,

              axios.get("URL", {responseType: 'blob'})
                   .then((r) => {
                       let fileName =  r.headers['content-disposition'].split('filename=')[1];
                       let blob = new Blob([r.data]);
                       window.saveAs(blob, fileName);             
                    }).catch(err => {
                      console.log(err);
                    });
              

              您可能已经尝试过像这样失败的解决方案, window.saveAs(blob, 'file.zip') 将尝试将文件另存为 zip 但不会工作,

              const downloadFile = (fileData) => {
                  axios.get(baseUrl+"/file/download/"+fileData.id)
                      .then((response) => {
                          console.log(response.data);
                          const blob = new Blob([response.data], {type: response.headers['content-type'], encoding:'UTF-8'});
                          const link = document.createElement('a');
                          link.href = window.URL.createObjectURL(blob);
                          link.download = 'file.zip';
                          link.click();
                      })
                      .catch((err) => console.log(err))
              }
              const downloadFile = (fileData) => {
              axios.get(baseUrl+"/file/download/"+fileData.id)
                  .then((response) => {
                      console.log(response);
                      //const binaryString = window.atob(response.data)
                      //const bytes = new Uint8Array(response.data)
                      //const arrBuff = bytes.map((byte, i) => response.data.charCodeAt(i));
                      //var base64 = btoa(String.fromCharCode.apply(null, new Uint8Array(response.data)));
                      const blob = new Blob([response.data], {type:"application/octet-stream"});
                      window.saveAs(blob, 'file.zip')
                      // const link = document.createElement('a');
                      // link.href = window.URL.createObjectURL(blob);
                      // link.download = 'file.zip';
                      // link.click();
                  })
                  .catch((err) => console.log(err))
              }
              function base64ToArrayBuffer(base64) {
                  var binaryString = window.atob(base64);
                  var binaryLen = binaryString.length;
                  var bytes = new Uint8Array(binaryLen);
                  for (var i = 0; i < binaryLen; i++) {
                      var ascii = binaryString.charCodeAt(i);
                      bytes[i] = ascii;
                  };
              
                  return bytes;
              }
              

              另一个简短的解决方案是,

              window.open("URL")
              

              将继续不必要地打开新标签页,用户可能必须使用 allow popups 才能使用此代码,如果用户想同时下载多个文件,那么请先使用解决方案,或者如果不尝试其他解决方案,该怎么办

              p>

              【讨论】:

                【解决方案14】:

                此功能将帮助您下载现成的 xlsx、csv 等文件下载。我只是从后端发送一个准备好的 xlsx 静态文件,然后它会做出反应。

                const downloadFabricFormat = async () => {
                    try{
                      await axios({
                        url: '/api/fabric/fabric_excel_format/',
                        method: 'GET',
                        responseType: 'blob',
                      }).then((response) => {
                         const url = window.URL.createObjectURL(new Blob([response.data]));
                         const link = document.createElement('a');
                         link.href = url;
                         link.setAttribute('download', 'Fabric Excel Format.xlsx');
                         document.body.appendChild(link);
                         link.click();
                      });
                    } catch(error){
                      console.log(error)
                    }
                  };
                

                【讨论】:

                  【解决方案15】:

                  适用于希望实现经过身份验证的本机下载的用户。

                  我目前正在使用 Axios 开发 SPA。
                  不幸的是,Axios 在这种情况下不允许 stream 响应类型。 来自文档:

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

                  但我找到了in this topic 提到的解决方法。
                  诀窍是发送包含您的令牌和目标文件的基本表单 POST。

                  “这针对一个新窗口。一旦浏览器读取服务器响应中的附件标头,它将关闭新选项卡并开始下载。”

                  这是一个示例:

                  let form = document.createElement('form');
                  form.method = 'post';
                  form.target = '_blank';
                  
                  form.action = `${API_URL}/${targetedResource}`;
                  form.innerHTML = `'<input type="hidden" name="jwtToken" value="${jwtToken}">'`;
                  
                  document.body.appendChild(form);
                  form.submit();
                  document.body.removeChild(form);
                  

                  “您可能需要将您的处理程序标记为未经身份验证/匿名,以便您可以手动验证 JWT 以确保正确授权。”

                  我的 ASP.NET 实现的结果:

                  [AllowAnonymous]
                  [HttpPost("{targetedResource}")]
                  public async Task<IActionResult> GetFile(string targetedResource, [FromForm] string jwtToken)
                  {
                      var jsonWebTokenHandler = new JsonWebTokenHandler();
                  
                      var validationParameters = new TokenValidationParameters()
                      {
                          // Your token validation parameters here
                      };
                  
                      var tokenValidationResult = jsonWebTokenHandler.ValidateToken(jwtToken, validationParameters);
                  
                      if (!tokenValidationResult.IsValid)
                      {
                          return Unauthorized();
                      }
                  
                      // Your file upload implementation here
                  }
                  

                  【讨论】:

                    【解决方案16】:

                    对于 axios POST 请求,请求应该是这样的: 这里的关键是responseTypeheader字段必须在Post的第三个参数中。第二个参数是应用参数。

                    export const requestDownloadReport = (requestParams) => async dispatch => { 
                      let response = null;
                      try {
                        response = await frontEndApi.post('createPdf', {
                          requestParams: requestParams,
                        },
                        {
                          responseType: 'arraybuffer', // important...because we need to convert it to a blob. If we don't specify this, response.data will be the raw data. It cannot be converted to blob directly.
                          headers: {
                              'Content-Type': 'application/json',
                              'Accept': 'application/pdf'
                          }
                      });          
                      }
                      catch(err) {
                        console.log('[requestDownloadReport][ERROR]', err);
                        return err
                      }
                    
                      return response;
                    }
                    

                    【讨论】:

                      【解决方案17】:

                      我的回答是完全破解- 我刚刚创建了一个看起来像按钮的链接并将 URL 添加到该链接。

                      <a class="el-button"
                        style="color: white; background-color: #58B7FF;"
                        :href="<YOUR URL ENDPOINT HERE>"
                        :download="<FILE NAME NERE>">
                      <i class="fa fa-file-excel-o"></i>&nbsp;Excel
                      </a>
                      

                      我正在使用出色的VueJs,因此注释很奇怪,但是,此解决方案与框架无关。这个想法适用于任何基于 HTML 的设计。

                      【讨论】:

                        猜你喜欢
                        • 2021-09-22
                        • 2022-06-13
                        • 2018-08-08
                        • 2021-11-03
                        • 1970-01-01
                        • 2020-05-25
                        • 1970-01-01
                        • 2020-02-26
                        • 2021-07-07
                        相关资源
                        最近更新 更多