求带HttpApi资源CORS配置的AWS SAM模板可用示例
解决AWS SAM HttpApi CORS配置无效及OPTIONS 403问题
原模板核心问题分析
- 资源类型拼写错误:
AWS::Serverless:HttpApi应改为AWS::Serverless::HttpApi(双冒号) - CORS规则不匹配:
AllowMethods未包含实际使用的POST方法,导致OPTIONS预请求返回的允许方法不匹配,触发403 - DefinitionBody冲突:当手动指定
DefinitionBody时,SAM的CorsConfiguration不会自动生成OPTIONS方法,需额外配置 - 输出变量错误:错误引用了RestApi的
ServerlessRestApi变量,HttpApi应使用自身的ApiEndpoint属性
示例1:SAM简化配置(自动处理CORS)
适合无需复杂OpenAPI定义的场景,SAM会自动生成OPTIONS方法并配置CORS规则:
AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 Description: sam-app with working HttpApi CORS Globals: Function: Timeout: 3 Resources: MainApi: Type: AWS::Serverless::HttpApi Properties: CorsConfiguration: AllowHeaders: ["*"] AllowMethods: ["GET", "POST", "OPTIONS"] # 包含所有需要的方法(含OPTIONS) AllowOrigins: ["http://localhost:8000"] ExposeHeaders: ["*"] CheckHumanFunction: Type: AWS::Serverless::Function Properties: PackageType: Image Architectures: [x86_64] Events: CheckHuman: Type: HttpApi Properties: ApiId: !Ref MainApi Path: /human-check Method: post Cors: true # 启用该路径的CORS,继承全局配置 Metadata: DockerTag: nodejs16.x-v1 DockerContext: ./api/human-check Dockerfile: Dockerfile Outputs: MainApiEndpoint: Description: "API Gateway HttpApi endpoint URL" Value: !Sub "${MainApi.ApiEndpoint}" CheckHumanFunction: Description: "CheckHuman Lambda Function ARN" Value: !GetAtt CheckHumanFunction.Arn CheckHumanFunctionIamRole: Description: "Implicit IAM Role created for CheckHuman function" Value: !GetAtt CheckHumanFunctionIamRole.Arn
示例2:手动配置OpenAPI CORS规则
如果必须使用DefinitionBody定义API,需为每个路径手动添加OPTIONS方法并配置CORS响应头:
AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 Description: sam-app with HttpApi CORS via OpenAPI Globals: Function: Timeout: 3 Resources: MainApi: Type: AWS::Serverless::HttpApi Properties: DefinitionBody: openapi: 3.0.1 info: title: !Ref 'AWS::StackName' paths: /human-check: post: x-amazon-apigateway-integration: uri: !Sub "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${CheckHumanFunction.Arn}/invocations" httpMethod: POST type: aws_proxy options: responses: '200': description: "Preflight response" headers: Access-Control-Allow-Origin: schema: type: string Access-Control-Allow-Methods: schema: type: string Access-Control-Allow-Headers: schema: type: string x-amazon-apigateway-integration: type: mock requestTemplates: application/json: | { "statusCode" : 200 } responses: default: statusCode: 200 responseParameters: method.response.header.Access-Control-Allow-Origin: "'http://localhost:8000'" method.response.header.Access-Control-Allow-Methods: "'GET,POST,OPTIONS'" method.response.header.Access-Control-Allow-Headers: "'*'" responseTemplates: application/json: | {} CheckHumanFunction: Type: AWS::Serverless::Function Properties: PackageType: Image Architectures: [x86_64] Metadata: DockerTag: nodejs16.x-v1 DockerContext: ./api/human-check Dockerfile: Dockerfile Outputs: MainApiEndpoint: Description: "API Gateway HttpApi endpoint URL" Value: !Sub "${MainApi.ApiEndpoint}" CheckHumanFunction: Description: "CheckHuman Lambda Function ARN" Value: !GetAtt CheckHumanFunction.Arn CheckHumanFunctionIamRole: Description: "Implicit IAM Role created for CheckHuman function" Value: !GetAtt CheckHumanFunctionIamRole.Arn
关键说明
- 示例1通过SAM自动管理API路径,无需手动编写OpenAPI,CORS规则会自动应用到所有关联路径
- 示例2使用mock集成处理OPTIONS预请求,直接返回符合要求的CORS响应头,确保前端能正常发起跨域请求
内容的提问来源于stack exchange,提问作者fixiecoder
相关产品推荐
相关产品推荐

