使用 https 从浏览器上传文件以进行进度更新

问题描述 投票:0回答:1

Axios 似乎对于文件上传工作得很好,但是,由于它是前端应用程序,我想避免使用第三方库来执行简单的文件上传任务。

我的要求是能够上传文件并获取进度更新,文件大小可能为 1-3GB。

注意,我不能使用

FormData
,因为我最终想使用
S3 presigned urls
,它使用
PUT
并期望原始二进制文件。

除了使用 axios,我遇到了 2 个选择:

  1. 获取
  2. Https模块

虽然使用

fetch
上传似乎很简单,但似乎没有办法获取进度更新。

我遇到的障碍是

https
,它似乎需要一个
Readstream
,并且在浏览器中我无法使用
fs
模块。所以,只是看到接口,我做了一些像这样的黑客代码(举一个类似的例子,但是,这个使用表单数据):

import https from 'https';

// file = event.target.files[0]

export async function uploadFile(
  url: string,
  file: File,
  onProgress: () => void = noOp,
  method = REQ.PUT,
) {
  
 let progressDataLength = 0;
  let data = "";
  
  return new Promise((resolve, reject) => {
    const req = https.request(
      {
        hostname: url,
        method: method,
        headers: {
          "Content-Type": file.type,
          "Content-Length": file.size,
        },
      },
      function (res) {
        res.on("data", (chunk) => {
          progressDataLength += chunk.size;
          data += chunk;
          onProgress();
          console.log("Total received: ", `${chunk.size}/${file.size}`);
        });
        res.on("end", () => {
          resolve("Mydata: " + data);
        });
      },
    );  
       
     // MY HACKY CODE BIT
     const startConversionTime = new Date().getTime();
     Readable.from(Buffer.from(await file.arrayBuffer())).pipe(req);
     console.log(
       "Total conversion time taken: ",
       new Date().getTime() - startConversionTime,
    );  

    req.end();
  });
}

虽然这个特定的代码产生了下面的错误,但我不确定这是否合法? (转换完成了吗?而且,我真的找不到

File
转换为可读流的示例)

TypeError:“listener”参数必须是 Function 类型。收到类型对象

我有哪些实现此功能的选项以及如何完成?

javascript reactjs browser
1个回答
0
投票

不幸的是,fetch 本身并不支持上传过程中的进度更新。但是,您可以使用 XMLHttpRequest API,它确实提供进度跟踪。对于上传带有预签名 URL 的大文件并获取进度更新,XMLHttpRequest 更合适。

© www.soinside.com 2019 - 2024. All rights reserved.