提问者:小点点

从完全形成的响应触发大文件下载


我有一个Node. jsendpoint,当使用以下方式访问时,它会正确触发任意大的文件下载:

response.setHeader('Content-disposition', 'attachment; filename=' + fileName);
response.set('Content-Type', 'text/csv');
response.status(200);
result.pipe(response);

其中结果是转换流,响应是Express对象。

这在Chrome、Firefox、Internet Explorer等中直接访问endpoint时工作正常。当启用基于令牌的身份验证时,尝试访问endpoint会出现问题。

从用户的角度来看,当他们单击按钮时,会下载一个文件。

如何使用请求标头中的正确身份验证令牌使按钮击中此endpoint并导致下载文件?

>

  • 当用户点击按钮时,它会触发一个由redux-api-middleware处理的操作,该操作会将GET请求发送到endpoint(请求中自动包含身份验证令牌)。该中间件将响应保存在一个变量中,该变量由React组件拾取。在这个React组件中,如果正在使用的浏览器(即Chrome和Opera)支持流,response. body将存在,因此您可以执行如下操作。

    if (response.body) {
        const csvReader = response.body.getReader();
        const textDecoder = new TextDecoder();
        const processCsvRow = (csvRow) => {
            if (csvRow.done) {
                console.log('Finished downloading file.');
                return Promise.resolve();
            }
    
            // Write to new file for user to download
            console.log(textDecoder.decode(csvRow.value, {stream: true}));
    
            return csvReader.read().then(processCsvRow);
        };
    
        csvReader.read().then(processCsvRow);
    }
    

    使用这种方法,我需要研究如何处理由不支持流的浏览器接收的数据。

    当用户单击按钮时,它会触发一个操作,该操作将endpoint保存到Redux存储中,这会触发React组件创建一个自动单击的锚点标签。

    const link = document.createElement('a');
    document.body.appendChild(link); // Firefox requires the link to be in the body
    link.href = endPoint;
    link.target = '_blank';
    link.click();
    document.body.removeChild(link); // Remove the link when done
    

    其中endPoint是响应文件的endpoint。

    当禁用身份验证时,此方法有效。当重新启用身份验证时,身份验证令牌必须以某种方式注入到锚标记的请求标头中。


  • 共1个答案

    匿名用户

    我现在决定采用方法7。