React项目上传文件到AWS S3报错:Cannot read properties of undefined (reading 'byteLength')
问题原因&修复方案
你代码中存在两处核心错误导致报错:
- 凭证传入格式错误:AWS SDK v3 的
S3Client要求credentials字段直接接收包含accessKeyId、secretAccessKey两个属性的对象,你既多嵌套了一层creds包装,又把属性名写错为全大写的环境变量名,导致SDK无法正确读取凭证,触发byteLength相关报错。 - 上传方法调用逻辑错误:
parallelUploads3.done()是异步方法,返回Promise,你当前同步调用的情况下,不仅会在上传未完成时就把进度条设为100%,也会导致上传异常无法被try catch捕获。
修改后的代码参考
// 仅列出修改后的upload函数,其余代码保持不变 const upload = async (file) => { console.log("uploaded file", file); setImgUpload(0); const target = { Bucket: "rhmybucket", Key: file.name, Body: file, }; try { const parallelUploads3 = new Upload({ client: new S3Client({ region: "eu-central-1", // 直接传入符合格式的凭证对象,无需额外嵌套 credentials: { accessKeyId: process.env.REACT_APP_aws_access_key_id, secretAccessKey: process.env.REACT_APP_aws_secret_access_key, }, }), leavePartsOnError: false, params: target, }); parallelUploads3.on("httpUploadProgress", (progress) => { // 可以在这里根据progress.loaded / progress.total计算实时进度更新到imgUpload const percent = Math.round((progress.loaded / progress.total) * 100); setImgUpload(percent); console.log(progress); }); // 等待上传完成 await parallelUploads3.done(); setImgUpload(100); } catch (e) { console.log("error", e.message); } };
额外注意
前端直接嵌入AWS访问密钥存在极高安全风险,即使密钥存放在被.gitignore忽略的.env文件中,项目打包后密钥也会明文暴露在客户端代码里,任何人都可以通过抓包、查看静态资源获取密钥,恶意操作你的S3存储桶。生产环境建议改为后端生成S3预签名URL,前端使用预签名URL完成上传,完全避免密钥泄露风险。
内容的提问来源于stack exchange,提问作者notADevYet
相关产品推荐
相关产品推荐

