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

问题

我有一个Node.js端点,当使用以下命令访问时,可以正确触发一个任意大的文件下载:

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

其中result是变换stream , response是Express对象 。

当直接访问Chrome,Firefox,Internet Explorer等的terminal时,这种方式可以正常工作。当启用基于令牌的身份validation时,尝试达到终点时会出现问题。

从用户的angular度来看,当他们点击一个button时,文件被下载。

如何使该button在请求标题中find正确的身份validation令牌并导致文件被下载?

一些可能的方法集体讨论

  1. 当用户点击button时,它会触发一个由redux-api-middleware处理的动作,这会使GET请求到达终点(authentication令牌自动包含在请求中)。 该中间件将响应保存在由React组件拾取的variables中。 在这个React组件中,如果使用的浏览器(即Chrome和Opera)支持stream, 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); } 

    采用这种方法,我需要研究如何处理数据,如果它是由非stream支持浏览器接收。

  2. 当用户点击button时,会触发一个动作,通过reducer将终点保存到Redux存储区,触发React组件以创build一个自动点击的锚定标记。

     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是用文件响应的终点。

    此方法在禁用身份validation时起作用。 当重新启用身份validation时,身份validation令牌必须以某种方式注入到定位标记的请求标头中。

  3. 与#2类似,通过构build带有内置身份validation令牌的HTTP请求来模拟锚点单击。
  4. 结合#1和#2中的元素,当用户点击button时,会触发一个操作,向终点发送一个GET请求,返回第二个临时的不安全终点,返回实际的文件响应。 将这个临时的不安全的终点传递给#2中的锚标签。
  5. 以某种方式将响应redirect到新的选项卡/窗口。
  6. 将身份validation令牌作为URLparameter passing(这是一个安全问题),然后使用#2。
  7. 创build一个新的终点,生成并返回一个新的临时一次性使用下载令牌。 使用这个新的端点来获得一个临时的标记,作为一个URL参数通过#2传递到原始的终点。

我已经决定现在采用方法7。