如何从获取中返回的浏览器上下载ReadableStream [英] How to download a ReadableStream on the browser that has been returned from fetch
问题描述
我正在从服务器接收到ReadableStream,该请求是我的提取调用返回的.
返回了ReadableStream,但我不知道如何从此阶段触发下载.我无法在href中使用该网址,因为它需要授权令牌.
我不想在客户端上安装fs
,所以我有什么选择?
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文件.
意思是这样的
x:ÚêÒÓ%¶âÜTb∞\܃
我发现2种解决方案都可行,但是我却缺少一个简单的方法来使它们起作用.
本机解决方案是
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);
window.URL.revokeObjectURL(blob);
此版本对任何喜欢它的人使用npm包steamSaver.
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文件. /p>
I am receiving a ReadableStream from a server, returned from my fetch call.
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.
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);
}
Update 1
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.
Meaning stuff like this
x:ÚêÒÓ%¶âÜTb∞\܃
I have found 2 solution, both worked but I was missing a simple addition to make them work.
The native solution is
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);
window.URL.revokeObjectURL(blob);
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));
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.
这篇关于如何从获取中返回的浏览器上下载ReadableStream的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!