通过浏览器调用SAM部署的AWS Serverless API时的CORS问题
问题解决步骤
1. 完善API Gateway的CORS配置
不要仅设置Cors: '*',这种通配符配置无法兼容带Authorization头或凭证的请求。需要明确指定允许的域名、请求头和方法,同时开启凭证支持:
Resources: MyServerlessApi: Type: AWS::Serverless::Api Properties: Cors: AllowOrigin: "'https://your-frontend-domain.com'" # 替换为你的前端实际域名 AllowHeaders: "'Content-Type,Authorization'" AllowMethods: "'GET,POST,OPTIONS'" AllowCredentials: true # 其他API配置...
2. 让Cognito授权器跳过OPTIONS预检请求
浏览器发送的OPTIONS预检请求不会携带Authorization头,默认会被Cognito授权器拦截返回401。在SAM的API授权配置中添加AddDefaultAuthorizerToCorsPreflight: false,让预检请求绕过授权:
Resources: MyServerlessApi: Type: AWS::Serverless::Api Properties: Auth: DefaultAuthorizer: MyCognitoAuthorizer AddDefaultAuthorizerToCorsPreflight: false # 关键配置 Authorizers: MyCognitoAuthorizer: UserPoolArn: !GetAtt MyUserPool.Arn # 其他API配置...
3. (可选)Lambda代理集成的OPTIONS响应处理
如果你的API用了Lambda代理集成,虽然SAM的CORS配置会自动处理OPTIONS响应,但如果仍有问题,可以在Lambda函数中手动添加预检请求的处理逻辑:
def lambda_handler(event, context): if event["httpMethod"] == "OPTIONS": return { "statusCode": 200, "headers": { "Access-Control-Allow-Origin": "https://your-frontend-domain.com", "Access-Control-Allow-Headers": "Content-Type,Authorization", "Access-Control-Allow-Methods": "GET,POST,OPTIONS", "Access-Control-Allow-Credentials": "true" }, "body": "" } # 处理业务请求的逻辑...
核心原因总结
- 初始CORS配置未包含
Authorization头,导致浏览器拒绝请求 - OPTIONS预检请求被Cognito授权器拦截,返回401错误
- curl调用正常是因为它不会触发浏览器的CORS预检机制,直接发送请求并携带授权头
内容的提问来源于stack exchange,提问作者Brandon Lee
相关产品推荐
相关产品推荐

