我正在使用 Clio API,这是一个第三方 API,具有一些基于云的文档存储。我希望我们的用户从他们的 API 下载视频/音频文档,但是由于它的设计,我必须使用我的 node.js 服务器作为代理来绕过 CORS 限制。
流程是:
- 用户请求将文档下载到我的服务器
- 我的服务器向 API 发出请求以下载文档
- 我的服务器将响应流式传输到客户端
因为文档可能很大(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���<E���Y\u0013\t(Ѳ��x�\u0015/3c�(�����\u000b�4O\u0006�{$�d_J�\\j���^�ԑ\u0017~�&��iǠN�QV��\t\u0006%�B��05\u0012�kW�l\u0006hfZ�q7\u0000\u0006�v%��G���/2*\u000e\u0001-�^^6i�|
这似乎是 UTF8 编码的数据,带有一些 - 我猜 - 替换字符。我认为这可能是膨胀 blob 大小并损坏 mp4 文件的原因。
会发生什么?