我正在使用axios来获取基本的http请求,比如get和post,它运行良好.现在我需要能够下载excel文件.这可能与axios一起使用.如果是这样,有人有一些示例代码吗?如果不是我还能在反应应用程序中使用什么来做同样的事情?
Har*_*dha 54
当响应带有可下载文件时,响应头将是类似的
Content-Disposition: "attachment;filename=report.xls"
Content-Type: "application/octet-stream" // or Content-type: "application/vnd.ms-excel"
Run Code Online (Sandbox Code Playgroud)
你可以做的是创建一个单独的组件,它将包含一个隐藏的iframe.
import * as React from 'react';
var MyIframe = React.createClass({
render: function() {
return (
<div style={{display: 'none'}}>
<iframe src={this.props.iframeSrc} />
</div>
);
}
});
Run Code Online (Sandbox Code Playgroud)
现在,您可以将可下载文件的url作为prop传递给此组件,因此当此组件将接收prop时,它将重新呈现并将下载文件.
编辑:您也可以使用js-file-download模块.链接到Github回购
const FileDownload = require('js-file-download');
Axios.get(`http://localhost/downloadFile`)
.then((response) => {
FileDownload(response.data, 'report.csv');
});
Run Code Online (Sandbox Code Playgroud)
希望这可以帮助 :)
Len*_*lid 36
当您想要使用Axios和某些安全手段下载文件时,这实际上更加复杂.为了防止其他人花费太多时间来搞清楚这一点,让我带你走过这个.
你需要做3件事:
1. Configure your server to permit the browser to see required HTTP headers
2. Implement the server-side service, and making it advertise the correct file type for the downloaded file.
3. Implementing an Axios handler to trigger a FileDownload dialog within the browser
Run Code Online (Sandbox Code Playgroud)
这些步骤大多是可行的 - 但是浏览器与CORS的关系很复杂.一步一步来:
在使用传输安全性时,在浏览器中执行的JavaScript可以[通过设计]仅访问HTTP服务器实际发送的6个HTTP头.如果我们想在服务器建议为下载的文件名,我们必须告知这是"OK"的JavaScript来被授予访问到文件名建议将运送其他头的浏览器.
让我们假设 - 为了讨论 - 我们希望服务器在名为X-Suggested-Filename的HTTP头中传输建议的文件名.HTTP服务器告诉它是浏览器OK揭露这个接收到的自定义标题的JavaScript /爱可信与下面的头:
Access-Control-Expose-Headers: X-Suggested-Filename
Run Code Online (Sandbox Code Playgroud)
配置HTTP服务器以设置此标头的确切方法因产品而异.
有关这些标准标题的完整说明和详细说明,请参阅https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Expose-Headers.
您的服务器端服务实现现在必须执行以下两项操作:
1. Create the (binary) document and assign correct ContentType to the response
2. Assign the custom header (X-Suggested-Filename) containing the suggested file name for the client
Run Code Online (Sandbox Code Playgroud)
这取决于您选择的技术堆栈,以不同的方式完成.我将使用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();
}
Run Code Online (Sandbox Code Playgroud)
该服务现在发出二进制文档(在本例中为Excel报告),设置正确的内容类型 - 并且还发送包含保存文档时使用的建议文件名的自定义HTTP标头.
这里有一些陷阱,所以让我们确保正确配置所有细节:
骨架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);
});
Run Code Online (Sandbox Code Playgroud)
Vin*_*ney 35
更通用的解决方案
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();
});
Run Code Online (Sandbox Code Playgroud)
通过https://gist.github.com/javilobo8/097c30a233786be52070986d8cdb1743查看怪癖
完整学分:https://gist.github.com/javilobo8
Ale*_*lex 24
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();
}
}
);
Run Code Online (Sandbox Code Playgroud)
上面的示例适用于 excel 文件,但只需稍加改动即可应用于任何格式。
在服务器上,我这样做是为了发送一个 excel 文件。
response.contentType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
response.addHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=exceptions.xlsx")
Run Code Online (Sandbox Code Playgroud)
rol*_*oli 13
使用 axios 进行 API 调用的函数:
function getFileToDownload (apiUrl) {
return axios.get(apiUrl, {
responseType: 'arraybuffer',
headers: {
'Content-Type': 'application/json'
}
})
}
Run Code Online (Sandbox Code Playgroud)
调用该函数,然后下载得到的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()
})
Run Code Online (Sandbox Code Playgroud)
KJ *_*han 12
大多数答案都缺少几个关键点。
我将尝试在这里进行更深入的解释。
太长了;
如果您正在创建a标签链接并通过浏览器请求启动下载,那么
总是打电话window.URL.revokeObjectURL(url);。否则可能会出现不必要的内存峰值。
无需使用 将创建的链接附加到文档正文document.body.appendChild(link);,从而防止以后不必要地删除子项。
有关组件代码和更深入的分析,请进一步阅读
首先是确定您尝试下载数据的 API 端点是公共的还是私有的。您是否可以控制服务器?
如果服务器响应
Content-Disposition: attachment; filename=dummy.pdf
Content-Type: application/pdf
Run Code Online (Sandbox Code Playgroud)
浏览器将始终尝试下载名为“dummy.pdf”的文件
如果服务器响应
Content-Disposition: inline; filename=dummy.pdf
Content-Type: application/pdf
Run Code Online (Sandbox Code Playgroud)
浏览器将首先尝试打开本地文件阅读器(如果名称为“dummy.pdf”),否则它将开始文件下载。
如果服务器没有响应上述 2 个标头
如果未设置下载属性,浏览器(至少是 Chrome)将尝试打开该文件。如果设置,它将下载该文件。如果 url 不是 blob,则文件名将是最后一个路径参数的值。
除此之外,请记住使用Transfer-Encoding: chunkedfrom server 从服务器传输大量数据。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>;
}
Run Code Online (Sandbox Code Playgroud)
对于公共文件
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>;
}
Run Code Online (Sandbox Code Playgroud)
很高兴知道:
始终控制从服务器下载文件。
浏览器中的 Axios 在底层使用 XHR,其中不支持响应流。
使用onDownloadProgressaxios中的方法来实现进度条。
来自服务器的分块响应不(不能)指示内容长度。因此,如果您在构建进度条时使用它们,您需要某种方法来了解响应大小。
<a>标签链接只能发出 GET HTTP 请求,无法向服务器发送标头或 cookie(非常适合从公共端点下载)
浏览器请求与代码中发出的 XHR 请求略有不同。
Nit*_*agi 11
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.
})
Run Code Online (Sandbox Code Playgroud)
Mul*_*ter 10
触发用户下载的 javascript 代码非常简单:
window.open("<insert URL here>")
Run Code Online (Sandbox Code Playgroud)
您不需要/不需要 axios 来执行此操作;让浏览器做它的事情应该是标准的。
注意:如果您需要下载授权,那么这可能不起作用。我很确定您可以使用 cookie 来授权这样的请求,前提是它在同一个域内,但无论如何,在这种情况下这可能不会立即起作用。
至于是否有可能......不是内置的文件下载机制,没有。
诀窍是在 中创建一个不可见的锚标记,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>
)
}
}
Run Code Online (Sandbox Code Playgroud)
这是文档: https: //reactjs.org/docs/refs-and-the-dom.html。您可以在这里找到类似的想法: https: //thewebtier.com/snippets/download-files-with-axios/。
| 归档时间: |
|
| 查看次数: |
104926 次 |
| 最近记录: |