使用Nginx、Express和Cloudflare时CORS跨域错误如何排查解决?
问题根因定位
你遇到的CORS报错是多个配置错误叠加导致的,核心问题如下:
- Express的CORS配置存在语法错误:
cors()中间件需要传入对象格式的参数,你写的配置缺少外层大括号,属于无效配置,CORS中间件根本没有按预期生效 - 同时在Express和Nginx两层配置CORS规则,会导致响应返回重复的
Access-Control-Allow-Origin头,浏览器识别到重复头会直接判定跨域不合法 - Nginx的CORS配置不完整:默认
add_header仅在2xx/3xx响应时生效,接口返回4xx/5xx状态码时不会携带跨域头;同时没有处理OPTIONS预检请求,浏览器发送的预检请求得不到正确响应也会触发CORS报错 - 可能存在Cloudflare缓存影响:Cloudflare会缓存历史响应,如果你之前未配置CORS时的响应被缓存,就算修改了配置,旧缓存的响应依然不会带跨域头
修复方案
CORS规则只需在其中一层配置即可,不要同时在Express和Nginx配置,推荐两种方案二选一:
方案1:仅配置Express(适合开发场景,规则更灵活)
- 先删除Nginx中
api.mywebsite.comserver块下所有CORS相关的add_header配置 - 修正Express的CORS配置语法,正确写法如下:
// 注意参数是包裹在大括号里的对象,属性之间用逗号分隔 app.use(cors({ origin: process.env.FRONT_END, // 不需要携带cookie的话也可以直接填'*' credentials: true // 仅当接口需要接收/返回cookie时加这个配置,否则可以省略 }))
- 重启Node.js服务,清除Cloudflare缓存后测试即可
方案2:仅配置Nginx(适合生产场景,性能更高)
- 删除Express代码中所有cors中间件相关配置,不需要在Node层处理跨域
- 修改
api.mywebsite.com对应的Nginx配置为如下内容:
server { listen 80; server_name api.mywebsite.com; # 处理OPTIONS预检请求 if ($request_method = OPTIONS) { add_header Access-Control-Allow-Origin "https://front.mywebsite.com" always; add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" always; add_header Access-Control-Allow-Headers "Content-Type, Authorization" always; # 不需要携带cookie可以删掉下面这行 add_header Access-Control-Allow-Credentials "true" always; add_header Content-Length 0; add_header Content-Type text/plain; return 204; } # 给普通请求加跨域头,always参数保证非2xx状态码也会返回响应头 add_header Access-Control-Allow-Origin "https://front.mywebsite.com" always; add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" always; add_header Access-Control-Allow-Headers "Content-Type, Authorization" always; # 不需要携带cookie可以删掉下面这行 add_header Access-Control-Allow-Credentials "true" always; location / { proxy_pass http://localhost:5555; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }
- 先执行
nginx -t验证配置无语法错误,再重启Nginx服务,清除Cloudflare缓存后测试即可
Cloudflare相关排查步骤
如果修改配置后依然报错,按以下步骤检查:
- 登录Cloudflare控制台,进入对应域名的「缓存」页面,点击「清除所有缓存」
- 检查「规则」-「转换规则」中有没有修改响应头的规则,不要覆盖CORS相关响应头
- 临时开启Cloudflare「开发模式」,绕过缓存直接访问源站测试,确认源站配置生效后再关闭开发模式即可
内容的提问来源于stack exchange,提问作者Rouissi Iheb
相关产品推荐
相关产品推荐

