React Native使用AWS Amplify上传视频遇Access Denied错误
解决React Native + AWS Amplify 上传视频到S3出现403 AccessDenied的问题
核心问题分析
你遇到的403错误+未处理Promise拒绝,通常和权限配置不全、Amplify Storage参数设置问题、Promise未正确捕获异常这几个点相关,下面逐一给出解决方案:
1. 补全S3桶权限配置
当前桶策略仅授权对象级({BUCKET_NAME}/*)操作,但开启resumable: true后Amplify会使用分段上传,需要额外桶级权限,同时建议明确操作范围避免过度开放:
{ "Version": "2012-10-17", "Statement": [ { "Sid": "AllowAmplifyUploadOperations", "Effect": "Allow", "Principal": "*", // 生产环境建议替换为你的Amplify Auth角色ARN "Action": [ "s3:PutObject", "s3:ListMultipartUploads", "s3:AbortMultipartUpload", "s3:ListParts" ], "Resource": [ "arn:aws:s3:::{BUCKET_NAME}/*", "arn:aws:s3:::{BUCKET_NAME}" // 桶级权限支持分段上传相关操作 ] } ] }
同时必须配置S3桶CORS规则,允许跨域请求:
<CORSConfiguration> <CORSRule> <AllowedOrigin>*</AllowedOrigin> <!-- 生产环境替换为APP实际域名 --> <AllowedMethod>PUT</AllowedMethod> <AllowedMethod>POST</AllowedMethod> <AllowedMethod>DELETE</AllowedMethod> <AllowedHeader>*</AllowedHeader> <ExposeHeader>ETag</ExposeHeader> <ExposeHeader>x-amz-meta-custom-header</ExposeHeader> </CORSRule> </CORSConfiguration>
2. 修正Amplify Storage上传参数
- 自动检测MIME类型:手动拼接
video/${extension}可能导致类型错误(比如.mov对应video/quicktime而非video/mov),改为自动检测:// 替换原contentType配置 contentType: file.type || `video/${extension}`, - 捕获Promise异常:
Storage.put返回的Promise未被捕获,导致未处理拒绝,在函数内添加catch逻辑:const putRequest = Storage.put(fileName, file, fileProps) // 捕获Promise异常,避免未处理拒绝 putRequest.catch(err => { console.error('Upload promise error', err) props.onErrorUpload(withTranslation('jobs_error_upload')) }) return putRequest - 验证customPrefix配置:确认
amplifyconfiguration.json中Storage的defaultAccessLevel为public,避免路径冲突:"storage": { "plugins": { "awsS3": { "bucket": "{BUCKET_NAME}", "region": "{REGION}", "defaultAccessLevel": "public" } } }
3. 确认Amplify Auth角色权限
检查Amplify Auth角色是否包含S3上传权限,添加如下IAM策略:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:PutObject", "s3:ListMultipartUploads", "s3:AbortMultipartUpload", "s3:ListParts" ], "Resource": [ "arn:aws:s3:::{BUCKET_NAME}/jobs/*" // 限定到上传路径,提升安全性 ] } ] }
4. 修正取消上传函数的参数类型
Storage.put返回的是StoragePutOutput而非Promise<Object>,调整参数类型:
const cancelRequestUploadFile = (putOutput: StoragePutOutput<StorageProvider>): void => { try { void Storage.cancel(putOutput, 'onPress cancel request') } catch (e: any) { console.log('Cancel error', e) if (Storage.isCancelError(e)) { console.log(e.message) } } }
验证步骤
- 重新部署Amplify配置(
amplify push) - 清除React Native缓存(
npx react-native start --reset-cache) - 测试上传,查看控制台是否仍有403错误
内容的提问来源于stack exchange,提问作者fabio87
相关产品推荐
相关产品推荐

