尽管设置了标头,但对API Gateway的调用返回了CORS错误

时间:2020-07-17 18:50:44

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

我有一个与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网关指定了CORS设置:

enter image description here

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本身的错误。

2 个答案:

答案 0 :(得分:3)

为@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

访问控制权限方法:选项,发布

访问控制允许标题:“内容类型,X-Amz-日期,X-Amz-安全令牌,授权,X-Api密钥,X-Requested-With ,接受,允许访问控制的方法,允许访问控制的起源,允许访问控制的标题的

访问控制允许来源:“ *”

然后单击“启用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网关添加新的来源和方法后,请确保点击{ {1}},使您的更改真正生效。

AWS确实需要清理API网关和Lambda的整个UI。尚不清楚您尚未发布更改,甚至还不需要发布;用户界面使所有更改都立即生效。

答案 1 :(得分:1)

主要问题在于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({})
}