AWS Amplify调用API Gateway上传二进制文件失败求助
解决Amplify API.post上传二进制文件损坏的问题
我来帮你搞定这个问题——核心原因是Amplify的API.post默认会对请求体做JSON序列化处理,当你用readAsDataURL传递base64字符串时,Amplify会把它当成普通文本发送,导致S3中存储的是base64编码的文本(而非原始二进制),这就是文件体积变大、无法正常打开的原因。结合你的场景,我们可以通过以下步骤修复:
1. 修正文件读取方式,获取原始二进制数据
放弃readAsDataURL,改用readAsArrayBuffer读取文件,这样能拿到文件的原始二进制缓冲区,避免base64编码带来的额外体积和格式问题。
2. 配置Amplify API支持二进制媒体类型
在你的aws-exports.js中,找到对应的API端点配置,添加binaryMediaTypes字段,指定你需要支持的二进制类型(比如PDF、图片等),告诉Amplify不要对这些类型的请求做JSON序列化:
// aws-exports.js 中的API配置示例 "api": { "endpoints": [ { "name": "lambdadocshell", "endpoint": "https://XXXXXXXXXX.execute-api.us-east-1.amazonaws.com/dev", "binaryMediaTypes": ["application/pdf", "image/jpeg", "image/png"] // 根据你的需求添加类型 } ] }
3. 修改Amplify上传函数,传递二进制数据
把读取到的ArrayBuffer转换成Uint8Array作为请求体,同时设置正确的Content-Type头(使用文件本身的MIME类型):
uploadImageLambda = async(event) => { const file = event.target.files[0]; console.log('Saving File Via Lambda: ' + file.name); // 用Promise封装FileReader,避免回调嵌套 const arrayBuffer = await new Promise((resolve, reject) => { const reader = new FileReader(); reader.onload = () => resolve(reader.result); reader.onerror = (err) => reject(err); reader.readAsArrayBuffer(file); }); try { return await API.post("lambdadocshell", 'upload', { headers: { 'Content-Type': file.type, // 使用文件实际的MIME类型 }, body: new Uint8Array(arrayBuffer), // 传递二进制数组 responseType: 'blob' // 可选,根据API返回的响应类型设置 }); } catch (e) { console.error('上传失败:', e); } }
额外检查点
- 确认API Gateway的Settings页面已经添加了对应的二进制媒体类型(和Amplify配置的一致),确保API Gateway能正确识别并传递二进制数据到Lambda。
- 你的Lambda函数逻辑不需要修改(因为Postman/Curl测试正常),它应该已经正确处理了API Gateway传来的base64编码的body(API Gateway会自动把二进制请求体转成base64字符串传给Lambda)。
这样修改后,Amplify会以原始二进制格式发送请求,同时保留Cognito的认证信息,上传后的文件就能正常打开了。
内容的提问来源于stack exchange,提问作者SpaceBrain
相关产品推荐
相关产品推荐

