同一VPS部署前后端遭遇CORS问题,求解决方案
问题说明
部署环境
- Golang后端:Docker容器运行,暴露
127.0.0.1:6060提供REST API - Svelte前端:Node.js进程运行在
127.0.0.1:3000 - Nginx反向代理,通过Certbot配置HTTPS,域名
https://example.com已正常解析并可访问前端
当前配置与报错
- 前端通过
fetch()调用https://127.0.0.1:6060/api/v1/whatever,浏览器报错:Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://127.0.0.1:6060/api/v1/me. (Reason: CORS request did not succeed). Status code: (null). - Golang后端CORS配置存在拼写错误,且误用autocert在内部端口启用HTTPS;尝试过宽松Nginx CORS配置无效。
核心问题分析
- 证书不匹配:autocert生成的证书仅对应
example.com,前端请求127.0.0.1:6060时浏览器会因证书域名不匹配拦截请求。 - CORS配置错误:后端
Access-Control-Allow-Origin值拼写错误(https:example.com缺少双斜杠)。 - 请求路径不合理:前端直接访问回环地址,违背HTTPS页面的安全策略,且无需在内部服务重复配置HTTPS。
解决方案
步骤1:修正Golang后端配置
- 修复CORS的Origin拼写错误,去掉autocert配置,改用HTTP监听回环端口:
// CORS中间件修正 headers.Add("Access-Control-Allow-Credentials", "true") // 修正Origin的双斜杠 headers.Add("Access-Control-Allow-Origin", "https://example.com") headers.Add("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE") if req.Method != http.MethodOptions { next.ServeHTTP(rw, req) return } // 处理OPTIONS预检请求 headers.Add("Access-Control-Allow-Headers", "content-type, allow-credentials")
// 后端HTTP服务器配置 server := &http.Server{ Addr: "127.0.0.1:6060", // 仅监听回环地址的HTTP端口 WriteTimeout: time.Second * 15, ReadTimeout: time.Second * 15, IdleTimeout: time.Second * 60, Handler: routerWithCORS, }
步骤2:更新Nginx配置
在现有server块中新增API代理规则,统一由Nginx处理HTTPS:
server { server_name example.com www.example.com; # 前端页面代理 location / { proxy_pass http://localhost:3000/; 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; } # API接口代理 location /api { proxy_pass http://localhost:6060/api; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } # Certbot自动生成的HTTPS配置(保留) listen [::]:443 ssl ipv6only=on; # managed by Certbot listen 443 ssl; # managed by Certbot ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # managed by Certbot include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot } # HTTP跳转HTTPS配置(保留Certbot生成的内容) server { if ($host = www.example.com) { return 301 https://$host$request_uri; } # managed by Certbot if ($host = example.com) { return 301 https://$host$request_uri; } # managed by Certbot listen 80; listen [::]:80; server_name example.com www.example.com; return 404; # managed by Certbot }
步骤3:修改前端请求地址
将API请求路径从https://127.0.0.1:6060/api/v1/whatever改为相对路径/api/v1/whatever,自动走当前域名的HTTPS路由。
步骤4:重启服务
- 重启Golang后端容器
- 重启Nginx:
sudo systemctl restart nginx - 清除浏览器缓存后测试请求
内容的提问来源于stack exchange,提问作者Toni Latenz
相关产品推荐
相关产品推荐

