首页 > 解决方案 > 使用流下载带有身份验证令牌的大文件

问题描述

我正在尝试使用 下载文件fetch,因为它需要在其标题中进行身份验证。问题是当文件太大时,用户不得不等待很长时间才能从浏览器得到任何反馈,直到它说文件实际上已经下载,所以我尝试了流媒体,让出现“下载" 浏览器中的菜单,同时下载。

在此处输入图像描述

虽然它适用于 Chrome,但我现在面临的问题是 Firefox 似乎不支持 Stream API,所以我尝试使用 polyfill,但它似乎不起作用。

import { createWriteStream, supported } from 'streamsaver';
import { WritableStream } from 'web-streams-polyfill/ponyfill/es6';

const downloadWithToken = async (url, name) => {

    const token = localStorage.getItem('token');
    const authorization = 'Bearer ' + token;
    const headers = new Headers({ authorization });
    const options = { headers };

    let response = await fetch(url, options)

    if (!supported) {
        window.WritableStream = WritableStream;
    }
    const filestream = createWriteStream(name);
    const writer = filestream.getWriter();

    if (response.body.pipeTo) {
        writer.releaseLock();
        return response.body.pipeTo(filestream);
    }

    const reader = response.body.getReader();

    const pump = () =>
        reader
            .read()
            .then(({ value, done }) => (done ? writer.close() : writer.write(value).then(pump)));

    pump();
};

我究竟做错了什么?

标签: downloadstreamcross-browserpolyfills

解决方案


我有同样的问题(如何使用来自 Axios 的流)。这就是我解决它的方法:

import { WritableStream } from 'web-streams-polyfill/ponyfill';
import streamSaver from 'streamsaver';

// If the WritableStream is not available (Firefox, Safari), take it from the ponyfill
if (!window.WritableStream) {
    streamSaver.WritableStream = WritableStream;
}

const fileStream = streamSaver.createWriteStream(fileName);

// The rest stays more or less the same, depends on the use case. For more detail in this section, refer to this example:
// https://jimmywarting.github.io/StreamSaver.js/examples/fetch.html

这个想法是检查window.WritableStream当前浏览器是否可用。如果没有,则将WritableStreamfromponyfill直接分配给streamSaver.WritableStream属性。

在 Google Chrome 78、Firefox 70、Safari 13 上测试;web-streams-polyfill 2.0.5StreamSaver.js 2.0.3


推荐阅读