AWS SAM部署Lambda函数遭遇CORS跨域问题求助
解决AWS SAM部署Lambda的CORS问题及模块加载错误
一、先修复Lambda模块找不到的错误
你遇到的Cannot find module 'app'是导致CORS头完全失效的核心原因——Lambda无法启动,所有请求(包括预检OPTIONS)都会返回500错误,自然不会返回任何CORS头。
问题出在SAM模板的Handler配置与esbuild打包输出路径不匹配:
- esbuild将
src/app.ts打包后,默认输出到server/目录根下的app.js - 但你的Handler设置为
src/app.lambdaHandler,Lambda会去server/src/app.js查找文件,实际文件并不存在
修复步骤:
修改SAM模板中HelloWorldFunction的Handler配置:
Handler: app.lambdaHandler
可选:在esbuild的BuildProperties中明确指定输出文件名,确保对应关系:
Metadata: BuildMethod: esbuild BuildProperties: Minify: true Target: es2020 Sourcemap: true EntryPoints: - src/app.ts Outfile: app.js
重新部署后,模块加载错误即可解决,Lambda能正常执行。
二、解决CORS预检请求失败问题
错误提示显示预检OPTIONS请求无Access-Control-Allow-Origin头,说明预检请求未被正确处理,以下两种方案二选一:
方案1:让API Gateway自动处理OPTIONS预检(推荐)
通过SAM模板配置全局API CORS,让API Gateway直接接管OPTIONS请求,无需Lambda介入。注意之前的CORS配置存在语法错误——参数值不需要额外加单引号:
正确的全局CORS配置:
Globals: Api: TracingEnabled: true Cors: AllowMethods: "POST, GET, OPTIONS, PUT, DELETE" AllowHeaders: "Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With, x-access-token, jwt" AllowOrigin: "http://localhost:3000, http://localhost:3001" AllowCredentials: true # 若前端请求带凭证(如cookie),必须开启此项
配置后,API Gateway会自动为所有端点创建OPTIONS方法并返回合规的CORS头,Lambda只需处理业务请求(GET/POST等),同时在响应中保持CORS头即可。
方案2:让Lambda显式处理OPTIONS请求
如果不想依赖API Gateway自动处理,需要在Lambda中直接响应OPTIONS请求:
export const lambdaHandler = async (event: APIGatewayProxyEvent): Promise<APIGatewayProxyResult> => { // 处理预检OPTIONS请求 if (event.httpMethod === 'OPTIONS') { const origin = event.headers?.Origin || event.headers?.origin || '*'; return { statusCode: 200, headers: { 'Access-Control-Allow-Origin': allowedCorsOrigins[origin] ? origin : '*', 'Access-Control-Allow-Methods': 'POST, GET, OPTIONS, PUT, DELETE', 'Access-Control-Allow-Headers': 'Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With, x-access-token, jwt', 'Access-Control-Allow-Credentials': origin !== '*' ? 'true' : 'false' }, body: '' }; } try { // 补充缺失的jwtPayload获取逻辑 const jwtPayload = await authenticateToken(event); return sendSuccessResponse({ event, data: { message: 'hello world', time: new Date().toISOString(), whoami: jwtPayload, }, dataType: 'json', }); } catch (err) { console.log(err); return sendErrorResponse({ event, error: { message: 'Internal Server Error', details: [ { code: 0, error_type: 'internal_server_error', message: 'Internal Server Error', }, ], }, errorCode: 500, }); } };
同时,在SAM模板的HelloWorldFunction事件中添加OPTIONS方法:
Events: HelloWorld: Type: Api Properties: Path: /hello Method: get HelloWorldOptions: Type: Api Properties: Path: /hello Method: options
三、额外排查点
- 验证响应头:用Postman直接调用API端点,确认响应中是否包含
Access-Control-Allow-Origin等CORS头 - 凭证模式限制:若前端请求带
credentials: 'include',Access-Control-Allow-Origin不能用通配符*,必须指定具体源,且Access-Control-Allow-Credentials设为true - 缓存问题:修改CORS配置后,重新部署API Gateway并清除浏览器缓存,避免旧响应头干扰
- Lambda逻辑漏洞:检查你的业务代码中是否有未捕获的异常,导致Lambda提前退出,未返回CORS头
内容的提问来源于stack exchange,提问作者monzim
相关产品推荐
相关产品推荐

