S3 PUT 不适用于 JavaScript 中的预签名 URL

2024-01-27

我已经在 java 中为 HTTP PUT 方法生成了一个预签名的 S3 URL。

URL 的稍微修改版本:

https://s3.amazonaws.com/somebucket/pre-signed-url-key-2?AWSAccessKeyId=BKIAIQ6H5Z7BG6KZ2ZUA&Expires=1425617244&Signature=GWcRM5ZIrAKnMJBsxyfm%2F9fyuBk%3D

我知道这是一个有效的预签名网址,因为我可以将它与curl上传文件

curl -v --upload-file somefile.txt "https://s3.amazonaws.com/somebucket/pre-signed-url-key-2?AWSAccessKeyId=BKIAIQ6H5Z7BG6KZ2ZUA&Expires=1425617244&Signature=GWcRM5ZIrAKnMJBsxyfm%2F9fyuBk%3D"

当我尝试使用以下 Javascript 将文件上传到同一 URL 时:

function ajaxUsingPresignedUrlPut() {
            $.ajax({
                url: presignedURLPUT,
                type: 'PUT',
                data: 'blah blah blah',
                success: function () {
                    console.log('Uploaded data successfully.');
                }
            }).done(function (data) {
                console.log("DONE : " + data);
            }).fail(function (e, r) {
                console.log("FAIL");
            });
        }

我收到 403 状态和响应文本

<?xml version="1.0" encoding="UTF-8"?>
<Error><Code>SignatureDoesNotMatch</Code><Message>The request signature we calculated does not match the signature you provided. Check your key and signing method.</Message><AWSAccessKeyId>BKIAIQ6H5Z7BG6KZ2ZUA</AWSAccessKeyId><StringToSign>PUT

application/x-www-form-urlencoded; charset=UTF-8
1425617244
/somebucket/pre-signed-url-key-2</StringToSign><SignatureProvided>GWcRM5ZIrAKnMJAsxyfm/9fyuAk=</SignatureProvided><StringToSignBytes>50 55 54 0a 0a 61 70 70 6c 69 63 61 74 69 6f 6e 2f 78 2d 77 77 77 2d 66 6f 72 6d 2d 75 72 6c 65 6e 63 6f 64 65 64 3b 20 63 68 61 72 73 65 74 3d 55 54 46 2d 38 0a 31 34 32 35 36 31 37 32 34 34 0a 2f 6e 6b 6f 6e 64 72 61 74 5f 62 75 63 6b 65 74 2f 70 72 65 2d 73 69 67 6e 65 64 2d 75 72 6c 2d 6b 65 79 2d 32</StringToSignBytes><RequestId>3C8298CAC404C6F5</RequestId><HostId>uCkzA//CdCLi4SINifkIe0WH6GOlCJBgFlN8ghx8NnULEe+QVslsdoUsJc4AUdA8</HostId></Error>

我在 S3 存储桶上配置了以下 CORS 策略:

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
    <CORSRule>
        <AllowedOrigin>*</AllowedOrigin>
        <AllowedMethod>HEAD</AllowedMethod>
        <AllowedMethod>GET</AllowedMethod>
        <AllowedMethod>PUT</AllowedMethod>
        <AllowedMethod>POST</AllowedMethod>
        <AllowedMethod>DELETE</AllowedMethod>
        <MaxAgeSeconds>3000</MaxAgeSeconds>
        <ExposeHeader>ETag</ExposeHeader>
        <ExposeHeader>Content-Length</ExposeHeader>
        <ExposeHeader>Content-Type</ExposeHeader>
        <ExposeHeader>Connection</ExposeHeader>
        <ExposeHeader>Date</ExposeHeader>
        <ExposeHeader>Server</ExposeHeader>
        <ExposeHeader>x-amz-delete-marker</ExposeHeader>
        <ExposeHeader>x-amz-id-2</ExposeHeader>
        <ExposeHeader>x-amz-request-id</ExposeHeader>
        <ExposeHeader>x-amz-version-id</ExposeHeader>
        <AllowedHeader>*</AllowedHeader>
    </CORSRule>
</CORSConfiguration>

相同的 JavaScript 代码适用于预签名的 GET URL:https://s3.amazonaws.com/somebucket/pre-signed-url-key-2?AWSAccessKeyId=BKIBIQ6H5Z7LG6KZ2ZUB&Expires=1425616588&Signature=qMPpuzMwxonYPDQETdLafEQGqMU%3D

function ajaxUsingPresignedUrlGET() {
            $.ajax({
                url: presignedURLGET,
                type: 'GET',
                success: function () {
                    console.log('Uploaded data successfully.');
                }
            }).done(function (data) {
                console.log("DONE : " + data);
            }).fail(function (e, r) {
                console.log("FAIL");
            });
        }

我现在查看 URL 的唯一猜测是 PUT url 包含%2F并看着http://www.w3schools.com/tags/ref_urlencode.asp http://www.w3schools.com/tags/ref_urlencode.asp这代表/这可能会导致浏览器出现问题?或者也许我完全不在这儿,并且我还缺少其他一些问题。


编辑 #1 添加用于生成预签名 URL 的 java 代码

public S3GeneratePresignedUrlDemo(HttpMethod httpMethod) {
    this.httpMethod = httpMethod;
    System.out.println("HTTP METHOD : " + this.httpMethod);
}

@Override
public void goImpl() throws Exception {        
    GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(bucketName, KEY);

    request.setMethod(httpMethod);

    request.setExpiration(createDateNHoursFromNow(24));

    URL url = s3Client.generatePresignedUrl(request);

    System.out.println(url);
}

private static Date createDateNHoursFromNow(int hours){
    Date date = new Date();
    long millis = date.getTime();
    final int millisInSecond = 1000;
    final int secondsInMinute = 60;
    final int minutesInHour = 60;
    millis += millisInSecond * secondsInMinute * minutesInHour * hours;

    date.setTime(millis);
    return date;
}`

Adding

headers: {'Content-Type': 'text/plain;charset=UTF-8'},

To AJAX

function ajaxUsingPresignedUrlPut() {
            $.ajax({
                url: presignedURLPUT,
                type: 'PUT',
                data: 'blah blah blah',
                headers: {'Content-Type': 'text/plain;charset=UTF-8'},
                success: function () {
                    console.log('Uploaded data successfully.');
                }
            }).done(function (data) {
                console.log("DONE : " + data);
            }).fail(function (arg1, arg2) {
                console.log("FAIL");        
            });
        }

生成 URL 时设置内容类型解决了该问题

    GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(bucketName, KEY);        
    request.setContentType("text/plain;charset=UTF-8");
    //...
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

S3 PUT 不适用于 JavaScript 中的预签名 URL 的相关文章

随机推荐

  • 基于 NSFetchedResultsController 的表视图在第二次插入实体时总是失败

    我正在使用 NSFetchedResultsController 来管理在具有一个部分的表视图中显示获取的托管对象 该表一开始是空的 用户可以使用 UI 向其中添加新实体 就目前情况而言 程序在添加第一个实体时始终有效 而在添加第二个实体时
  • C# 中的心电图数字信号处理

    我正在寻找用于数字滤波 低通 高通 陷波 的 C NET 库 以实时过滤心电图波形 有什么建议么 如果这是非商业用途 我听说过关于信号实验室库 http www mitov com html signallab html 非商业用途免费 商
  • MDX - TopCount 加“其他”或“其余”

    我创建了一个 MDX 查询 用于计算前 10 个邮政编码 根据我的患者住院测量 如下所示 WITH MEMBER Discharge Date Y M D Aggregation AS AGGREGATE EXISTING Current
  • 如何在 Github Actions 中查看已取消步骤的日志?

    我的工作流程中有一个步骤是运行命令 python 脚本 这个 python 脚本似乎挂在执行过程中的某个地方 GitHub 显示该步骤在运行时被卡住并且没有任何反应 为了调试这个 我想查看 python 脚本的日志输出 我怎样才能做到这一点
  • PHP 中的测试驱动开发

    我是一名使用 PHP 工作的 Web 开发人员 我在 C 桌面应用程序中使用测试驱动开发的经验有限 在这种情况下 我们使用 nUnit 作为单元测试框架 我想在新项目中开始使用 TDD 但我真的不知道从哪里开始 对于基于 PHP 的单元测试
  • 通知在 flutter 上显示两次

    我被困住了 我的后台通知显示两次 但前台只有一个通知 这是我的代码 Future
  • 谷歌数据存储中的节点分页

    我在使用 Google Datastore 进行分页时遇到问题 我有一个查询 没有限制 有几百个结果 我想检索 5 个 将它们发送回用户 如果用户想要更多 他们会检索下 5 个 根据文档 我创建了查询 var query datastore
  • div 相对于窗口的位置?

    尝试找到 div 相对于窗口的位置 我有一个水平 div 我想获取相对于窗口的左侧值 因此 如果我将第二个 div 滚动到窗口左侧 它将显示 0 不确定如果没有父 div 这是否可行 这是我的小提琴 http jsfiddle net FS
  • 如何在 Symfony2 配置中添加带有值的数组?

    我想在配置文件 config yml 中添加一个简单的值列表 例如 my bundle columns col1 col2 将节点添加到配置解析器时 它只是失败 rootNode treeBuilder gt root my bundle
  • NHibernate 测试,模拟 ISession

    我正在使用 NHibernate 和 Rhinomocks 但在测试我想要的东西时遇到了困难 我想在不访问数据库的情况下测试以下存储库方法 其中 session 作为 ISession 注入存储库 public class Reposito
  • SQL语句只删除一行重复项

    所以我正在使用 Ruby 工作 并假设我的两列表中有 6 行完全相同 就我而言 我的表 campaign items 有两列 campaign name 和 item 我想使用单个查询仅删除 6 个重复项中的一行 我是这样开始的 db ex
  • Flex 页脚在 Chrome 中不会停留在底部

    仅当内容短于视口时 我才使用 Flexbox 让页脚保持在底部 如果它较高 页脚应保持在内容下方 以便您必须滚动才能看到它 这在 Firefox 和 Edge 中可以正常工作 但在 Chrome 或 IE 中则不行 在 Chrome 中 正
  • WCF - 自定义凭据和安全令牌

    我对 WCF 开发相当陌生 在学习该框架时遇到了一些问题 我有一个必须支持 REST 和 SOAP 的服务 API 到目前为止 这很容易实现 尤其是使用 WCF4 和路由 我目前正在研究授权 并通过创建两个新的管理器类来扩展 Authori
  • 如何在Apache中设置mod_lua来访问第三方Lua模块?

    我正在尝试为 Apache 设置 mod lua 模块 但在访问第三方 Lua 模块时遇到了困难 假设我在 Apache 的 htdocs 文件夹中有一个 hello world lua 其中包含以下内容 require apache2 f
  • 尽管已传输,但仍出现错误“无法传输文件 *.jar,状态代码为 409”

    我正在尝试将项目发布到azure artefacts 项目pom是这样的
  • Django 使用 selenium 进行测试,未加载固定装置

    我正在使用 Selenium 为 Django 网站设置功能测试 我有一个固定文件 users fixtures users json 并在另一个应用程序的功能测试中使用它 accounts 运行测试时 我还运行我的开发服务器来接受来自 S
  • 为什么 std::visit 必须有单一返回类型?

    玩耍的同时std variant and std visit出现了以下问题 考虑以下代码 using Variant std variant
  • m2eclipse过滤测试资源

    我正在使用 m2eclipse 我想右键单击并从 eclipse 内部运行测试 同时从 Maven 过滤测试资源 我怎样才能做到这一点 从 Eclipse 中 当我右键单击测试时 我没有得到任何 m2eclipse 选项 Julia 如同
  • LinqPad 在每个表的末尾添加一个 S

    我刚刚下载了 LinqPad 以探索在我正在开发的应用程序中使用 Linq 查询的好处 但是当我查看左侧列中的数据库表时 LinqPad 显示我的所有表 末尾带有 s 例如实例 CategoryTbl 变为 CategoryTbls 但是当
  • S3 PUT 不适用于 JavaScript 中的预签名 URL

    我已经在 java 中为 HTTP PUT 方法生成了一个预签名的 S3 URL URL 的稍微修改版本 https s3 amazonaws com somebucket pre signed url key 2 AWSAccessKey