reactjs如何下载文件
Posted
技术标签:
【中文标题】reactjs如何下载文件【英文标题】:how to download file in react js 【发布时间】:2018-11-14 15:11:41 【问题描述】:我从 api 收到文件 url 作为响应。当用户单击下载按钮时,应下载文件,而无需在新选项卡中打开文件预览。如何在 React js 中实现这一点?
【问题讨论】:
从前端触发浏览器下载并不是一种可靠的方法。您应该创建在调用时将提供正确响应标头的端点,从而触发浏览器下载。前端代码只能做这么多。例如,“下载”属性可能只是在新选项卡中打开文件,具体取决于浏览器。 根据我的理解,你是说rest api可以通过正确的响应头来实现,对吗? 是的。我不知道如何在评论中附加链接,所以我发布了一个答案。 【参考方案1】:从前端触发浏览器下载不可靠。
你应该做的是,在服务器上创建一个端点,当被调用时,它会以正确的响应头响应,从而触发浏览器下载。
前端代码只能做这么多。例如,“下载”属性可能只是在新选项卡中打开文件,具体取决于浏览器和文件类型。
您需要查看的响应标头是Content-Type
和Content-Disposition
。您应该查看answer 以获取有关这些标题的更详细说明。
【讨论】:
你应该做的是,创建一个端点,当被调用时,它将提供正确的响应头,从而触发浏览器下载......这些头是什么以及具体的头如何触发浏览器下载?谢谢 您好,抱歉回复晚了。有问题的标题是Content-Type
和Content-Disposition
。【参考方案2】:
出色而快速的解决方案:
window.open('https://myapi.com/download/file-name')
【讨论】:
【参考方案3】:fetchFile()
axios(
url: `/someurl/thefiles/$this.props.file.id`,
method: "GET",
headers: headers,
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",
`$this.props.file.name.$this.props.file.mime`
);
document.body.appendChild(link);
link.click();
// Clean up and remove the link
link.parentNode.removeChild(link);
);
render()
return( <button onClick=this.fetchFile> Download file </button>)
【讨论】:
请注意,如果页面未在您的应用中重新加载,则传递给“URL.createObjectURL”的 blob 将保留在内存中,直到您调用 URL.revokeObjectUrl。对于长时间运行的应用,这可能会导致内存浪费和性能问题。【参考方案4】:import resume from '../assets/data/resume.pdf';
<a href=resume download="YourName resume.pdf"> Download CV </a>
【讨论】:
我能够以同样的方式添加一个 epub 文件【参考方案5】:解决我的下载链接问题的包是:
npm install --save react-download-link
像这样使用它:
fileDownload(axiosResponse.data, 'filename.csv');
您可以创建例如在后端有这样的 C# Web API 端点:
[HttpGet("GenerateSitemap")]
public async Task<IActionResult> GenerateSitemap()
var sitemapString = "[place-xml-sitemap-string-here]";
var serializedObj = JsonConvert.SerializeObject(obj);
var bytesObj = Encoding.UTF8.GetBytes(serializedObj);
return File(sitemapString.SerializeToByteArray(), "application/octet-stream");
【讨论】:
【参考方案6】:下载文件
对于下载,您可以使用上面解释的多种方式,此外,我还将针对这种情况提供我的策略。
npm install --save react-download-link
import DownloadLink from "react-download-link";
React 客户端缓存数据的下载链接
<DownloadLink
label="Download"
filename="fileName.txt"
exportFile=() => "Client side cache data here…"
/>
带有 Promises 的客户端缓存数据的下载链接
<DownloadLink
label="Download with Promise"
filename="fileName.txt"
exportFile=() => Promise.resolve("cached data here …")
/>
使用 Promises 函数从 URL 下载数据链接以从 URL 获取数据
getDataFromURL = (url) => new Promise((resolve, reject) =>
setTimeout(() =>
fetch(url)
.then(response => response.text())
.then(data =>
resolve(data)
);
);
, 2000);
DownloadLink 组件调用 Fetch 函数
<DownloadLink
label=”Download”
filename=”filename.txt”
exportFile=() => Promise.resolve(this. getDataFromURL (url))
/>
编码愉快! ;)
【讨论】:
【参考方案7】:tldr; 从 url 获取文件,将其存储为本地 Blob,将链接元素注入 DOM,然后单击以下载 Blob
我有一个 PDF 文件存储在 Cloudfront URL 后面的 S3 中。我希望用户能够单击按钮并立即启动下载,而无需打开带有 PDF 预览的新标签。通常,如果文件托管在与用户当前所在站点具有不同域的 URL 上,出于用户安全原因,许多浏览器会阻止立即下载。如果您使用此解决方案,请不要启动文件下载,除非用户单击按钮有意下载。
为了解决这个问题,我需要从绕过任何 CORS 策略的 URL 中获取文件,以保存一个本地 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);
);
此解决方案参考getting a blob from a URL 和using a CORS proxy 的解决方案。
更新 从 January 31st, 2021 开始,托管在 Heroku 服务器上的 cors-anywhere 演示仅允许有限地用于测试目的,不能用于生产应用程序。您必须通过cors-anywhere 或cors-server 来托管您自己的 cors-anywhere 服务器。
【讨论】:
【参考方案8】:我们可以使用 react-download-link 组件将内容下载为文件。
<DownloadLink
label="Download"
filename="fileName.txt"
exportFile=() => "Client side cache data here…"/>
https://frugalisminds.com/how-to-download-file-in-react-js-react-download-link/
【讨论】:
【参考方案9】:解决方案(适用于 React JS、Next JS)
您可以使用 js-file-download,这是我的示例:
import axios from 'axios'
import fileDownload from 'js-file-download'
...
handleDownload = (url, filename) =>
axios.get(url,
responseType: 'blob',
)
.then((res) =>
fileDownload(res.data, filename)
)
...
<button onClick=() => this.handleDownload('https://your-website.com/your-image.jpg', 'test-download.jpg')
>Download Image</button>
此插件可以下载excel等文件类型。
【讨论】:
这很好用,要求另存为,这是我正在寻找的 下载后无法打开文件,文件错误:“文件(nameFile)无法打开。它可能已损坏或使用了预览无法识别的文件格式。”我错过了什么吗? 它对我有用。感谢您提供此解决方案。【参考方案10】:您可以使用FileSaver.js 来实现这个目标:
const saveFile = () =>
fileSaver.saveAs(
process.env.REACT_APP_CLIENT_URL + "/resources/cv.pdf",
"MyCV.pdf"
);
;
<button className="cv" onClick=saveFile>
Download File
</button>
【讨论】:
使用fileSaver时会在新标签页打开pdf @DivyeshKanzariya 你怎么能解决这个问题?【参考方案11】:这就是我在 React 中的做法:
import MyPDF from '../path/to/file.pdf';
<a href=myPDF download="My_File.pdf"> Download Here </a>
使用download="name_of_file_you_want.pdf"
覆盖默认文件名很重要,否则下载时文件会附上一个哈希号。
【讨论】:
【参考方案12】:我有完全相同的问题,这是我现在使用的解决方案: (注意,这对我来说似乎很理想,因为它使文件与从 Amazon S3 加载的 SinglePageApplication React 应用程序密切相关。所以,这就像存储在 S3 和应用程序中,相对而言,它知道它在 S3 中的位置.
步骤
三个步骤:
-
在项目中使用文件保护程序:npmjs/package/file-saver(
npm install file-saver
什么的)
将文件放入您的项目中您说它在 components 文件夹中。好吧,如果你有 web-pack,它可能会尝试缩小它。(有人请指出 webpack 会对 components 文件夹中的资产文件做什么),所以我认为这不是你想要的.因此,我建议将资产放入public
文件夹中,使用resource
或asset
名称。 Webpack 不会触及 public
文件夹和 index.html
并且您的资源会按原样复制到生产构建中,您可以在下一步中引用它们。
参考你项目中的文件 示例代码:
import FileSaver from 'file-saver';
FileSaver.saveAs(
process.env.PUBLIC_URL + "/resource/file.anyType",
"fileNameYouWishCustomerToDownLoadAs.anyType");
来源
Create-React-App.dev | Using the public folder Github | File saver documentation附录
我还尝试了react-router
react-router-docs/Link 的Link
组件。 zip 文件将下载,并以某种方式正确解压缩。一般来说,链接是蓝色的,要继承父配色方案,只需添加一个类似的道具:style=color: inherit
或简单地分配你的 CSS 库的一个类,如 button button-primary
或其他东西,如果你是 Bootstrappin'
与它密切相关的其他圣人问题:
download file in react
how to download file in react js
button to download a file in reactJS
download sample file in public folder (react)
【讨论】:
这是一个很酷的库。不幸的是,它仍然在新选项卡中打开了 PDF。不过,它使动态打开文件成为一个非常干净的过程。【参考方案13】:将a
标记与target="_blank"
一起使用时,React 会出现安全问题。
我设法让它像这样工作:
<a href=uploadedFileLink target="_blank" rel="noopener noreferrer" download>
<Button>
<i className="fas fa-download"/>
Download File
</Button>
</a>
【讨论】:
【参考方案14】:您可以定义一个组件并在任何地方使用它。
import React from 'react';
import PropTypes from 'prop-types';
export const DownloadLink = ( to, children, ...rest ) =>
return (
<a
...rest
href=to
download
>
children
</a>
);
;
DownloadLink.propTypes =
to: PropTypes.string,
children: PropTypes.any,
;
export default DownloadLink;
【讨论】:
【参考方案15】:如果您使用的是 React Router,请使用:
<Link to="/files/myfile.pdf" target="_blank" download>Download</Link>
/files/myfile.pdf
在您的public
文件夹中的位置。
【讨论】:
我尝试使用 zip 文件,文件下载,但从未正确解压缩。有人可能知道它的原因吗?顺便说一句,我找到了解决方法:***.com/a/62855917/7622204【参考方案16】:浏览器足够智能,可以检测链接并在单击锚标记时直接下载链接,而无需使用下载属性。
从 api 获取文件链接后,只需通过创建锚标记使用纯 javascript 并在动态单击后立即将其删除。
const link = document.createElement('a');
link.href = `your_link.pdf`;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
【讨论】:
除了浏览器会打开一个PDF,我想下载它。未开放。 它也适用于 react 和 node/HAPI。我在下面添加了 link.href =your_link.pdf
;链接下载=yourFileName
;非常感谢。【参考方案17】:
这与 React 无关。但是,您可以使用锚点 <a>
元素上的 download
属性来告诉浏览器下载文件。
<a href='/somefile.txt' download>Click to download</a>
并非所有浏览器都支持此功能:https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a
【讨论】:
锚标签在同一浏览器选项卡中打开图像(图像预览),然后我们需要手动保存图像。我正在尝试在按钮单击时实现自动下载,而无需打开文件预览 更多详情请参考:***.com/questions/2408146/…download
遵守同源策略仅供参考
2021 年更新:95% 的浏览器支持 download
属性:caniuse.com/download 所以...?♂️以上是关于reactjs如何下载文件的主要内容,如果未能解决你的问题,请参考以下文章