为什么在尝试通过 AWS API Gateway 和 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?

查看:37
本文介绍了为什么在尝试通过 AWS API Gateway 和 Lambda 执行 DELETE 请求时会收到 CORS 内部服务器错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I made todo application, i could process GET,POST method in lambda function but i got error when invoke delete method.Here i want to delete data in dynamo db by making delete query from axios through lambda function

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

This is axios delete function,it send {"data": {"id":this.id}} to 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

I have lambda api for delete

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;
};

我用

{
    "body": "{\"data\":{\"id\":\"1633613467228\"}}"
}

我得到 statusCode 200 并且没有错误,我检查数据是否在 dynamo db 中被删除

and i got statusCode 200 and no error and i check that the data is deleted in dynamo db

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

i have a DELETE method API that is related to the lambda function above, and i test delete method api above by giving query {item} => id=1633613467228 , this is the id i want to delete

但它给了我结果

{
  "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 似乎不起作用

i got error, it seem that the query ?id=1633613467228 is not work

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

i also test the application , i got CORRS/network error in console although i already set access control orign to *

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.为什么上面api中的delete方法会导致内部服务器错误,我该如何测试该方法.我也对 api 网关中的测试和 lambda 函数中的测试之间的不同感到困惑.我的测试数据格式错误吗?

so my questions are:
1.why delete method in api above result in internal server error and how can i test the method. i also got confused of the different between test in api gateway and test in lambda function. Is my test data wrong format?

  1. 在 axios 我有 "data": {"id":this.id}}) ,是Key:{id: body.data.id} aws lambda 函数中获取 axios 发送的数据的正确方法?
  1. in axios i have "data": {"id":this.id}}) , is Key:{id: body.data.id} right way to get the data send by axios in aws lambda function?

这是亚马逊云观察的错误.似乎数据"为空.

this is the eror from amazon cloudwatch. it seems 'data' is null.

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 查看数据

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

i test lambda function with body and got 200
test lambda with body

在此处输入图片说明

我通过添加删除查询来测试 api 网关,它给出了内部服务器错误
在此处输入图片描述

i test api gateway by add query for delete it gave internal server error
enter image description here

我在这里尝试使用 axios 发出请求,我想删除名称为aa"且 id = 1633601975370 的任务
删除任务名称=aa"

i tried to make request by using axios here, i want to delete task which name is 'aa' with id = 1633601975370
delete task name="aa"

如您所见,发送了带有id的body,但是axios请求删除api时出现错误

as you can see, body with id is sent, but there is error when axios request delete api

我在控制台出错
控制台错误

amaxon cloudwatch 日志错误
在此处输入图片描述

amaxon cloudwatch log error
enter image description here

cloudwatch 日志错误

推荐答案

尽管我已经将 Access-Control-Allow-Origin 设置为 *

问题是:

您是尝试为 Lambda 代理 集成还是 Lambda 非代理 集成启用 CORS?

Are you trying to enable CORS for a Lambda proxy integration or a Lambda non-proxy integration?

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

Enabling CORS will differ based on the integration type.

首先参考使用 Amazon API Gateway 开发人员指南的 API Gateway 控制台 部分对资源启用 CORS,因为它包括图像等.

First, refer to the Enable CORS on a resource using the API Gateway console section of the Amazon API Gateway developer guide as it includes images etc.

遵循代理指南非代理.

如果是非代理集成,您就完成了.

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

If it's a proxy integration (which I don't think it is), your request will still fail - a DELETE request is classed as a complex request by the CORS specification.

这意味着,如果您使用 Web 应用程序调用此端点,您可能已允许所有来源,但您尚未指定要使用哪些 HTTP 方法允许(网络应用程序将在 DELETE 请求之前以 preflight 请求的形式请求).

This means that if you are making a call to this endpoint using a web app, you may have allowed all origins but you haven't specified which HTTP methods to allow (which the web app will request for in the form of a preflight request before the DELETE request).

所以你还需要设置 Access-Control-Allow-Methods 标头到 * 以允许在您的 Lambda 返回的响应中使用 HTTP DELETE:

So you'll need to also set the Access-Control-Allow-Methods header to * to allow HTTP DELETEin the response returned by your Lambda:

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

这篇关于为什么在尝试通过 AWS API Gateway 和 Lambda 执行 DELETE 请求时会收到 CORS 内部服务器错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆