我使用axios的基本http请求,如GET和POST,它工作得很好。现在我需要能够下载Excel文件。这在axios中可行吗?如果是,谁有一些示例代码?如果不是,我还可以在React应用程序中使用什么来做同样的事情?


当前回答

对于axios POST请求,请求应该是这样的: 这里的关键是responseType和header字段必须在Post的第3个参数中。第二个参数是应用程序参数。

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;
}

其他回答

我有一个问题,我从axios const axiosResponse = await axios.get(pdf.url)传输到谷歌驱动器googleDrive.files。create({media: {body: axiosResponse.)data, mimeType}, requestBody: {name: fileName, parents: [parentFolder], mimeType}, auth: jwtClient})上传一个损坏的文件。

文件损坏的原因是axios转换了axiosResponse。数据转换为字符串。为了解决这个问题,我必须要求axios返回一个axios.get流。url, {responseType: 'stream'})。

诀窍是在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/。

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

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模块。链接到Github回购

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

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

对于axios POST请求,请求应该是这样的: 这里的关键是responseType和header字段必须在Post的第3个参数中。第二个参数是应用程序参数。

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;
}

文件下载自定义头请求。在这个例子中,它展示了如何用承载令牌发送文件下载请求。适合授权下载内容。

下载(urlHere) { axios。get (urlHere, { 标题:{ “Access-Control-Allow-Origin”:“*”, 授权:'持有人${sessionStorage.getItem("auth-token")} ', } }).then((response) => { const temp = window.URL。createObjectURL(新团([response.data])); const link = document.createElement('a'); 链接。Href = temp; 链接。setAttribute(“下载”,“file.csv”);//或任何其他扩展 document.body.appendChild(链接); link.click (); }); }