How to download a ReadableStream on the browser that has been returned from fetch(如何在浏览器上下载从 fetch 返回的 ReadableStream)
问题描述
我正在接收来自服务器的 ReadableStream,它是从我的 fetch 调用返回的.
I am receiving a ReadableStream from a server, returned from my fetch call.
返回了 ReadableStream,但我不知道如何从这个阶段触发下载.我不能在 href 中使用 url,因为它需要授权令牌.
A ReadableStream is returned but I don't know how to trigger a download from this stage. I can't use the url in an href because it requires an Authorization token.
我不想在客户端安装 fs
那么我有什么选择?
I don't want to install fs
on the client so what options do I have?
try {
const res = await fetch(url, {
method: 'GET',
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/octet-stream'
}
});
const blob = await res.blob();
const newBlob = new Blob([blob]);
const newUrl = window.URL.createObjectURL(newBlob);
const link = document.createElement('a');
link.href = newUrl;
link.setAttribute('download', 'filename');
document.body.appendChild(link);
link.click();
link.parentNode.removeChild(link);
window.URL.revokeObjectURL(newBlob);
} catch (error) {
console.log(error);
}
更新 1
我将文件转换为 Blob,然后将其传递给新生成的 href.成功下载了一个文件.最终结果是 ReadStream 内容为 .txt 文件.
I converted the file to a Blob, then passed it into a newly generated href. Successfully downloaded a file. The end result was the ReadStream contents as a .txt file.
意思是这样的
x:ÚêÒÓ%¶âÜTb∞܃
推荐答案
我找到了 2 个解决方案,两者都有效,但我缺少一个简单的补充来使它们有效.
I have found 2 solutions, both worked but I was missing a simple addition to make them work.
原生解决方案是
try {
const res = await fetch(url, {
method: 'GET',
headers: {
Authorization: `Bearer ${token}`
}
});
const blob = await res.blob();
const newBlob = new Blob([blob]);
const blobUrl = window.URL.createObjectURL(newBlob);
const link = document.createElement('a');
link.href = blobUrl;
link.setAttribute('download', `${filename}.${extension}`);
document.body.appendChild(link);
link.click();
link.parentNode.removeChild(link);
// clean up Url
window.URL.revokeObjectURL(blobUrl);
此版本正在使用 npm 包 steamSaver 供任何喜欢它的人使用.
This version is using the npm package steamSaver for anyone who would prefer it.
try {
const res = await fetch(url, {
method: 'GET',
headers: {
Authorization: `Bearer ${token}`
}
});
const fileStream = streamSaver.createWriteStream(`${filename}.${extension}`);
const writer = fileStream.getWriter();
const reader = res.body.getReader();
const pump = () => reader.read()
.then(({ value, done }) => {
if (done) writer.close();
else {
writer.write(value);
return writer.ready.then(pump);
}
});
await pump()
.then(() => console.log('Closed the stream, Done writing'))
.catch(err => console.log(err));
它不起作用的关键是因为我没有包含扩展名,所以它要么因为 mimetype 错误而出错,要么它打开一个带有正文字符串而不是图像的 .txt 文件.
The key for why it was not working was because I did not include the extension, so it either errored out because of the mimetype was wrong or it opens a .txt file with a string of the body instead of the image.
这篇关于如何在浏览器上下载从 fetch 返回的 ReadableStream的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:如何在浏览器上下载从 fetch 返回的 ReadableStream


- Quasar 2+Apollo:错误:找不到ID为默认的Apollo客户端。如果您在组件设置之外,请使用ProvideApolloClient() 2022-01-01
- 400或500级别的HTTP响应 2022-01-01
- CSS媒体查询(最大高度)不起作用,但为什么? 2022-01-01
- Css:将嵌套元素定位在父元素边界之外一点 2022-09-07
- 使用RSelum从网站(报纸档案)中抓取多个网页 2022-09-06
- Fetch API 如何获取响应体? 2022-01-01
- 失败的 Canvas 360 jquery 插件 2022-01-01
- addEventListener 在 IE 11 中不起作用 2022-01-01
- Flexslider 箭头未正确显示 2022-01-01
- 如何使用 JSON 格式的 jQuery AJAX 从 .cfm 页面输出查 2022-01-01