首页 > 解决方案 > 从节点流式传输并在 javascript 客户端上生成 blob 的文件要大得多且已损坏

问题描述

我正在使用 Clio API,这是一个第三方 API,具有一些基于云的文档存储。我希望我们的用户从他们的 API 下载视频/音频文档,但是由于它的设计,我必须使用我的 node.js 服务器作为代理来绕过 CORS 限制。

流程是:

  1. 用户请求将文档下载到我的服务器
  2. 我的服务器向 API 发出请求以下载文档
  3. 我的服务器将响应流式传输到客户端

因为文档可能很大(1GB+),我试图将我的服务器获取的文件流式传输到客户端。

问题是客户端收到的文件已损坏并且比实际文件大。以下是我目前提出请求的方式(注意:我们通常使用 axios,但我不确定如何使用该包执行下面的操作,所以现在我使用 request 包进行概念验证)

对于大小约为 220kb 的 MP4 文件:

request({
      url: `https://app.clio.com/api/v4/documents/${documentId}/download.json`,
      headers: { Authorization: `Bearer ${accessToken}` },
    }).pipe(res);

然后在客户端我们收到如下响应:

response.blob()

令人困惑的是,生成的 blob 是这样的:

Blob {size: 407852, type: "application/mp4"}

大小几乎是文件实际大小的两倍,我不明白为什么。此外,从这里下载和播放 mp4 是不可能的,因为 mp4 文件已损坏并且无法播放。这特别奇怪,因为如果我决定将服务器请求通过管道传输到服务器上的文件,如下所示:

    const filepath = path.resolve(__dirname, "test.mp4");
    const writer = fs.createWriteStream(filepath);

    request({
      url: `https://app.clio.com/api/v4/documents/${documentId}/download.json`,
      headers: { Authorization: `Bearer ${accessToken}` },
    }).pipe(writer);

生成的“test.mp4”大小正确,播放正常。

问题似乎是专门将文件流式传输到客户端。当我尝试查看到达客户端的原始数据时(通过 response.text()),我看到的示例如下:

\u0000\u0000\u0000\u001cftypmp42\u0000\u0000\u0000\u0001mp41mp42isom\u0000\u0000\u0000\u0001mdat\u0000\u0000\u0000\u0000\u0000\u0003UJ!*Te&(�B��4�p*hUī\u0012��Т�\u0012ɾ���0�P}�C$��}<��Gc�^�#~��ʠ6�^��m���&lt;E���Y\u0013\t(Ѳ��x�\u0015/3c�(�����\u000b�4O\u0006�{$�d_J�\\j���^�ԑ\u0017~�&amp;��iǠN�QV��\t\u0006%�B��05\u0012�kW�l\u0006hfZ�q7\u0000\u0006�v%��G���/2*\u000e\u0001-�^^6i�|

这似乎是 UTF8 编码的数据,带有一些 - 我猜 - 替换字符。我认为这可能是膨胀 blob 大小并损坏 mp4 文件的原因。

会发生什么?

标签: node.jsreactjsexpressutf-8clio-api

解决方案


推荐阅读