两台Nginx反向代理服务器无法同时工作的CORS问题求助
跨域请求交替失败的CORS问题修复方案
问题背景
我部署了两台Nginx服务器,分别作为运行在5000和5001端口的Node.js服务器的反向代理:
- 5000端口服务器处理普通表单上传
- 5001端口服务器处理图片上传
客户端流程:用户填写表单(标题、描述、图片)后,先将图片上传至图片服务器,再将图片URL、标题和描述上传至普通服务器。
问题现象
客户端提交表单时,若图片上传成功则普通服务器上传失败,反之亦然。报错信息如下(触发其中之一):
Access to XMLHttpRequest at 'https://myserver.com/imagev2api/profile-upload-single' from origin 'https://blogs.vercel.app' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
备注:已在两台Node.js服务器中配置了app.use(cors())
现有Nginx配置
图片服务器配置
upstream imageserver.com { server 127.0.0.1:5001; keepalive 600; } server { server_name imageserver.com; error_log /var/www/log/imagserver.com.error; access_log /var/www/log/imagserver.com.access; location / { proxy_pass http://imageserver.com; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; proxy_set_header Host $host; proxy_cache_bypass $http_upgrade; # fastcgi_split_path_info ^(.+\.php)(/.+)$; } listen 443 ssl http2; # managed by Certbot ssl_certificate /etc/letsencrypt/live/linoxcloud.com/fullchain.pem; # managed by Certbot ssl_certificate_key /etc/letsencrypt/live/linoxcloud.com/privkey.pem; # managed by Certbot ssl_protocols TLSv1.2 TLSv1.3 SSLv2 SSLv3; ssl_session_cache shared:SSL:5m; ssl_session_timeout 10m; ssl_session_tickets off; } server { if ($host = imageserver.com) { return 301 https://$host$request_uri; } # managed by Certbot listen 80; server_name imageserver.com; }
普通服务器配置
upstream normalserver.com { server 127.0.0.1:5000; keepalive 600; } server { server_name normalserver.com; error_log /var/www/log/normalserver.com.error; access_log /var/www/log/normalserver.com.access; location / { proxy_pass http://normalserver.com; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; proxy_set_header Host $host; proxy_cache_bypass $http_upgrade; } listen 443 ssl http2; # managed by Certbot ssl_certificate ...; # managed by Certbot ssl_certificate_key ...; # managed by Certbot ssl_protocols TLSv1.2 TLSv1.3 SSLv2 SSLv3; ssl_session_cache shared:SSL:5m; ssl_session_timeout 10m; ssl_session_tickets off; } server { if ($host = normalserver.com) { return 301 https://$host$request_uri; } # managed by Certbot listen 80; server_name normalserver.com; }
修复步骤
1. 完善Nginx的CORS处理配置
在两台Nginx服务器的location /块中添加以下配置,确保正确转发请求头并处理预检请求:
# 转发Origin头到后端Node.js服务,让cors中间件能识别来源 proxy_set_header Origin $http_origin; # 直接处理OPTIONS预检请求,避免转发到后端 if ($request_method = OPTIONS) { add_header Access-Control-Allow-Origin $http_origin; add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS'; add_header Access-Control-Allow-Headers 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization'; add_header Access-Control-Max-Age 1728000; add_header Content-Type 'text/plain; charset=utf-8'; add_header Content-Length 0; return 204; } # 确保所有响应都携带CORS允许头 add_header Access-Control-Allow-Origin $http_origin always; add_header Access-Control-Allow-Credentials true always;
2. 调整Node.js的cors配置(可选)
为了更精准控制,可在Node.js中明确指定允许的来源:
const cors = require('cors'); app.use(cors({ origin: 'https://blogs.vercel.app', // 替换为你的前端域名 credentials: true }));
3. 排查Keepalive连接问题
如果上述配置无效,可暂时注释upstream中的keepalive配置测试,看是否是连接复用导致的头丢失:
upstream imageserver.com { server 127.0.0.1:5001; # keepalive 600; 暂时注释 }
4. 验证配置并重启Nginx
执行以下命令检查配置是否正确,然后重启服务:
nginx -t systemctl restart nginx
内容的提问来源于stack exchange,提问作者adijsad
相关产品推荐
相关产品推荐

