每当我尝试通过浏览器通过 POST 访问无服务器 lambda 函数时,都会收到错误
对预检请求的响应未通过访问控制检查:请求的资源上不存在 >'Access-Control-Allow-Origin' 标头。
当它是
/GET
时,它工作得很好,我读过它是因为它没有发送飞行前请求。当我将其更改为 POST
时,它就会失败。
我正在运行的命令:
sam local start-api
我的 template.yaml 是:
...
Resources:
PropertiesFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: target/service-0.0.1-SNAPSHOT.jar
Handler: com.aws.PropertiesHandler::handleRequest
Runtime: java8
Events:
PropertiesApi:
Type: Api
Properties:
Path: /properties
Method: post
...
如何在这些端点上启用 CORS?
我有同样的错误,我已经通过 3 个步骤修复了它。 (Java8 中的 AWS Lambda、SAM CLI v0.37.0)
Map<String, String> headers = new HashMap<>();
headers.put("Content-Type", "application/json");
headers.put("X-Custom-Header", "application/json");
headers.put("Access-Control-Allow-Origin", "*");
headers.put("Access-Control-Allow-Methods", "GET, POST, OPTIONS, PUT, PATCH, DELETE");
headers.put("Access-Control-Allow-Headers", "X-Requested-With,content-type");
Globals:
Function:
Timeout: 20
Api:
Cors:
AllowMethods: "'GET,POST,OPTIONS'"
AllowHeaders: "'content-type'"
AllowOrigin: "'*'"
AllowCredentials: "'*'"
Events:
HelloWorld:
Type: Api
Properties:
# Path: /hello
# Method: get
Path: "/{proxy+}"
Method: ANY
首先,您需要在 template.yml 中添加以下部分以在 API 网关中启用 cors:
Globals:
Api:
Cors:
AllowMethods: "'GET,POST,OPTIONS'"
AllowHeaders: "'content-type'"
AllowOrigin: "'*'"
AllowCredentials: "'*'"
然后在您的 lambda 函数响应中
MultivaluedMap<String, Object> headers = responseContext.getHeaders();
headers.add("Access-Control-Allow-Origin", "*");
headers.add("Access-Control-Allow-Headers", requestContext.getHeaderString("Access-Control-Request-Headers"));
headers.add("Access-Control-Allow-Methods", "GET,PUT,POST,DELETE,HEAD,OPTIONS");
您应该能够通过在处理函数中将以下标头显式添加到响应中来解决本地测试的问题:
"Access-Control-Allow-Origin": "*"
如果您在本地运行,则可以使用仅添加标头的环境变量。
这是我拥有的处理函数中的一个简单的 Python 示例:
if not all(field in values for field in required_fields):
response = {
'statusCode': 400,
'body': json.dumps(
{
'message': 'Required data missing from request body'
}
)
}
# explicitly add CORs headers for local testing
response['headers'] = {"Access-Control-Allow-Origin": "*"}
return response
这仅适用于本地测试,当您部署到 API 网关时,COR 由 API 网关上的配置处理。
这个解决方案对我有用,直到我还使用 Cognito 用户池向 API 添加了授权,我目前正在尝试解决该问题。
这是关于该问题的类似帖子: 如何为 AWS API Gateway 资源启用 CORS
如果您使用 SAM,请在无服务器模板文件上尝试此操作
"Globals": {
"Api": {
"Cors": {
"AllowMethods": "'POST, GET, PUT, DELETE'",
"AllowHeaders": "'content-type'",
"AllowOrigin": "'*'"
}
}
}
聚会有点晚了,但我一直在努力解决这个问题并找到了解决方案。希望对其他人也有帮助。我不想用额外的、不安全的标头来污染我的 lambda 代码,因此考虑在 SAM 中执行此操作。
我仅将 SAM 用于本地开发,而不用于部署,因此该解决方案可能并不适合所有人,因为它需要更改模板。
解决此问题的方法是在 SAM 模板中使用
HttpApi
而不是 'Api
。我已将以下内容添加到 Globals
部分:
Globals:
HttpApi:
CorsConfiguration:
AllowHeaders:
- Content-Type
- Authorization
- Access-Control-Allow-Origin
AllowMethods:
- '*'
AllowOrigins:
- '*'
然后将
Function
资源更改为 HttpApi
类型:
MyFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: api/
Handler: management.createHandler
Runtime: nodejs20.x
Architectures:
- x86_64
Events:
HelloWorld:
Type: HttpApi <-- Change here
Properties:
Path: /announcement
Method: post
现在当
local start-api
返回 CORS 标头时所有响应。
一件奇怪的事情,我在模板中定义了许多函数,但我只需要更改其中一个函数上的
Type
即可使标题适用于所有函数。