简体   繁体   English

如何使用 Node.js 从 Dropbox 下载大文件?

[英]How to download a big file from Dropbox with Node.js?

I want to implement a big file downloading (approx. 10-1024 Mb).我想实现一个大文件下载(大约 10-1024 Mb)。 I've already succeeded to get a file from Dropbox:我已经成功从 Dropbox 获取了一个文件:

operationResult = await dbx.filesDownload({
    path: `/${CONFIG_STORAGE.uploader.assetsPath}/${fileUUID}`
});

Then I bundle the received file with a meta-data and I return it to my Node.js server:然后我将收到的文件与元数据捆绑在一起,并将其返回到我的 Node.js 服务器:

fileMIME = mime.lookup(operationResult.name);

const downloadResult = Object.freeze({
    fileBinary: operationResult.fileBinary,
    fileLength: operationResult.fileBinary.length,
    fileMIME,
    fileName: operationResult.name,
    isSucceeded,
    message
});

return downloadResult;

Now I convert a Buffer , I got from Dropbox, into a Readable stream and pipe it back to a client:现在,我将从 Dropbox 获得的Buffer转换为Readable的 stream 和 pipe 将其返回给客户端:

res.setHeader("Content-Disposition", "attachment; filename=" + downloadResult.fileName);
res.setHeader("Content-Type", downloadResult.fileMIME);

const fileReadableStream = new Readable();

fileReadableStream.push(downloadResult.fileBinary);
fileReadableStream.push(null);

fileReadableStream.pipe(res);

Up until now everything is clear and works.到目前为止,一切都很清楚并且有效。 Here I face a first pitfall: I need somehow to trigger a download process in browser.在这里我面临第一个陷阱:我需要以某种方式在浏览器中触发下载过程。

In many examples, some small image or JSON are used, which we can completely load into RAM, make operations, eg transforming to Base64 , assign it to a.href , and trigger a.click() .在很多示例中,使用了一些小图像或 JSON,我们可以将其完全加载到 RAM 中,进行操作,例如转换为Base64 ,将其分配给a.href ,并触发a.click() But since my file is 10-50 Mb I'm not sure if such approach is a correct one.但由于我的文件是 10-50 Mb,我不确定这种方法是否正确。

I've already tried Fetch API:我已经尝试过获取 API:

const response = await fetch(`${host}/download?fileName=${fileName}`, {
    credentials: "same-origin",
    method: "POST",
    mode: "cors"
});

const a = document.createElement("a");
a.href = response.text();
a.download = "MyFile.pdf";
a.click();

But I always get Failed - No file error.但我总是失败 - 没有文件错误。 I also tried to use jQuery AJAX, and XMLHttpRequest ( XHR ), but still no file is downloaded.我还尝试使用 jQuery AJAX 和XMLHttpRequestXHR ),但仍然没有下载文件。

Perhaps, there is something I'm missing.也许,我缺少一些东西。 How to get a 10-1024 Mb file from a server?如何从服务器获取 10-1024 Mb 的文件?

PS I never thought that such a trivial task, as a file downloading, can be so complicated. PS 没想到像下载文件这样的小事,竟然这么复杂。

I've solved the issue by switching from filesDownload to filesGetTemporaryLink , which returns a link to a file instead of the file itself.我通过从filesDownload切换到filesGetTemporaryLink解决了这个问题,它返回一个文件链接而不是文件本身。 Then I trigger a downloading of this link.然后我触发下载此链接。

The final result:最终结果:

operationResult = await dbx.filesGetTemporaryLink({
    path: `/${CONFIG_STORAGE.uploader.assetsPath}/${fileUUID}`
});

const downloadResult = Object.freeze({
    fileLength: operationResult?.metadata.size,
    fileLink: operationResult?.link,
    fileMIME: mime.lookup(operationResult?.metadata.name),
    fileName: operationResult?.metadata.name,
    isSucceeded,
    message
});

return downloadResult;

Then I send the output to a client:然后我将 output 发送给客户端:

res.json(downloadResult);

On a client-side I get it via await / async Fetch API call:在客户端,我通过await / async Fetch API 调用获得它:

const fileResponse = await fetch(``${host}/downloadDocument`, {
    body: JSON.stringify({fileUUID: fileName}),
    cache: "no-cache",
    credentials: "same-origin",
    headers: {
        "Content-Type": "application/json"
    },
    method: "POST",
    mode: "cors"
});

const fileData = await fileResponse.json();

const aTag = document.createElement("a");

aTag.href = fileData.fileLink;
aTag.download = fileData.fileName;
aTag.click();

As a result, a server doesn't have to deal with files at all, no extra CPU, RAM, or traffic impact, no matter what size of a file I'm trying to download.因此,服务器根本不需要处理文件,没有额外的 CPU、RAM 或流量影响,无论我尝试下载什么大小的文件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM