我正在构建一个应用程序,该应用程序通过Web前端上使用的AWS Amplify与AWS上的无服务器API(API网关/ Lambda)连接。
请求成功后,一切正常(我想应该是明确的)。没有CORS问题。但是,如果我尝试返回“失败”响应,则前端不会收到该响应。它接收到通用Network Error
,但没有有关发生的任何信息,并且控制台记录了故障。
我认为代码将对此更加有意义。我使用这样的代码(在其他地方配置了Ampl)向API请求:
import { API } from 'aws-amplify';
...
API.get('apiName', path, options)
.then(response => {
// Whatever
})
.catch(err => {
// Whatever
})
在Lambda中,我将返回一个完整的响应对象(在运行callback(null, responseObject)
之前,Cloudwatch会进行验证,就像我登录时一样):
{
"statusCode": 200,
"headers": {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Credentials": true
},
"body": "{ /* whatever */ }"
}
或者这个:
{
"statusCode": 500,
"headers": {
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Credentials": true
},
"body": "{ /* error here */ }"
}
在200
情况下,响应完美地到达了我的前端(在.then
函数中显示为response
)。在500
(或一般错误)的情况下,.catch
被称为, err
对象不是我所输入的 响应正文,而是一个普通的Network Error
,没有相关信息(或状态码):
Error: Network Error
at createError (createError.js:16)
at XMLHttpRequest.handleError (xhr.js:87)
为澄清起见,只需将statusCode
从200更改为400,都意味着该请求在前端被捕获(良好),并且该错误没有我所需要的信息从Lambda(坏)返回。
控制台还会记录错误:
DELETE https://abcdefg.execute-api.us-west-2.amazonaws.com/development/my-endpoint 403 ()
Failed to load https://abcdefg.execute-api.us-west-2.amazonaws.com/development/my-endpoint: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access. The response had HTTP status code 403.
它还会记录与CORS故障相关的信息,这对我来说是没有意义的,因为我遵循的是与成功案例相同的 exact 模式,只是使用更高的statusCode
。
Cross-Origin Read Blocking (CORB) blocked cross-origin response https://abcdefg.execute-api.us-west-2.amazonaws.com/development/my-endpoint with MIME type application/json.
XHR failed loading: DELETE "https://abcdefg.execute-api.us-west-2.amazonaws.com/development/my-endpoint".
知道这里发生了什么吗?不能访问前端的实际信息错误确实令人沮丧。请让我知道是否还有其他信息可以帮助解决此问题。
编辑-根据下面@Michael的反馈,我检查了我的应用是否使用了lambda或lambda-proxy,实际上是使用了lambda-proxy,应该不是会产生这种行为。
在我的serverless.yml文件中有一些代码,
functions:
projectsGetAll:
handler: handlers/projects/getAll.handler
events:
- http:
path: projects
method: get
cors: true
authorizer: aws_iam
这是来自AWS API Gateway的以下端点之一的屏幕截图(端点为空白):
我想确认这是lambda-proxy的意外行为。可能有某些设置使事情变糟了吗?
答案 0 :(得分:1)
这最终取决于您如何配置API网关,例如Lambda代理等。如果您未使用Lambda代理设置,则需要在API网关内映射这些错误响应/代码,请参阅此处的大量文章: https://aws.amazon.com/blogs/compute/error-handling-patterns-in-amazon-api-gateway-and-aws-lambda/
如果您使用的是Lambda代理,则只是从Lambda作为特定类型的代理响应返回:https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-create-api-as-simple-proxy-for-lambda.html
答案 1 :(得分:1)
如果您使用 API Gateway 并遇到此问题,请确保更新 API Gateway 的“网关响应”默认 5XX 和默认 4XX 标头以包含正确的响应标头(和/或消息)--否则 { {1}} 不会在错误响应时发送,您的浏览器将抛出“网络错误”。
例如,将默认 5XX 和 4XX 的响应标头设置为:
Access-Control-Allow-Origin
更新这些默认标头值解决了我的问题,现在正在解决正确的错误消息。
答案 2 :(得分:0)
想通了!错误对象又回来了(在500
键下,通用的NetworkError
和response
包含了我构造的错误)。
因此,如果我登录error.response
,即使错误对象本身的statusCode
为{{1},也会得到带有其自身消息和code
的完全构造的错误对象。 }和500
的消息,错误捕获过程似乎在控制台中抛出了不准确的错误日志(CORB内容)。
很奇怪。不知道这是预期的Lambda行为,还是Amplify发生的事情,或者我做错了什么,但是如果有人遇到此问题,希望对您有所帮助!
编辑-显然,这是预期的放大行为,我在文档中错过了该行为。
但是我发现了另一个似乎是错误的问题。仅当我不在请求选项中指定Error: Network Error
时,才会显示此响应键。换句话说,此请求返回带有headers
键的error
:
response
但是这个返回没有密钥的错误:
API.get('my-api', '/path')
很奇怪,但对我来说是正确的。甚至 other 选项都可以,但是headers选项似乎使事情变得混乱(并且仅用于错误响应)。