【问题标题】:S3 Object Lambda WriteGetObjectResponse API returns 405 Method Not AllowedS3 对象 Lambda WriteGetObjectResponse API 返回 405 Method Not Allowed
【发布时间】:2021-06-20 08:51:52
【问题描述】:

代码使用 AWS SDK for JavaScript 版本 2.868.0 在 AWS Lambda Node.js 14 运行时上运行。

这里是sn-p的代码:

const AWS = require('aws-sdk');
const s3 = new AWS.S3();

exports.handler = async (event) => {
    const objectContent = event['getObjectContext'];
    const data = await s3.writeGetObjectResponse({
        Body: 'test',
        RequestRoute: objectContent['outputRoute'],
        RequestToken: objectContent['outputToken']
    }).promise();
    console.log(data);
    const response = {
        statusCode: 200
    };
    return response;
};

我已将以下 IAM 策略附加到 Lambda 角色:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowObjectLambdaAccess",
            "Action": [
                "s3-object-lambda:WriteGetObjectResponse"
            ],
            "Effect": "Allow",
            "Resource": "*"
        }
    ]
}

函数在await s3.writeGetObjectResponse(...).promise()这一行抛出如下错误:

2021-03-22T01:59:29.951Z    eb99f9a6-75c7-40ec-9f85-e19da084c42c    ERROR   Invoke Error    {
    "errorType": "MethodNotAllowed",
    "errorMessage": "The specified method is not allowed against this resource.",
    "code": "MethodNotAllowed",
    "message": "The specified method is not allowed against this resource.",
    "region": null,
    "time": "2021-03-22T01:59:29.891Z",
    "requestId": "C0FKZ5WSK027GPQW",
    "extendedRequestId": "+9rRhWJUPgIAmFupxXKrkAIWe5dXbi0vAacoN+/NlCQPgKzyZi0+mpevGMIVDDPo/1EYpo8Ntyk=",
    "statusCode": 405,
    "retryable": false,
    "retryDelay": 15.885104429810148,
    "stack": [
        "MethodNotAllowed: The specified method is not allowed against this resource.",
        "    at Request.extractError (/opt/nodejs/node_modules/aws-sdk/lib/services/s3.js:712:35)",
        "    at Request.callListeners (/opt/nodejs/node_modules/aws-sdk/lib/sequential_executor.js:106:20)",
        "    at Request.emit (/opt/nodejs/node_modules/aws-sdk/lib/sequential_executor.js:78:10)",
        "    at Request.emit (/opt/nodejs/node_modules/aws-sdk/lib/request.js:688:14)",
        "    at Request.transition (/opt/nodejs/node_modules/aws-sdk/lib/request.js:22:10)",
        "    at AcceptorStateMachine.runTo (/opt/nodejs/node_modules/aws-sdk/lib/state_machine.js:14:12)",
        "    at /opt/nodejs/node_modules/aws-sdk/lib/state_machine.js:26:10",
        "    at Request.<anonymous> (/opt/nodejs/node_modules/aws-sdk/lib/request.js:38:9)",
        "    at Request.<anonymous> (/opt/nodejs/node_modules/aws-sdk/lib/request.js:690:12)",
        "    at Request.callListeners (/opt/nodejs/node_modules/aws-sdk/lib/sequential_executor.js:116:18)"
    ]
}

提前致谢。

【问题讨论】:

    标签: amazon-web-services amazon-s3 aws-lambda aws-sdk-js


    【解决方案1】:

    我在 AWS SDK Github https://github.com/aws/aws-sdk-js/issues/3675 上打开了一个错误问题,因为它似乎是一个 SDK 问题

    【讨论】:

      【解决方案2】:

      更新:该问题已在 2.876.0 中修复。请更新到最新版本以避免任何解决方法的需要。


      我听说 SDK 团队正在解决这个问题。该问题与端点有关。如果您控制台记录s3.WriteGetObjectResponse(...) 的结果,您实际上可以看到使用了哪个端点。

      现在您可以使用此解决方法:

      //Construct the client with an endpoint override so the request lands in the right place
      const client = new AWS.S3({ region: "us-east-1", endpoint: "s3-object-lambda.us-east-1.amazonaws.com"});
      
      // Override the signing service name from s3 to s3-object-lambda so the signatures are valid.
      client.__proto__.api.endpointPrefix = "s3-object-lambda";
      const data = await client.writeGetObjectResponse({
          Body: 'test',
          RequestRoute: objectContent['outputRoute'],
          RequestToken: objectContent['outputToken']
      }).promise();
      

      我在试验该功能时遇到了完全相同的问题,解决方法对我来说效果很好。

      如果觉得有用我结合了一篇基于学习的文章,可以作为a small tutorial to S3 Object Lambda

      【讨论】:

      • 嗨,你知道这相当于打字稿吗?我不能在我的打字稿代码中使用__proto__
      • Petra,该问题已得到修复(在 2.876.0 版中 - github.com/aws/aws-sdk-js/blob/master/.changes/2.876.0.json)。使用新版本,您将不需要解决方法:)
      • 知道了!非常感谢@anelook!
      【解决方案3】:

      有一种解决方法可以临时修复此问题,直到错误未解决

      /** START Workaround for bug #3675 **/
      const s3 = new AWS.S3({ region: "us-east-1", endpoint: "s3-object-lambda.us-east-1.amazonaws.com" });
      s3.__proto__.api.endpointPrefix = "s3-object-lambda";
      /** END Workaround for bug #3675 **/
      

      如果有帮助的话,我已经在我的medium blog 中记录了用法

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-09-25
        • 1970-01-01
        • 2015-07-01
        • 2022-01-19
        • 2021-06-14
        • 2016-12-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多