我收到文件 url 作为来自 api 的响应。当用户单击下载按钮时,应下载文件而无需在新选项卡中打开文件预览。如何在 react js 中实现这一点?
如何在react js中下载文件
这与 React 无关。但是,您可以使用download
锚<a>
元素上的属性来告诉浏览器下载文件。
<a href='/somefile.txt' download>Click to download</a>
并非所有浏览器都支持此功能:https : //developer.mozilla.org/en-US/docs/Web/HTML/Element/a
如果您使用的是 React Router,请使用以下命令:
<Link to="/files/myfile.pdf" target="_blank" download>Download</Link>
哪里/files/myfile.pdf
是你的内部public
文件夹。
从前端触发浏览器下载是不可靠的。
您应该做的是,创建一个端点,当调用该端点时,将提供正确的响应标头,从而触发浏览器下载。
前端代码只能做这么多。例如,“下载”属性可能只是根据浏览器在新选项卡中打开文件。
您需要查看的响应标头可能是Content-Type
和Content-Disposition
。您应该查看此答案以获取更详细的解释。
tldr; 从 url 中获取文件,将其存储为本地 Blob,在 DOM 中注入一个链接元素,然后单击它以下载 Blob
我有一个 PDF 文件,它存储在 Cloudfront URL 后面的 S3 中。我希望用户能够单击按钮并立即启动下载,而无需打开带有 PDF 预览的新选项卡。通常,如果文件托管在与用户当前所在站点具有不同域的 URL 上,则出于用户安全原因,许多浏览器会阻止立即下载。如果您使用此解决方案,除非用户单击按钮有意下载,否则不要启动文件下载。
为了解决这个问题,我需要从 URL 中获取文件,绕过任何 CORS 策略以保存本地 Blob,然后该 Blob 将成为下载文件的源。在下面的代码,请确保您在自己的交换fileURL
,Content-Type
和FileName
。
fetch('https://cors-anywhere.herokuapp.com/' + fileURL, {
method: 'GET',
headers: {
'Content-Type': 'application/pdf',
},
})
.then((response) => response.blob())
.then((blob) => {
// Create blob link to download
const url = window.URL.createObjectURL(
new Blob([blob]),
);
const link = document.createElement('a');
link.href = url;
link.setAttribute(
'download',
`FileName.pdf`,
);
// Append to html link element page
document.body.appendChild(link);
// Start download
link.click();
// Clean up and remove the link
link.parentNode.removeChild(link);
});
此解决方案引用了从 URL 获取 blob并使用 CORS 代理的解决方案。
更新 截至2021 年 1 月 31 日,托管在 Heroku 服务器上的 cors-anywhere 演示将仅允许有限地用于测试目的,不能用于生产应用程序。您必须按照cors-anywhere或cors-server来托管您自己的 cors-anywhere服务器。
浏览器足够聪明,可以在不使用下载属性的情况下单击锚标记时直接检测链接并下载它。
从 api 获取文件链接后,只需通过创建锚标记使用普通 javascript 并在动态单击后立即删除它。
const link = document.createElement('a');
link.href = `your_link.pdf`;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);