AWS Lambda API遭CORS策略拦截问题排查求助
我通过Serverless Framework部署了一个Python编写的AWS Lambda API,前端调用时遭遇CORS策略拦截,错误信息如下:
Access to fetch at 'https://0vdu10a3e6.execute-api.eu-west-1.amazonaws.com/dev/init' from origin 'http://localhost:8080' has been blocked by CORS policy: Request header field access-control-allow-origin is not allowed by Access-Control-Allow-Headers in preflight response.
已尝试调整Lambda返回的CORS头配置,但问题仍未解决,且Lambda无日志输出。附上相关配置代码,请求协助排查:
Lambda代码
def init(event, context): # 省略大部分业务代码 return { "statusCode": 200, "headers": { "Access-Control-Allow-Origin": "http://localhost:8080", "Access-Control-Allow-Credentials": True, "Access-Control-Allow-Headers": "Origin, Content-Type, Credentials", "Access-Control-Allow-Methods": "POST, GET", 'Content-Type': "application/json" }, "body": json.dumps(response) }
Dockerfile
FROM public.ecr.aws/lambda/python:3.11.2023.09.12.11 WORKDIR /app COPY Models/best.pt /app COPY AcharyaMeasuringPrototype.py /app COPY Utlis.py /app COPY requirements.txt /app RUN pip install --upgrade pip RUN pip cache purge RUN pip install 'ultralytics[yolo]~=8.0.147' RUN pip install -r requirements.txt EXPOSE 3000 CMD [ "AcharyaMeasuringPrototype.init" ]
serverless.yaml
service: acharya-ml provider: name: aws runtime: python3.8 stage: dev region: eu-west-1 iam: role: statements: - Effect: "Allow" Action: - "ecr:InitiateLayerUpload" - "ecr:SetRepositoryPolicy" - "ecr:GetRepositoryPolicy" Resource: !Join - ':' - - 'arn:aws:ecr' - Ref: AWS::Region - Ref: AWS::AccountId - 'repository/*' plugins: # - serverless-python-requirements - serverless-offline custom: pythonRequirements: dockerizePip: true functions: main: image: 550512796301.dkr.ecr.eu-west-1.amazonaws.com/acharya-prototype-ml:latest timeout: 30 events: - http: path: /init method: POST
前端fetch代码
const res = await fetch("https://hinjggqsg4.execute-api.eu-west-1.amazonaws.com/dev/init", { method: "POST", headers: { 'Content-Type': 'application/json' }, });
排查方向
补全API Gateway CORS配置
Serverless部署的HTTP API中,OPTIONS预请求默认由API Gateway处理,而非Lambda。需在serverless.yaml的http事件中添加CORS规则,覆盖默认配置:events: - http: path: /init method: POST cors: origin: http://localhost:8080 headers: - Content-Type - Origin - Credentials allowCredentials: true methods: - POST - GET - OPTIONSLambda显式处理OPTIONS请求
如果API Gateway未配置自动处理OPTIONS,需在Lambda代码中添加分支逻辑:def init(event, context): if event['httpMethod'] == 'OPTIONS': return { "statusCode": 200, "headers": { "Access-Control-Allow-Origin": "http://localhost:8080", "Access-Control-Allow-Credentials": True, "Access-Control-Allow-Headers": "Origin, Content-Type, Credentials", "Access-Control-Allow-Methods": "POST, GET, OPTIONS" }, "body": "" } # 原有业务逻辑代码修复Lambda日志无输出问题
当前IAM角色缺少CloudWatch日志权限,需补充:iam: role: statements: # 保留原有ECR权限 - Effect: "Allow" Action: - "logs:CreateLogGroup" - "logs:CreateLogStream" - "logs:PutLogEvents" Resource: "arn:aws:logs:*:*:*"同时本地运行Docker镜像,验证依赖是否完整、函数能否正常启动。
检查请求头匹配性
错误提示提到access-control-allow-origin不被允许,确认前端未误发该请求头(当前代码未包含),优先排查前三点配置问题。
内容的提问来源于stack exchange,提问作者Simões

