Amazon web services 触发API网关终结点时CORs配置错误

Amazon web services 触发API网关终结点时CORs配置错误,amazon-web-services,amazon-s3,cors,aws-api-gateway,Amazon Web Services,Amazon S3,Cors,Aws Api Gateway,我正在尝试使用AJAX从我的网站触发AWSAPI网关上的API。我的API网关触发一个Lambda。我已经在S3上托管了我的网站 我的AJAX代码如下所示: $.ajax({ type: "POST", url: api-gateway-api-endpoint-goes-here, data: str, dataType: 'json', contentType: 'application/json', crossDomain: true, headers: {

我正在尝试使用AJAX从我的网站触发AWSAPI网关上的API。我的API网关触发一个Lambda。我已经在S3上托管了我的网站

我的AJAX代码如下所示:

$.ajax({
  type: "POST",
  url: api-gateway-api-endpoint-goes-here,
  data: str,
  dataType: 'json',
  contentType: 'application/json',
  crossDomain: true,
  headers: {
    'Access-Control-Allow-Origin': "*",
    'Access-Control-Allow-Credentials': 'true',
    'Access-Control-Allow-Methods': 'OPTIONS,POST',
    'Access-Control-Allow-Headers': 'access-control-allow-origin'
  },
  success: function(msg) {
      // blah blah
  }
});
def lambda_handler(event, context):
    # call SES send-email API
    aws_ses_response = ses_client.send_email(
        Source=blah,
        Destination=blah,
        Message=blah
    )

    return {
        'response': aws_ses_response
    }
lambda处理程序看起来有点像这样:

$.ajax({
  type: "POST",
  url: api-gateway-api-endpoint-goes-here,
  data: str,
  dataType: 'json',
  contentType: 'application/json',
  crossDomain: true,
  headers: {
    'Access-Control-Allow-Origin': "*",
    'Access-Control-Allow-Credentials': 'true',
    'Access-Control-Allow-Methods': 'OPTIONS,POST',
    'Access-Control-Allow-Headers': 'access-control-allow-origin'
  },
  success: function(msg) {
      // blah blah
  }
});
def lambda_handler(event, context):
    # call SES send-email API
    aws_ses_response = ses_client.send_email(
        Source=blah,
        Destination=blah,
        Message=blah
    )

    return {
        'response': aws_ses_response
    }
我已经在API网关的API端点上“启用”了CORS。我添加了
access control allow origin
作为
Integration Response
access control allow Headers
映射中的一个值

当触发此AJAX调用时,我仍然看到此错误:

访问位于的XMLHttpRequest'https://xxxxxxx.execute-api.xxxxx.amazonaws.com/dev/my-api“起源”http://www.my-website.com'已被CORS策略阻止:飞行前响应中的访问控制允许标头不允许请求标头字段访问控制允许来源。

当我从终端从cURL触发API时,它工作正常

我错过了什么?谢谢

另外,我在这里看了一些类似的问题,但没有一个建议奏效。所以,再次在这里发布

--

更新:在遵循@hephalump的建议后,我能够触发我的API,只是API响应似乎没有传播回网站(托管在S3上)。我在发送AJAX POST请求后“检查”我的网站时看到此错误:


当使用启用API网关和CORS的Lambda代理集成时,您的浏览器将期望在响应中返回CORS头。当前,您正在返回ses_client.send_电子邮件的结果,如果它只是原始的ses sendmail原始响应,将类似于:

{
    "ResponseMetadata": {
      "RequestId": "99aaaaa9-a9aa-9999-aa99-744d6b6ede3c"
    },
    "MessageId": "0100000aa0a00a0a-715e3e9e-e010-43c1-a91f-0492d75aa64c-000000"
  }
正如我们所看到的,这不包括CORS头,这是您的浏览器所必需的。要解决这个问题,首先构建
aws_seu response
的结果,以包含HTTP状态代码和相应的头,然后将完整的响应返回给调用方。按如下方式修改代码,它应该可以工作:

    aws_ses_response = ses_client.send_email(
        Source=blah,
        Destination=blah,
        Message=blah
    )

    const result = {
        statusCode: 200,
        headers: {
            'Access-Control-Allow-Origin': '*',
            // other required headers
        },
        body: aws_ses_response
    };

    return result;

此外,尽管我并不完全清楚API网关的配置,但是对于您的请求,您可以删除头和跨域属性(可能还有其他属性)。在一个新的APIG端点上进行测试时,我只是向API发出了一个请求,但没有这些请求,并且能够得到一个成功的响应(我的响应主体就是我给出的原始SES sendEmail响应的示例)。

当使用启用API网关和CORS的Lambda代理集成时,您的浏览器期望在响应中返回CORS头。当前,您正在返回ses_client.send_电子邮件的结果,如果它只是原始的ses sendmail原始响应,将类似于:

{
    "ResponseMetadata": {
      "RequestId": "99aaaaa9-a9aa-9999-aa99-744d6b6ede3c"
    },
    "MessageId": "0100000aa0a00a0a-715e3e9e-e010-43c1-a91f-0492d75aa64c-000000"
  }
正如我们所看到的,这不包括CORS头,这是您的浏览器所必需的。要解决这个问题,首先构建
aws_seu response
的结果,以包含HTTP状态代码和相应的头,然后将完整的响应返回给调用方。按如下方式修改代码,它应该可以工作:

    aws_ses_response = ses_client.send_email(
        Source=blah,
        Destination=blah,
        Message=blah
    )

    const result = {
        statusCode: 200,
        headers: {
            'Access-Control-Allow-Origin': '*',
            // other required headers
        },
        body: aws_ses_response
    };

    return result;

此外,尽管我并不完全清楚API网关的配置,但是对于您的请求,您可以删除头和跨域属性(可能还有其他属性)。在一个新的APIG端点上进行测试时,我只是向API发出了一个请求,但没有这些请求,并且能够得到一个成功的响应(我的响应主体就是我给出的原始SES sendEmail响应的示例)。

查看错误消息:

不允许请求标头字段访问控制允许来源

现在看看你的要求:

您正在尝试对您的请求设置权限

如果你的JavaScript允许自己访问任何它喜欢的服务,那就太愚蠢了。这意味着这些标题是胡说八道

因为它们是无意义的,所以它们不在跨源请求的可接受头列表中,所以服务器需要显式地授予您设置它们的权限……但事实并非如此

不要试图设置它们

访问控制-*
头需要由服务器设置


请查看其中明确说明的内容。

查看错误消息:

不允许请求标头字段访问控制允许来源

现在看看你的要求:

您正在尝试对您的请求设置权限

如果你的JavaScript允许自己访问任何它喜欢的服务,那就太愚蠢了。这意味着这些标题是胡说八道

因为它们是无意义的,所以它们不在跨源请求的可接受头列表中,所以服务器需要显式地授予您设置它们的权限……但事实并非如此

不要试图设置它们

访问控制-*
头需要由服务器设置


查看哪个明确说明了这一点。

您的API是否触发了Lambda?@hephalump-是扫描您发布的Lambda代码?@hephalump-我刚刚用Lambda代码更新了我的问题。基本上,我调用了AWS SES api,并从我的lambda返回了该api的响应。昨晚我用明显相同的问题回答了实际上相同的问题,OP似乎已经删除了它。我会再写一次回复。你的API是否触发了Lambda?@hephalump-yesCan你发布了Lambda代码吗?@hephalump-我刚刚用Lambda代码更新了我的问题。基本上,我调用了AWS SES api,并从我的lambda返回了该api的响应。昨晚我用明显相同的问题回答了实际上相同的问题,OP似乎已经删除了它。我会再写一次回复。现在我可以调用lambda函数,也可以发送电子邮件了。(是的!)。然而,我无法得到回复我的网站(这是托管在S3上)。我在响应中看到了这个错误:在“MY-APIG-ENDP”访问XMLHttpRequest