PUT 上传文件到 AWS S3 预签名 URL Retrofit2 Android

Posted

技术标签:

【中文标题】PUT 上传文件到 AWS S3 预签名 URL Retrofit2 Android【英文标题】:PUT upload file to AWS S3 presigned url Retrofit2 Android 【发布时间】:2019-08-05 07:50:29 【问题描述】:

我有一个来自 AWS S3 的预签名上传 URL,用于将视频文件上传到。在 Postman 上测试视频已成功上传。但是,在改造中实施时,我得到了 403 返回。我不能为此任务使用分段上传。

服务调用:

@Headers("Content-Type: video/mp4")
    @PUT
    fun uploadTaskAWS(@Url awsUrl: String, @Body filePart: RequestBody): Call<ResponseBody>

上传:

            val file = File(task.file_path)
            val requestFile = RequestBody.create(MediaType.parse("video/mp4"), file)
            val response = awsTaskUploadService.uploadTaskAWS(task.upload_url, requestFile)

我已确保 URL 正确无误。还添加了内容类型标题,附上邮递员屏幕截图。获取 403 禁止错误

screenshot of postman

我找到了这个相关的问题,但是我仍然收到 403。Upload a file to AWS S3 pre-signed URL using Retrofit2

有什么建议吗?

【问题讨论】:

【参考方案1】:

解决方案是包含多部分并期望单一响应而不是调用:

  @Multipart
    @PUT
    fun uploadAsset(
        @Header(CONTENT_TYPE) contentType: String,
        @Url uploadUrl: String,
        @Part file: MultipartBody.Part
    ): Single<ResponseBody>

contentType 传入的地方

val requestFile = RequestBody.create(MediaType.parse(contentType), file)
val body = MultipartBody.Part.createFormData(mediaType, task.file_name, requestFile)
assetService.uploadAsset(contentType, task.upload_url, body)

【讨论】:

对于其他人来说,我遇到了同样的问题,建议的方法现在已被弃用,而且 android 现在使用内容提供程序,这使得访问底层文件变得很棘手,如果有兴趣我记录了我的解决方案 here跨度> 完美解决方案。关注@ZzAntáres 提到的链接 谢谢@ZzAntáres。 谢谢@ZzAntáres 男孩。你拯救了我的一天。 单身未定义。应该从哪里添加【参考方案2】:

403 错误意味着服务器知道你是谁,但无权执行所需的操作。

如果正确生成了预签名 URL,您应该能够在没有任何身份验证的情况下上传。

您可以检查邮递员是否默认添加任何 AWS 身份验证来请求

如果上传到仅使用版本 4 的区域,您还需要在签署请求时明确设置协议版本。

【讨论】:

协议版本是什么意思?

以上是关于PUT 上传文件到 AWS S3 预签名 URL Retrofit2 Android的主要内容,如果未能解决你的问题,请参考以下文章

仅从浏览器使用预签名 URL 上传时出现 AWS S3 CORS 错误

使用预签名的 url PUT 到 S3 会出现 403 错误

使用预签名 URL 上传到 S3 存储桶会出现 403 禁止错误

AWS 预签名 URL

AWS S3 PHP SDK 预签名 url 限制内容类型

AWS S3 PHP SDK 预签名 url 限制内容类型