在Angular 11中,如何通过API网关将HTTP POST应用程序/json发送到AWS Lambda



我计划在AWS Amplify中托管一个角度应用程序。它为其REST API调用Lambda函数。我有一个测试应用程序,它基本上是成功的,但它不能做到这一点:将JSON数据POST到托管的URI。

在浏览器中,我有一个Angular客户端,它有一个按钮,单击时会调用HttpClient.postHttpClient.request。我测试过多个后端服务器:(1(NestJs/Express,(2(sam local start-api和(3(AWS托管。本地sam服务器和托管环境是同步的,并且使用相同的template.yaml。这三个服务器都接受application/jsonapplication/x-www-form-urlencoded中的Content-Type

除了托管lambda函数中的Json之外,Content-Type、服务器实例和HttpClient方法的每一个组合(postrequest(“POST”,...)(都可以工作。它似乎立即被拒绝了。

该调用从未进入Cloudwatch日志,我猜这意味着它在某种程度上是错误的,并被我不知道的东西过滤掉了。我对AWS很陌生,也不熟悉它的特殊性,所以我不确定我可以在托管环境中打开什么日志来捕捉这一点。它失败得太快了,从来没有到达日志,更不用说我的代码了,我很好奇这是个什么问题。

与Json一起冰壶同样有效:curl -X POST -H "Content-Type:application/json" ...

总之,当使用.post().request()方法将Json或Form样式发布到非AWS和本地AWS web服务器时,一切都很顺利。表单样式的POST到AWS托管(通过API网关(也起作用。命令行手工制作的带有Json的POST也可用于托管AWS(通过API网关(。

只有从Angular托管到AWS的POST不起作用。

ETA这是一个代码片段:

const URI_LOCAL = “/api/music”;
const URI_HOSTED = “https://…amazonaws.com/Prod/api/music”;
const headers_j = new HttpHeaders({ 'Content-Type': 'application/json' });
const album = {"title":"Mullet Beginnings","band":"The Wallabys”};
const body_j = JSON.stringify(album);
// This fails
let res_j$ = this.http.post<any>(URI_HOSTED, body_j, { headers: headers_j });
// This works
const headers_x = new HttpHeaders({ 'Content-Type': 'application/x-www-form-urlencoded' });
const body_x = 'title=Dancing Beers&band=Evils Ypsley’;
let res_x$ = this.http.post<any>(URI_HOSTED, body_x, { headers: headers_x });

我也试过通过album而不是body_j。这两个选项(对象或JSON字符串(都适用于URI_LOCAL。两者都不适用于URI_HOSTED。

某个地方一定有人成功地将Json从Angular发布到了AWS托管环境中。关于我做错了什么,有什么建议吗?

[ETA]以下是来自浏览器控制台的错误日志:

[Error] Preflight response is not successful
[Error] XMLHttpRequest cannot load https://_SNIP_.amazonaws.com/Prod/api/rebuild due to access control checks.
[Log] POST: (main.js, line 194)
HttpErrorResponse
error: XMLHttpRequestProgressEvent {isTrusted: true, position: 0, totalSize: 0, lengthComputable: false, loaded: 0, …}
headers: HttpHeaders {normalizedNames: Map, lazyUpdate: null, headers: Map}
message: "Http failure response for https://_SNIP_.amazonaws.com/Prod/api/rebuild: 0 Unknown Error"
name: "HttpErrorResponse"
ok: false
status: 0
statusText: "Unknown Error"
url: "https://_SNIP_.amazonaws.com/Prod/api/rebuild"
[Error] Failed to load resource: Preflight response is not successful (rebuild, line 0)
结果aws托管托管的失败aws托管成功成功成功nestjs
客户端内容类型服务器
HttpClient.postjson失败
HttpClient.requestjsonaws
curljson成功
HttpClient.postjsonsam local成功
HttpClient.postjsonnestjs
HttpClient.postx-www-form托管的aws
HttpClient.postx-www-formsam local
HttpClient.postx-www-form成功

听起来像是CORS问题。

您不仅需要在API网关中启用CORS,而且您的Lambda API网关响应还必须包括访问控制头。

你的回复应该是这样的:

response = {
statusCode: 204,
headers: {
"Access-Control-Allow-Headers" : "Content-Type",
"Access-Control-Allow-Origin": "https://www.example.com",
"Access-Control-Allow-Methods": "OPTIONS,POST,GET",
},
};
return response;
};

最新更新