【问题标题】:Call to API Gateway returning CORS error despite headers being set尽管设置了标头,但调用 API 网关返回 CORS 错误
【发布时间】:2020-11-07 14:59:18
【问题描述】:

我有一个与 Lambda 函数集成的 API 网关(HTTP 类型)。我正在尝试从 localhost 调用该函数,如下所示:

const jwt = getAuthToken();
const formBody = new FormData();
formBody.set('user', 'test');

const res = await fetch('https://example.execute-api.eu-west-1.amazonaws.com/default/GetShareValue', {
method: 'POST',
body: formBody,
headers: {
   'Authorization': jwt
   }
});

但是,我收到以下错误消息:

访问获取地址 'https://example.execute-api.eu-west-1.amazonaws.com/default/GetShareValue' 来自原点“http://localhost:3000”已被 CORS 策略阻止: 对预检请求的响应未通过访问控制检查:否 请求中存在“Access-Control-Allow-Origin”标头 资源。如果不透明的响应满足您的需求,请设置请求的 模式为“no-cors”以获取禁用 CORS 的资源。

我了解不正确的 CORS 设置会阻止浏览器显示 Lambda 函数返回的内容。但是,我的 API Gateway 指定了 CORS 设置:

According to this thread,在 Lambda 函数的响应中设置标头很重要。我已将它们设置为相同。这是我的 Lambda 函数:

exports.handler = async (event, context) => {
    let body;
    let statusCode = '200';
    const headers = {
        'Content-Type': 'application/json',
        "Access-Control-Allow-Headers": "Content-Type,X-Amz-Date,X-Amz-Security-Token,Authorization,X-Api-Key,X-Requested-With,Accept,Access-Control-Allow-Methods,Access-Control-Allow-Origin,Access-Control-Allow-Headers",
        "Access-Control-Allow-Origin": "*",
        "Access-Control-Allow-Methods": "*",
        "X-Requested-With": "*"
    };

try {
    body = "Success!!";
} catch (err) {
    statusCode = '400';
    body = err.message;
} finally {
    body = JSON.stringify(body);
}

return {
    statusCode,
    body,
    headers,
};

};

我可以在 Postman 中调用这个端点——它不关心 CORS——所以我知道它正在工作。我开始认为这是 AWS 本身的一个错误。

【问题讨论】:

  • 您是否尝试过重新部署 API?
  • 是的,我创建了另一个相同的 API,它也有同样的问题。
  • 好吧,我最终将 API 网关重新创建为 REST API 而不是 HTTP API。即便如此,我在 AWS 文档中深埋的解决方案也遇到了 CORS 问题。从用户体验的角度来看,这是一个糟糕的平台。相比之下,Azure 轻而易举。
  • 您介意分享解决方案吗?我同意 CORS 对 API Gateway 来说是一个古怪的过程。
  • 嗨,彼得。我将发布我的解决方案作为这个问题的答案。

标签: amazon-web-services aws-lambda cors aws-api-gateway


【解决方案1】:

为了@peter n 的利益回答我自己的问题。

最后我放弃了 HTTP API 网关。我相信 AWS 中存在一个错误,因为当我通过 REST API 触发它时,完全相同的 Lambda 函数起作用了。这就是我所做的。

  1. 创建新的 API 网关
  2. 选择 API 网关的类型为 REST API。我之前选择了 HTTP。 REST API 给了我们更多的控制权; HTTP API 很简单(而且便宜 70%)
  3. 在“资源”页面上,单击“操作”>“创建资源”
  4. 创建资源;如果您看到任何提到 CORS 的复选框,请检查它。我不记得这是否发生在这个阶段。
  5. 然后点击操作 > 创建方法
  6. 选择“任何”以外的任何方法(如 POST、GET 等)。这很重要 - 如果您选择“任何”,CORS 会出现更多问题。为什么?谁知道呢,AWS 是一个用户不友好的平台。
  7. 一旦您配置了该方法并让它在您的 Lambda 函数(或您正在集成的任何东西)上触发,就可以使用 Postman 之类的工具对其进行测试,它不关心 CORS。
  8. 最后,要让 CORS 正常工作,请单击操作 > 启用 CORS

我输入了以下设置:

方法:POST

访问控制允许方法:OPTIONS、POST

Access-Control-Allow-Headers: 'Content-Type,X-Amz-Date,X-Amz-Security-Token,Authorization,X-Api-Key,X-Requested-With ,Accept,Access-Control-Allow-Methods,Access-Control-Allow-Origin,Access-Control-Allow-Headers'

访问控制允许来源:'*'

然后点击“启用 CORS 并替换现有的 CORS 标头”。

你还没有完成。如果您以 Lambda 函数为目标,这仍然无法解决问题。您需要将 CORS 标头添加到 Lambda 的实际响应中。

这是我的 Lambda 的完整代码:

exports.handler = async (event, context) => {
   let body = JSON.stringify('Success!');
   let statusCode = '200';
   const headers = {
      'Content-Type': 'application/json',
      "Access-Control-Allow-Headers": "Content-Type,X-Amz-Date,X-Amz-Security-Token,Authorization,X-Api-Key,X-Requested-With,Accept,Access-Control-Allow-Methods,Access-Control-Allow-Origin,Access-Control-Allow-Headers",
      "Access-Control-Allow-Origin": "*",
      "Access-Control-Allow-Methods": "*",
      "X-Requested-With": "*"
   };
    
   return {
      statusCode,
      body,
      headers,
   };
};

我不确定您在 Lambda 中返回的 CORS 设置是否与您在 AWS 控制台中应用的 CORS 设置相同。

这真是令人头疼,除非我做错了什么,否则 AWS 的实施非常糟糕。

更新:在遇到更多问题后,我想我会更新我的答案,说明您提出的请求似乎也会影响 CORS。我正在更改我的 API 并且 CORS 错误再次开始发生;最终,唯一的解决方案是删除我发送给 AWS 的请求中的一些标头。

这导致了 CORS 错误:

const res = await fetch('https://123.execute-api.eu-west-1.amazonaws.com/test', {
   method: 'POST',
   headers: {
      'Authorization': jwt,
      "Access-Control-Allow-Origin": "*" // This had to be removed to fix the CORS error
   }
});

如您所见,我在对我的 API 的出站请求中指定了 Access-Control-Allow-Origin。这一直存在并且从未引起问题,但似乎现在我可以在请求中评论和取消评论该行并获取/不获取 CORS 错误。

更新 #2: 进一步更新,以拯救任何可能为此撞墙的人。在现有 API 网关添加新的源和方法后,请务必点击 @ 987654324@ 所以你的更改实际上是实时的。

AWS 确实需要清理 API Gateway 和 Lambda 的整个 UI。根本不清楚您是否有未发布的更改,或者甚至需要发布;用户界面使任何更改看起来都立即生效。

【讨论】:

  • 谢谢 .. 希望做出改变以使这个过程更容易。不应该有这么多“内部”知识才能让它发挥作用。
【解决方案2】:

主要问题在于 Options 方法提供的答案。出于某种原因,至少在我的情况下,模拟响应无法正常工作,因此我将其与 lambda 链接,其唯一目的是使用 200 代码响应并返回所有必要的标头。

因此,您需要做的是,在启用了 CORS 的资源的 options 方法中,将集成请求更改为 Lambda。

完成后,我们必须开发 lambda,使其返回 200 作为响应并接受所有必要的标头:

{
    'statusCode': 200,
    'headers': {
        'Content-Type': 'application/json',
          "Access-Control-Allow-Headers": "Content-Type,X-Amz-Date,X-Amz-Security-Token,Authorization,X-Api-Key,X-Requested-With,Accept,Access-Control-Allow-Methods,Access-Control-Allow-Origin,Access-Control-Allow-Headers",
          "Access-Control-Allow-Origin": "*",
          "Access-Control-Allow-Methods": "*",
          "X-Requested-With": "*"
    },
    'body': json.dumps({})
}

【讨论】:

  • 你可能是对的。自从我开始使用无服务器框架以来,为我创建了 OPTIONS 方法,我没有遇到任何问题。你的配置是这样的吗? i.imgur.com/q9NUW5u.png
猜你喜欢
  • 2020-10-01
  • 2017-09-29
  • 2019-09-17
  • 2023-03-14
  • 2020-11-05
  • 2022-08-17
  • 2021-07-25
  • 2021-10-03
  • 2020-07-27
相关资源
最近更新 更多