为什么在尝试通过 AWS API 网关和 Lambda 执行 DELETE 请求时会出现 CORS 内部服务器错误?

Why do I get a CORS internal server error when trying to do a DELETE request via AWS API Gateway and Lambda?

我制作了 todo 应用程序,我可以处理 GET,POST lambda 函数中的方法但是调用 delete 时出错 method.Here 我想通过从 axios 进行删除查询来删除 dynamo 数据库中的数据通过 lambda 函数

这是axios删除函数,它发送{"data": {"id":this.id}}到lambda

   axios.delete('https://94sc9th9bi.execute-api.ap-northeast-1.amazonaws.com/prod/item',
        { "data": {"id":this.id}}).then(
          res => {
            console.log(res.data.id)
          }).catch(err => {console.log(err)})

      this.getalltask()
    },

我有 lambda api 用于删除

const AWS = require('aws-sdk')
const docClient = new AWS.DynamoDB.DocumentClient()

exports.handler = async (event) => {
    console.log(event)
    let body = JSON.parse(event.body);
     const scanItemPayload = {
        TableName: 'aws-training',
        Key:{
         id: body.data.id
    }
     }
     console.log(body);

   
    const dynamoDBResponse = await docClient.delete(scanItemPayload).promise()
  console.log(dynamoDBResponse)

    const response = {
        body: JSON.stringify(dynamoDBResponse),
       statusCode: 200,
  headers: {
    "Access-Control-Allow-Origin" : "*", // Required for CORS support to work
    "Access-Control-Allow-Credentials" : true, // Required for cookies, authorization headers with HTTPS 
 
  },
    };
    return response;
};

我用

测试上面的lambda
{
    "body": "{\"data\":{\"id\":\"1633613467228\"}}"
}

我收到 statusCode 200 并且没有错误,我检查数据是否已在 dynamo db

中删除

我有一个与上面的 lambda 函数相关的删除方法 API,我通过给出查询 {item} => id=1633613467228 来测试上面的删除方法 api,这是我要删除的 id

但它给了我结果

{
  "message": "Internal server error"
}


with error log

Execution log for request f83e7e01-52ca-498d-b3e6-34d972510ad8
Fri Oct 08 15:50:00 UTC 2021 : Starting execution for request: f83e7e01-52ca-498d-b3e6-34d972510ad8
Fri Oct 08 15:50:00 UTC 2021 : HTTP Method: DELETE, Resource Path: /item
Fri Oct 08 15:50:00 UTC 2021 : Method request path: {}
Fri Oct 08 15:50:00 UTC 2021 : Method request query string: {id=1633613467228}
Fri Oct 08 15:50:00 UTC 2021 : Method request headers: {}
Fri Oct 08 15:50:00 UTC 2021 : Method request body before transformations: 
Fri Oct 08 15:50:00 UTC 2021 : Endpoint request URI: https://lambda.ap-northeast-1.amazonaws.com/2015-03-31/functions/arn:aws:lambda:ap-northeast-1:184371581740:function:aws-training-20211006-p-delete/invocations

我和邮递员一起测试

https://94sc9th9bi.execute-api.ap-northeast-1.amazonaws.com/prod/item?id=1633613467228

我收到错误消息,似乎查询 ?id=1633613467228 无效

我还测试了该应用程序,尽管我已经将访问控制原点设置为 *

,但控制台出现 CORRS/network 错误
Access to XMLHttpRequest at 'https://94sc9th9bi.execute-api.ap-northeast-1.amazonaws.com/prod/item?' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
index.vue?0f48:64 Error: Network Error
    at createError (createError.js?2d83:16)
    at XMLHttpRequest.handleError (xhr.js?b50d:117)
xhr.js?b50d:210 DELETE https://94sc9th9bi.execute-api.ap-northeast-1.amazonaws.com/prod/item? net::ERR_FAILED 502

所以我的问题是:
1.why 上面 api 中的删除方法导致内部服务器错误,我该如何测试该方法。我也对 api 网关中的测试和 lambda 函数中的测试之间的区别感到困惑。我的测试数据格式错误吗?

  1. 在我有 "data": {"id":this.id}}) 的 axios 中,是 Key:{id: body.data.id} 在 aws lambda 函数中获取 axios 发送的数据的正确方法?

这是来自 amazon cloudwatch 的错误。似乎 'data' 为空。

START RequestId: 8197a2bb-b045-438b-8b37-4467687006e3 Version: $LATEST
2021-10-09T06:28:31.894Z    8197a2bb-b045-438b-8b37-4467687006e3    INFO    { key: { id: '1633613467228' } }
2021-10-09T06:28:31.927Z    8197a2bb-b045-438b-8b37-4467687006e3    ERROR   Invoke Error    
{
    "errorType": "SyntaxError",
    "errorMessage": "Unexpected token u in JSON at position 0",
    "stack": [
        "SyntaxError: Unexpected token u in JSON at position 0",
        "    at JSON.parse (<anonymous>)",
        "    at Runtime.exports.handler (/var/task/index.js:12:21)",
        "    at Runtime.handleOnce (/var/runtime/Runtime.js:66:25)"
    ]
}

END RequestId: 8197a2bb-b045-438b-8b37-4467687006e3
REPORT RequestId: 8197a2bb-b045-438b-8b37-4467687006e3  Duration: 56.29 ms  Billed Duration: 57 ms  Memory Size: 128 MB Max Memory Used: 72 MB  Init Duration: 399.98 ms    
START RequestId: ff096041-a1fb-4349-abbc-a5d422e034d6 Version: $LATEST
2021-10-09T06:29:04.648Z    ff096041-a1fb-4349-abbc-a5d422e034d6    INFO    {
  resource: '/item',
  path: '/item',
  httpMethod: 'DELETE',
  headers: null,
  multiValueHeaders: null,
  queryStringParameters: { id: '1633613467228' },
  multiValueQueryStringParameters: { id: [ '1633613467228' ] },
  pathParameters: null,
  stageVariables: null,
  requestContext: {
    resourceId: '2gw7om',
    resourcePath: '/item',
    httpMethod: 'DELETE',
    extendedRequestId: 'G7V7mFskNjMF-vg=',
    requestTime: '09/Oct/2021:06:29:04 +0000',
    path: '/item',
    accountId: '184371581740',
    protocol: 'HTTP/1.1',
    stage: 'test-invoke-stage',
    domainPrefix: 'testPrefix',
    requestTimeEpoch: 1633760944483,
    requestId: 'f7596258-871a-4b15-b62c-11d434e176b4',
    identity: {
      cognitoIdentityPoolId: null,
      cognitoIdentityId: null,
      apiKey: 'test-invoke-api-key',
      principalOrgId: null,
      cognitoAuthenticationType: null,
      userArn: 'arn:aws:iam::184371581740:user/user07',
      apiKeyId: 'test-invoke-api-key-id',
      userAgent: 'aws-internal/3 aws-sdk-java/1.12.71 Linux/5.4.134-73.228.amzn2int.x86_64 OpenJDK_64-Bit_Server_VM/25.302-b08 java/1.8.0_302 vendor/Oracle_Corporation cfg/retry-mode/standard',
      accountId: '184371581740',
      caller: 'AIDASV3LHCMWIZKMZMLPE',
      sourceIp: 'test-invoke-source-ip',
      accessKey: 'ASIASV3LHCMWBJROEHQN',
      cognitoAuthenticationProvider: null,
      user: 'AIDASV3LHCMWIZKMZMLPE'
    },
    domainName: 'testPrefix.testDomainName',
    apiId: '94sc9th9bi'
  },
  body: null,
  isBase64Encoded: false
}
2021-10-09T06:29:04.667Z    ff096041-a1fb-4349-abbc-a5d422e034d6    ERROR   Invoke Error    
{
    "errorType": "TypeError",
    "errorMessage": "Cannot read property 'data' of null",
    "stack": [
        "TypeError: Cannot read property 'data' of null",
        "    at Runtime.exports.handler (/var/task/index.js:16:19)",
        "    at Runtime.handleOnce (/var/runtime/Runtime.js:66:25)"
    ]
}

END RequestId: ff096041-a1fb-4349-abbc-a5d422e034d6
REPORT RequestId: ff096041-a1fb-4349-abbc-a5d422e034d6  Duration: 180.66 ms Billed Duration: 181 ms Memory Size: 128 MB Max Memory Used: 73 MB  
START RequestId: 1adde91a-ce53-4d2f-8fa8-d296352fc689 Version: $LATEST
2021-10-09T06:30:01.788Z    1adde91a-ce53-4d2f-8fa8-d296352fc689    INFO    { key: { id: '1633613467228' } }
2021-10-09T06:30:01.807Z    1adde91a-ce53-4d2f-8fa8-d296352fc689    ERROR   Invoke Error    
{
    "errorType": "SyntaxError",
    "errorMessage": "Unexpected token u in JSON at position 0",
    "stack": [
        "SyntaxError: Unexpected token u in JSON at position 0",
        "    at JSON.parse (<anonymous>)",
        "    at Runtime.exports.handler (/var/task/index.js:12:21)",
        "    at Runtime.handleOnce (/var/runtime/Runtime.js:66:25)"
    ]
}

intecept axios to see data

我用 body 测试 lambda 函数并得到 200
test lambda with body

enter image description here

我测试 api 网关通过添加查询删除它给出了内部服务器错误
enter image description here

我试图在这里使用 axios 发出请求,我想删除名称为 'aa' id = 1633601975370
的任务 delete task name="aa"

可以看到,发送了id为body,但是axios请求删除时出现错误api

控制台出现错误
error in console

amaxon cloudwatch 日志错误
enter image description here

cloudwatch log error

I got a CORS error the in console even though I've already set Access-Control-Allow-Origin to *

问题是:

您是否尝试为 Lambda proxy 集成或 Lambda non-proxy 集成启用 CORS ?

启用 CORS 将根据集成类型不同


首先,请参阅亚马逊 API 网关开发人员指南的 Enable CORS on a resource using the API Gateway console 部分,因为它包括图像等。

遵循代理指南 & non-proxy。

如果它是 non-proxy 集成,你就完成了。


如果它是代理集成(我认为不是),您的请求仍然会失败 - DELETE 请求被归类为 CORS 规范的复杂请求

这意味着如果您正在使用网络应用程序调用此端点,您可能已经允许所有 来源 但您没有指定哪个 HTTP methods 允许(Web 应用程序将在 DELETE 请求之前以 preflight 请求的形式请求)。

因此您还需要将 Access-Control-Allow-Methods header 设置为 * 以允许 HTTP DELETE 在您的 Lambda 返回的响应中:

const response = {
    body: JSON.stringify(dynamoDBResponse),
    statusCode: 200,
    headers: {
        "Access-Control-Allow-Origin": "*",
        "Access-Control-Allow-Methods": "*",
        "Access-Control-Allow-Credentials": true
    }
};