我是API网关和Lambda的新手。我正在尝试将基于Node.js Express的API部署到lambda。我正在使用awslabs中的aws-serverless-express example。因此,我的大部分AWS配置都是为我自动创建的。
似乎我的API通过API网关正常工作。我的帖子和get方法运行正常。但是,我需要支持CORS。我的应用程序应该返回对OPTIONS请求的正确CORS响应,但它不适用于AWS。
最终,无论我做什么,我都会收到500个选项请求回复。我无法弄清楚如何获得有关这500个错误的任何信息。我不确定是什么导致了他们。
这是500响应的正文{"message": "Internal server error"}
。
这些是响应标题:
内容长度:36
内容类型:application / JSON
日期:2017年7月9日星期日17:56:24 GMT
状态:500
via:1.1 9af17e5a616bfc9ac07fc7e415ade9e6.cloudfront.net(CloudFront)
的x AMZ-CF-ID:1_AZmkLqf1rjkog2MRtvcBAe54aIZdPWmNApBTwG48Af-v_g9WHkZw ==
的x AMZN-的requestId:ec216a62-64cf-11E7-ad2b-4f1e96508dba
x-cache:来自cloudfront的错误
我很确定我的OPTIONS请求甚至没有进入Lambda上的应用程序。
我尝试使用API网关(在我的应用程序中)配置CORS。我正在尝试将其配置为允许所有来源。
如果有什么我可以查看或正在调试此问题?
编辑:
为了尝试调试此问题,我尝试在CloudWatch中为API网关启用日志记录。
在执行此操作后,我在CloudWatch中看到了这两个网关外观日志:
我一直在使用prod所以我点击该链接并看到:
我假设这是一个很长的日志条目列表。我不确定“流”在这种情况下意味着什么。这些条目有数百种。因此,我选择具有最新时间戳的那个并单击它。现在我看到了:
似乎我的所有网关日志都是这样的。 IE:显然是空的。
那么,我是否正确设置了日志记录?我在寻找合适的地方吗?
答案 0 :(得分:1)
我刚刚完成了这个...隐藏在AWS lambda docs中启用CORS的事实是你必须在lambda中设置CORS头。所以这是如何做到的:
let payload = {
statusCode: 400,
body: JSON.stringify('body'),
headers: {"Access-Control-Allow-Origin": "*"} // NEED this for API CORS access
};
callback(null, payload);
您必须返回有效的statusCode和正文以及标题,否则API将无法将您的lambda响应转换为API响应。
答案 1 :(得分:0)
使用cloudformation创建无服务器解决方案时,我遇到了同样的问题。 Cloudformation创建了API Gateway + Lambda,一切看起来都还不错。但是,OPTIONS请求返回了内部服务器错误。
我必须去API网关并手动发布我的API一次。 (尽管它已经发布到生产阶段),然后OPTIONS请求起作用了。我现在可以使用cloudformation进行更新。
答案 2 :(得分:0)
对于仍然因aws-serverless-express而面临OPTIONS 500错误的人,解决方案是将contentHandling: CONVERT_TO_TEXT
添加到Swagger template的OPTIONS方法中
这是包含 / 和 / {proxy +} 路径
的招摇模板文件---
swagger: 2.0
info:
title: AwsServerlessExpressApi
basePath: /prod
schemes:
- https
paths:
/:
x-amazon-apigateway-any-method:
produces:
- application/json
responses:
200:
description: 200 response
schema:
$ref: "#/definitions/Empty"
x-amazon-apigateway-integration:
responses:
default:
statusCode: 200
uri: arn:aws:apigateway:YOUR_AWS_REGION:lambda:path/2015-03-31/functions/arn:aws:lambda:YOUR_AWS_REGION:YOUR_ACCOUNT_ID:function:${stageVariables.ServerlessExpressLambdaFunctionName}/invocations
passthroughBehavior: when_no_match
httpMethod: POST
type: aws_proxy
options:
consumes:
- application/json
produces:
- application/json
responses:
200:
description: 200 response
schema:
$ref: "#/definitions/Empty"
headers:
Access-Control-Allow-Origin:
type: string
Access-Control-Allow-Methods:
type: string
Access-Control-Allow-Headers:
type: string
x-amazon-apigateway-integration:
contentHandling: CONVERT_TO_TEXT
responses:
default:
statusCode: 200
responseParameters:
method.response.header.Access-Control-Allow-Methods: "'DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT'"
method.response.header.Access-Control-Allow-Headers: "'Content-Type,Authorization,X-Amz-Date,X-Api-Key,X-Amz-Security-Token'"
method.response.header.Access-Control-Allow-Origin: "'https://example.com'"
passthroughBehavior: when_no_match
requestTemplates:
application/json: "{\"statusCode\": 200}"
type: mock
/{proxy+}:
x-amazon-apigateway-any-method:
produces:
- application/json
parameters:
- name: proxy
in: path
required: true
type: string
responses: {}
x-amazon-apigateway-integration:
uri: arn:aws:apigateway:YOUR_AWS_REGION:lambda:path/2015-03-31/functions/arn:aws:lambda:YOUR_AWS_REGION:YOUR_ACCOUNT_ID:function:${stageVariables.ServerlessExpressLambdaFunctionName}/invocations
httpMethod: POST
type: aws_proxy
options:
consumes:
- application/json
produces:
- application/json
responses:
200:
description: 200 response
schema:
$ref: "#/definitions/Empty"
headers:
Access-Control-Allow-Origin:
type: string
Access-Control-Allow-Methods:
type: string
Access-Control-Allow-Headers:
type: string
x-amazon-apigateway-integration:
contentHandling: CONVERT_TO_TEXT
responses:
default:
statusCode: 200
responseParameters:
method.response.header.Access-Control-Allow-Methods: "'DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT'"
method.response.header.Access-Control-Allow-Headers: "'Content-Type,Authorization,X-Amz-Date,X-Api-Key,X-Amz-Security-Token'"
method.response.header.Access-Control-Allow-Origin: "'https://example.com'"
passthroughBehavior: when_no_match
requestTemplates:
application/json: "{\"statusCode\": 200}"
type: mock
x-amazon-apigateway-binary-media-types:
- '*/*'
definitions:
Empty:
type: object
title: Empty Schema
更多信息可以在GitHub Internal server error when request method OPTIONS
上找到希望这会有所帮助!
答案 3 :(得分:0)
我和@scopchanov有类似的问题。
在我的AWS Lambda + API网关+无服务器框架1.42.3 + Express.js项目中有效的是:
我必须启用CORS /从Express发送标头:
/// AWS API Gateway CORS(OPTIONS)支持是否有问题? app.use(cors({credentials:true}))); app.options(“ *”,cors());
请勿在API网关中启用CORS,即不要在serverless.yml
中进行此操作:
没有cors: true
,所有请求都可以正常工作。
在cors: true
中,OPTIONS
请求将以{"message": "Internal server error"}
响应(无论Lambda函数做什么,它似乎都是由API Gateway直接发送的,或者是错误的MOCK集成发送的)
答案 4 :(得分:0)
对我来说,解决方案是改变:
cors: true
到
cors:
origin: '*'
我不确定有什么区别,但一个给我内部服务器错误,另一个没有。
答案 5 :(得分:-1)
您可以在路线索引文件中使用以下代码
app.options(function(req,res){res.send(200);})
这里app是express的路由器对象。这会将所有选项请求发送到200。