【问题标题】:S3 rejects browser PUT's with presigned URLs - it thinks they're GET'sS3 拒绝带有预签名 URL 的浏览器 PUT - 它认为它们是 GET
【发布时间】:2023-03-23 13:57:01
【问题描述】:

我正在尝试使用带有 PUT 方法的预签名 URL 将文件从浏览器(Chrome 版本 41.0)上传到 S3。我在我的服务器上正确生成了预签名的 URL,因为它在 CURL 中运行良好:

curl -X PUT "Content-Type:" --data "junk" "https://mypresignedurl"

我现在正在尝试使用 jQuery 从浏览器上传:

$.ajax({ url: "https://mypresignedurl", method: 'PUT', // I've also tried type: 'PUT' data: "junk", })

AWS 使用 SignatureDoesNotMatch 代码拒绝此操作。错误说明:

<StringToSign>GET 1427216999 /mybucket/myfile</StringToSign>

但我没有使用 GET - 我使用的是 PUT。如果我检查 Chrome 的网络选项卡,它会正确地将请求列为 PUT。那么为什么 AWS 将浏览器 PUT 请求解释为 GET 并拒绝它们呢?

(这似乎与 CORS 无关。我已经在我的存储桶上设置了 CORS,然后使用 -H "Origin: http://elsewhere.com" 从 CURL 进行测试。我还尝试传递 "type" 而不是“方法”。我尝试过使用 POST 而不是 PUT——即使如此,AWS 仍然将 StringToSign 列为 GET。我尝试了各种 contentTypes。FWIW,我的 presignedURL 上传逻辑在 WPF 应用程序中的 .NET 上都可以正常工作。)

【问题讨论】:

    标签: jquery curl amazon-web-services amazon-s3 pre-signed-url


    【解决方案1】:

    好的,开始工作了。我现在可以使用预签名 URL 从浏览器上传。

    让我失望的是 S3 将我的 PUT 解释为 GET 的问题。但这实际上是错误的。为了找出权限问题,我查看了 Chrome 的网络选项卡。在向 S3 发出 PUT 请求之前,有一个对同一个 S3 端点的 OPTIONS 请求。我单击此以获取更多信息,那时我看到带有<StringToSign>GET ... </StringToSign>SignatureDoesNotMatch 消息 但是在浏览器中单击此链接会导致浏览器尝试从 S3 获取资源。这不是你应该用它做的。正在使用 OPTIONS 方法检索请求。如果您真的愿意,您可以使用curl -X OPTIONS ... 手动执行此操作,然后它会正确列出如何访问此 url。但是不要在浏览器中点击它,否则浏览器会尝试 GET 它,产生一条与你原来的 PUT 请求无关的废话。

    那么,为什么我一开始上传时会出错?原来我把content-type留空了。浏览器显然不喜欢这个,把它变成" , text/plain ..."。另一方面,curl 和 .net 似乎可以使用空白 content-type,因此它们的行为存在差异。当我在服务器上生成预签名 URL 和 ajax 上传时都使用相同的 content-type = "text/plain" 时,一切正常。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-03-18
      • 1970-01-01
      • 1970-01-01
      • 2022-01-28
      • 2015-09-05
      • 2017-11-26
      • 2018-10-20
      • 2018-06-30
      相关资源
      最近更新 更多