我已经构建了一个支持CORS的API,但是HttpClient
在客户端给我带来了一些奇怪的东西。当我查看Chrome中的“网络”选项卡时,我看到对我的请求的正确响应,但由于我在本地运行,因此Angular会抛出CORS错误。
这是我的代码:
public search(data: string): Promise<any> {
const url = `${Configuration.ENDPOINTS.APP}`, headers = new HttpHeaders({ 'x-api-key': 'abcd...' });
const body = { data: data };
return this._http.post<any>(url, body, { headers: headers }).toPromise();
}
/// View Logic
search("test").then(console.log).catch(console.error)
运行此代码,我在Chrome的控制台标签上收到以下错误:
Failed to load https://abcd.execute-api.us-east-1.amazonaws.com/v1/: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8100' is therefore not allowed access.
HttpErrorResponse
{
"headers": {
"normalizedNames": {},
"lazyUpdate": null,
"headers": {}
},
"status": 0,
"statusText": "Unknown Error",
"url": null,
"ok": false,
"name": "HttpErrorResponse",
"message": "Http failure response for (unknown url): 0 Unknown Error",
"error": {
"isTrusted": true
}
}
但是,如果我查看“网络”选项卡,这是响应:
Headers
content-length: 16865
content-type: application/json
date: Wed, 04 Apr 2018 17:34:28 GMT
status: 200
via: 1.1 cae81d5ff1d682b28f2deabdd94777d4.cloudfront.net (CloudFront)
x-amz-apigw-id: E07puFICPHcFYCA=
x-amz-cf-id: -UYlYK_yC8cUVZF2OnRFcUb_fIjcRrgMuvpU3ADdbpyEvPZ-nUJXNA==
x-amzn-requestid: 6d3a0533-382e-11e8-ad31-b124cb8b7a9a
x-amzn-trace-id: sampled=0;root=1-5ac50ca4-2411d1b5cb7d1af6232883a6
x-cache: Miss from cloudfront
Response
{
meta: { ... }
data: [ ... ]
}
出于安全原因,我从响应中省略了一些内容。
有谁知道发生了什么事?为什么网络选项卡有效但Angular没有?
编辑:这是AWS API网关的一部分。所有资源都启用了CORS,但由于某种原因,与Lambda集成的端点正在向我抛出这些资源。其他端点直接进入DynamoDB并完美运行......
答案 0 :(得分:1)
引擎盖 - 浏览器成功请求您的API,但由于请求有不同的来源,并且 Access-Control-Allow-Origin 标头丢失 - 由于安全原因而被阻止,这是现代网络浏览器的标准行为。
您可以阅读有关CORS here的更多信息。
正如我所见,您正在使用AWS API Gateway - here is guide how to enable CORS at API Gateway
修改强>
如果您启用了CORS,状态代码为200且仍然缺少 Access-Control-Allow-Origin ,您可能在API网关上使用Lambda代理集成。在这种情况下 - 您的Lambda负责返回标题等。
因此响应对象应如下所示:
{
...
"headers": {
"Access-Control-Allow-Origin": "*",
...
},
...
}
答案 1 :(得分:0)
据我所知,有两种选择。 第一种是修改后端,以便它在Access-Control-Allow-Origin标头中发送localhost,第二种(对我来说更简单)是代理你的api调用。如果你使用angular-cli,你可以配置它来代理你的请求,如果没有 - 你可以使用nginx - 只需下载它,甚至不需要安装东西,然后修改conf文件(fiy)