Capacitor+Vue上传至Yandex Object Storage(S3兼容)Android端空文件问题
问题根源分析
你的核心问题在于错误使用FormData发送PUT请求到S3预签名URL,同时HTTP头配置不符合Yandex Object Storage的要求:
- S3兼容存储的预签名PUT接口期望直接接收文件原始字节流,而非
multipart/form-data格式的表单数据。浏览器端XMLHttpRequest能自动处理FormData序列化,但Android端Capacitor的HTTP客户端(底层基于OkHttp)在此场景下未正确解析FormData,导致请求体为空,最终生成0KB文件。 - 响应中的ETag
"d41d8cd98f00b204e9800998ecf8427e"是空字符串的MD5值,完全印证了请求体无任何内容。 - 手动设置的
Content-Type: multipart/form-data与预签名URL生成时指定的文件类型不匹配,导致存储服务无法正确处理上传内容。
解决方案
直接发送文件原始内容,无需用FormData包裹,同时设置正确的Content-Type:
修正后的代码示例
// 获取上传用的预签名URL const uploadLinkRequest = { url: 'https://functions.yandexcloud.net/******', headers: { 'Content-Type': 'text/plain' }, data: { action:'getUploadLink', key:this.file.name, type:this.file.type, size:this.file.size }, }; let signedUrl = await CapacitorHttp.post(uploadLinkRequest); signedUrl = signedUrl.data // 直接上传文件,不使用FormData const uploadResponse = await this.axios.put(signedUrl, this.file, { headers: { "Content-Type": this.file.type // 使用文件实际的Content-Type } }); console.log(uploadResponse)
CapacitorHttp写法参考
如果改用CapacitorHttp实现:
const uploadResponse = await CapacitorHttp.put({ url: signedUrl, data: this.file, headers: { "Content-Type": this.file.type } });
关键注意事项
- 确保生成预签名URL时指定的
Content-Type,与上传时设置的Content-Type完全一致,否则会触发签名验证失败(你当前返回200但内容为空,大概率是预签名时允许了任意Content-Type,但存储服务无法解析FormData格式)。 - S3类存储的PUT接口仅接收文件字节流,只有POST表单上传场景才需要使用FormData。
内容的提问来源于stack exchange,提问作者dindev
相关产品推荐
相关产品推荐

