为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

料青山看我应如是 2022-11-03 14:59:39
我想实现一个大文件下载(大约 10-1024 Mb)。我已经成功从 Dropbox 获取了一个文件:operationResult = await dbx.filesDownload({    path: `/${CONFIG_STORAGE.uploader.assetsPath}/${fileUUID}`});然后我将接收到的文件与元数据捆绑在一起,并将其返回到我的 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;现在Buffer,我将从 Dropbox 获得的 a 转换为Readable流并将其通过管道传输回客户端: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);到目前为止,一切都很清楚并且有效。在这里我面临第一个陷阱:我需要以某种方式在浏览器中触发下载过程。在许多示例中,使用了一些小图像或 JSON,我们可以将其完全加载到 RAM 中,进行操作,例如转换为Base64,将其分配给a.href,并触发a.click()。但由于我的文件是 10-50 Mb,我不确定这种方法是否正确。我已经尝试过 Fetch 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();但我总是失败 - 没有文件错误。我还尝试使用 jQuery AJAX 和XMLHttpRequest( XHR),但仍然没有下载文件。也许,我缺少一些东西。如何从服务器获取 10-1024 Mb 的文件?PS 没想到像下载文件这样的小事,竟然这么复杂。
查看完整描述

1 回答

?
忽然笑

TA贡献1806条经验 获得超5个赞

我通过从filesDownloadto切换解决了这个问题filesGetTemporaryLink,它返回一个文件链接而不是文件本身。然后我触发下载此链接。


最终结果:


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;

然后我将输出发送给客户端:


res.json(downloadResult);

在客户端,我通过await/ asyncFetch 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();

因此,服务器根本不需要处理文件,没有额外的 CPU、RAM 或流量影响,无论我尝试下载多大的文件。


查看完整回答
反对 回复 2022-11-03
  • 1 回答
  • 0 关注
  • 114 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信