使用自定义域名的AWS API Gateway中XMLHttpRequest请求遭CORS策略阻止问题排查
首先,咱们先拆解你遇到的这个错误:
Access to XMLHttpRequest at 'https://test.mycustomendpoint.com/auth/v1/?action=login' from origin 'http://localhost' has been blocked by CORS policy: Request header field access-control-allow-origin is not allowed by Access-Control-Allow-Headers in preflight response.
这个错误的核心问题是:你的前端请求里错误地发送了access-control-allow-origin这个请求头,但这个头本应该是服务端返回给前端的响应头,不是前端要主动发送的。而API Gateway的CORS配置里没把这个头加入允许的请求头列表,所以预检(OPTIONS)请求直接被拒绝了。
下面是具体的排查和修复步骤:
1. 先清理前端请求里的多余头
检查你的Axios全局配置或者本次请求的自定义头,看看是不是不小心加了access-control-allow-origin这个头。比如有没有类似这样的代码:
axios.defaults.headers.common['Access-Control-Allow-Origin'] = '*'
如果有,直接删掉这行代码——这个头是服务端返回给前端的,前端完全不需要发送它。你现在的代码里只设置了Content-Type,这部分是没问题的,重点找有没有额外加了这个错误的请求头。
2. 确认API Gateway的CORS配置
因为你用了Lambda代理集成,API Gateway的CORS配置需要和Lambda返回的响应头配合,注意这几点:
- 看你附图2的
Access-Control-Allow-Headers配置,确保包含Content-Type(你代码里明确设置了这个请求头),但不要加access-control-allow-origin(因为前端不该发这个头)。 - 配置完CORS后,一定要重新部署API Gateway的测试阶段!很多人配置完忘了部署,导致配置根本没生效,这是高频踩坑点。
3. 修正Lambda函数的响应头(关键!)
因为你启用了Lambda代理集成,API Gateway会直接把Lambda的返回作为响应返回给前端,所以Lambda必须自己返回正确的CORS响应头,否则API Gateway的CORS配置会被覆盖。
以Node.js Lambda为例,你的返回结构应该类似这样:
exports.handler = async (event) => { // 处理业务逻辑 const result = { status: 'success', data: 'your processed data' }; return { statusCode: 200, headers: { "Access-Control-Allow-Origin": "http://localhost", // 生产环境请替换成你的前端正式域名,不要用* "Access-Control-Allow-Headers": "Content-Type", // 这里要和API Gateway配置的允许请求头一致 "Content-Type": "application/json" }, body: JSON.stringify(result) }; };
注意:如果你的前端会发送其他自定义请求头,也要把它们加到Access-Control-Allow-Headers里,同时同步更新API Gateway的CORS配置。
4. 用浏览器Network面板验证
修复后,打开浏览器的开发者工具→Network面板,找到OPTIONS类型的预检请求,查看它的响应头:
- 确认
Access-Control-Allow-Origin是你的前端域名(http://localhost) - 确认
Access-Control-Allow-Headers包含你实际发送的请求头(比如Content-Type)
如果这两个都正确,后续的POST请求就能正常发起了。
内容的提问来源于stack exchange,提问作者user19517065

