【问题标题】:how can I fix conflicting query string params for S3 uploads?如何修复 S3 上传的查询字符串参数冲突?
【发布时间】:2015-10-27 21:43:47
【问题描述】:

我正在尝试在 react-native 应用的上下文中将原始图像数据上传到 S3。

我的原始数据是正确的,并且在大多数情况下,我认为我在 react native 中的代码可以正常工作以捕获图像数据。

在我的 Rails 服务器上,我正在使用 amazon ruby​​ gem 构建 URL 的详细信息以及将数据发布到相关存储桶所需的相关身份验证数据,然后我将其渲染为 react-native,就像普通的响应 web 前端。

# inside the rails server controller
s3_data = S3_BUCKET.presigned_post(key: "uploads/#{SecureRandom.uuid}/${filename}", success_action_status: '201', acl: 'public-read', url: 'https://jd-foo.s3-us-west-2.amazonaws.com')
render json: {s3Data: {fields: s3_data.fields, url: s3_data.url}}

在我尝试发布到 S3 的那一刻,我正在使用如下所示的 ES6 fetch 来构建我的 http 请求。

    saveImage(data) {
    var url = data.url
    var fields = data.fields
    var headers = {'Content-Type': 'multipart/form-data'}
    var body = `x-amz-algorithm=${encodeURIComponent(fields['x-amz-algorithm'])}&` + 
        `x-amz-credential=${encodeURIComponent(fields['x-amz-credential'])}&` + 
        `x-amz-date=${encodeURIComponent(fields['x-amz-date'])}&` +
        `x-amz-signature=${encodeURIComponent(fields['x-amz-signature'])}&` +
        `acl=${encodeURIComponent(fields['acl'])}&` +
        `key=${encodeURIComponent(fields['key'])}&` +
        `policy=${encodeURIComponent(fields['policy'])}&` +
        `success_action_status=${encodeURIComponent(fields['success_action_status'])}&` +
        `file=${encodeURIComponent('12foo')}`
    console.log(body);
    return fetch(url, {method: 'POST', body: body, headers: headers})
        .then((res) =>  {console.log('s3 inside api res', res['_bodyText']) ; res.json()} );
}

身体的日志看起来像

x-amz-algorithm=AWS4-HMAC-SHA256&x-amz-credential=AKIAJJ22D4PSUNBB5RAQ%2F20151027%2Fus-west-1%2Fs3%2Faws4_request&x-amz-date=20151027T223159Z&x-amz-signature=42b09d7ae134f803b10ef72d220fe74a630a3f826c7f1f625448277d0a6d93c7&acl=public-read&key=uploads%2F46be8ca3-6d3a-4bb7-a658-f2c8e058bc28%2F%24%7Bfilename%7D&policy=eyJleHBpcmF0aW9uIjoiMjAxNS0xMC0yN1QyMzozMTo1OVoiLCJjb25kaXRpb25zIjpbeyJidWNrZXQiOiJqZC1mb28ifSxbInN0YXJ0cy13aXRoIiwiJGtleSIsInVwbG9hZHMvNDZiZThjYTMtNmQzYS00YmI3LWE2NTgtZjJjOGUwNThiYzI4LyJdLHsic3VjY2Vzc19hY3Rpb25fc3RhdHVzIjoiMjAxIn0seyJhY2wiOiJwdWJsaWMtcmVhZCJ9LHsieC1hbXotY3JlZGVudGlhbCI6IkFLSUFKSjIyRDRQU1VOQkI1UkFRLzIwMTUxMDI3L3VzLXdlc3QtMS9zMy9hd3M0X3JlcXVlc3QifSx7IngtYW16LWFsZ29yaXRobSI6IkFXUzQtSE1BQy1TSEEyNTYifSx7IngtYW16LWRhdGUiOiIyMDE1MTAyN1QyMjMxNTlaIn1dfQ%3D%3D&success_action_status=201&file=12foo

看来我的问题可能与两者有关

  1. 帖子正文格式错误,包括特殊字符问题

  2. 没有在帖子正文中为 S3 提供足够的数据,包括密钥和其他信息,文档感觉有点不清楚什么是/不需要什么。

从 S3 服务器返回的错误看起来像

<?xml version="1.0" encoding="UTF-8"?>
<Error><Code>MalformedPOSTRequest</Code><Message>The body of your POST request is not well-formed multipart/form-data.</Message>    <RequestId>DCE88AC349D7B2E8</RequestId><HostId>AKE1xctETuZMAhBFLfyuFlDxikYUlbAC7YufkM7h8Z8eVQdtLA25Z0Od/a4cMUbfW1nWnGjc+vM=</HostId></Error>

我很不清楚我的实际问题是什么以及我应该在哪里挖掘。

任何意见将不胜感激。

【问题讨论】:

  • 您是否曾经使用预签名的 URL 成功地将图像上传到 s3?我在这个问题上浪费了大约 5 天时间
  • @user2689931 我意识到,考虑到时间和工具内部的反应原生,构建多部分帖子是不可能的,所以我将 base64 图像数据传递给 Rails 服务器,然后发布数据从服务器而不是设备到 S3,回想起来这似乎是一个更好的模式。

标签: amazon-web-services amazon-s3 react-native


【解决方案1】:
<Message>The body of your POST request is not well-formed multipart/form-data.</Message>

这可能不是您缺少正文中的值。这里最重要的问题是你的身体结构不像multipart/form-data

请参阅 RFC 2388 了解 multipart/form-data 的工作原理。 (或者找一个为你构建这个的库。)

您发送的内容看起来更像application/x-www-form-urlencoded 格式,某些 AWS API 使用这种格式,但 S3 不使用这种格式。

There is an example in the S3 docs 显示示例 POST 正文可能的样子。您应该在那里看到很大的不同。


另请注意,POST 用于基于浏览器的上传。如果你是从代码中加载,你正在做很多额外的工作。 PUT Object 更直接。请求正文是二进制文件内容。或者,如果这最终将由浏览器完成,则使用浏览器对其进行测试,然后让浏览器构建您的表单。

【讨论】:

    猜你喜欢
    • 2012-02-08
    • 1970-01-01
    • 2022-11-04
    • 1970-01-01
    • 1970-01-01
    • 2014-01-24
    • 2023-02-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多