我从服务器接收 ReadableStream,从我的 fetch 调用返回。
返回了 ReadableStream,但我不知道如何从该阶段触发下载。我无法在 href 中使用 url,因为它需要授权令牌。
我不想在客户端上安装
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);
// clean up Url
window.URL.revokeObjectURL(blobUrl);
此版本使用 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 文件。
我使用 file-saver 下载 ReadableStream
import FileSaver from 'file-saver';
// ...
const res = await fetch("YOUR_URL", requestOptions);
const blob = await res.blob();
FileSaver.saveAs(blob, "test.zip");