大多数答案都缺少几个关键点。
我将尝试在这里进行深入解释。
太长了;
如果你正在创建 a
标签链接并通过浏览器请求启动下载,那么
-
p4
-
p5
有关组件代码和更深入的分析,请进一步阅读
首先要弄清楚您尝试下载数据的 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>;
}
很高兴知道:
-
p18
-
第19页
-
p20
-
p21
-
第22页
-
p23
参考: AJAX 请求和常规浏览器请求之间的区别