使用进度处理程序时将文件上传到AWS S3有反应

0

的问题

我只是最近处理与 传输 ,并因此请原谅如果我的方法完全是胡说八道。

我想上传一个简单的媒体文件到我的S3。 我是以下 这个教程 和迄今为止,我能够上传文件而不是一个问题。 为userbility进度条会是一个不错的额外因此,我正在研究如何实现这一点。 我很快就发现, 目前的传输 v3 不支持 httpUploadProgress 但是,我们应该使用 @aws-sdk/lib-storage 代替。 使用这个图书馆,我仍然能够将文件上传到S3但我不能获取的进展跟踪工作! 我以为这有什么我不完全了解如何处理 async 在一个反应的组成部分。

因此,这里是我缩小成分的实例(我采用轮UI在这里)

const TestAWS: React.FC = () => {
  const inputRef = useRef<HTMLInputElement | null>(null);
  const [progr, setProgr] = useState<number>();

  const region = "eu-west-1";
  const bucketname = "upload-test";

  const handleClick = async () => {
    inputRef.current?.click();
  };

  const handleChange = (e: any) => {

    console.log('Start file upload');

    const file = e.target.files[0];
    const target = {
      Bucket: bucketname,
      Key: `jobs/${file.name}`,
      Body: file,
    };

    const s3 = new S3Client({
      region: region,
      credentials: fromCognitoIdentityPool({
        client: new CognitoIdentityClient({ region: region }),
        identityPoolId: "---MY ID---",
      }),
    });

    const upload = new Upload({
      client: s3,
      params: target,
    });

    const t = upload.on("httpUploadProgress", progress => {
      console.log("Progress", progress);

      if (progress.loaded && progress.total) {
        console.log("loaded/total", progress.loaded, progress.total);
        setProgr(Math.round((progress.loaded / progress.total) * 100)); // I was expecting this line to be sufficient for updating my component
      }
    });
    await upload.done().then(r => console.log(r));
  };

console.log('Progress', progr);

return (
    <InputGroup onClick={handleClick}>
      <input ref={inputRef} type={"file"} multiple={false} hidden accept='video/*' onChange={e => handleChange(e)} />
      <Flex layerStyle='uploadField'>
        <Center w='100%'>
          <VStack>
            <PlusIcon />
            <Text>Choose Video File</Text>
          </VStack>
        </Center>
      </Flex>
      {progr && <Progress value={progr} />}
    </InputGroup>
  );
};

export default TestAWS;

所以基本上我看到事件得到解雇了 (启动文件上载). 然后它需要一段时间,我看到的结果和承诺 Progress, 100 在我的控制台。 这对我意味着国家变得到更新(至少一次),但该件没有重新呈现的?

它是什么我在做什么错在这里? 任何帮助,感谢!

amazon-s3 aws-sdk reactjs
2021-11-22 15:34:31
2

最好的答案

1

好吧,我已找到的解决方案。 回调的状态变量和不什么应该的。 但配置的 Upload 目的是关闭的。 后挖掘入来源,我发现,事件监听器只会触发,如果 上传已经上传了更多的数据. 因为上传块上传你有两个分配参数,让你可以拆分上载入单独的区块。 所以

const upload = new Upload({
  client: s3,
  params: target,
  queueSize: 4,          // 4 is minimum
  partSize: 5*1024*1024  // 5MB is minimum
});

基本上没有工作文件时我们上传是 大于5MB! 只有这样的事件再次触发和更新国家可变的。

由于这个上传者是由于处理大文件上载,这是完全有道理的,我们可以简单的调整 queueSizepartSize 根据该文件,我们希望,以上载。 喜欢的东西

let queueSize = 10;
const file = event.target.files[0];

let partSize = file.size / (10 * 1024 * 1024);    // 1/10th of the file size in MB

const upload = new Upload({
  client: s3,
  params: target,
  queueSize: partSize > 5 queueSize : undefined,
  partSize: partSize > 5 ? partsize : undefined
});

显然,这是可以做到更复杂的,但我不想花太多时间在这因为它不是部分原来的问题。

结论

如果你的 文件是足够大 (>5MB),您将看到更新的进展,取决于数量大块的(5MB或更多)已选择分割你的文件。

因为这只会影响 handleChange 方法从原来的例子中,我后这完整性

const handleChange = async ( event ) => {
  const file = event.target.files[0]

  const target = {
    Bucket: 'some-S3-bucket',
    Key: `jobs/${file.name}`,
    Body: file,
  };

  const s3 = new S3Client({
    region: 'your-region',
    credentials: fromCognitoIdentityPool({
      client: new CognitoIdentityClient({ region: 'your-region' }),
      identityPoolId: "your-id",
    }),
  });

  // this will default to queueSize=4 and partSize=5MB
  const upload = new Upload({
    client: s3,
    params: target
  });

  upload.on("httpUploadProgress", progress => {
    console.log('Current Progress', progress);
    setProgr(progress);
  });

  await upload.done().then(r => console.log(r));
} 

也许这可以帮助某人有同样的问题。

2021-11-22 18:06:15
1

我遇到了你的答复后,具有完全相同的问题(与Vue)今天!

事实上,你是正确的:在传输JS v3事件只火灾每 一部分 ,这是不清楚和我浪费时间的调试这一点。 像一4M文件,这只会过火的100%。

正如你所说,你可以尝试的一部分大小 ,但 最低为5MB和使连接速度较慢,我发现它可以出现这一传坚持你必须要等待5MB获得 任何 数据。 嗯。 那么我所做的是看看尺寸的文件正在上传。 如果它是下一个阈值(说25MB,或任何适用),以及它可能是安全的上载,都在一个去你真的不需要多部分上传。 所以我 做了一个预签名网址(https://aws.amazon.com/blogs/developer/generate-presigned-url-modular-aws-sdk-javascript/),它可被用来把使用爱可信(因为 fetch 不支持进步事件)。

所以这种方式可以使用 upload 对于大型的文件(在那里,你实际上需要多部分上载并在5MB作为一个百分比,文件大小),并使用一个预签名URL小的文件,并因此获得更频繁地更新。

同样的进展的事件的处理程序可以由两个。

this.$axios
  .request({
     method: "PUT",
     url: SIGNED-URL-HERE,
     data: file,
     timeout: 3600 * 1000,
     onUploadProgress: this.uploadProgress,
  })
  .then((data) => {
     console.log("Success", data);
  })
  .catch((error) => {
     console.log("Error", error.code, error.message);
  });

不理想,但它可以帮助。

2021-11-24 00:54:55

我有同样的想法,但是公平的,我猜 lib-storage 从来就不是用于小型的文件上传。 不幸的是,它似乎目前还没有令人满意的解决方案时使用 v3 (因为它使用取api引擎盖下)和上传小的文件。 所以你的方式绝对是一个很好的解决方法,但希望他们将会实施的东西在SDK很快。
Flo Ragossnig

我同意。 这很烦人具有使用已签署的网址作为一个解决方法,但除非/直到SDK改动(也许当取API增加上传的进展)对于现在看来,你必须选择取决于是否多部分或经常的进度更新是最重要的是要你使用
coder_uk

其他语言

此页面有其他语言版本

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................