Nginx 反向代理配置踩坑记录:WebSocket、CORS 和超时问题

Nginx Reverse Proxy Pitfalls: WebSocket, CORS and Timeout Issues

| David | 2026-08-26T18:04:12

记录一下最近在配置 Nginx 反向代理时遇到的几个坑,包括 WebSocket 断连、CORS 重复头和大文件上传超时的问题。

Documenting common Nginx reverse proxy issues including WebSocket disconnects, duplicate CORS headers, and large file upload timeouts.

Nginx 反向代理看起来简单,但实际配置中总有各种意想不到的坑。最近集中遇到了好几个,记录一下。 坑一:WebSocket 连接过一分钟就断 我们的在线客服系统用了 WebSocket,配完 Nginx 反代之后发现连接过大概 60 秒就会自动断开。原因是 Nginx 默认的 proxy_read_timeout 是 60 秒,WebSocket 空闲超过这个时间就会被 Nginx 关闭。 解决方案: location /ws/ { proxy_pass http://backend; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_read_timeout 3600s; # 改成 1 小时 proxy_send_timeout 3600s; } 另外在应用层也加了心跳包,每 30 秒 ping 一次,双保险。 坑二:CORS 头重复了 后端 Spring Boot 已经配了 CORS,Nginx 里又配了一次,导致浏览器收到了两个 Access-Control-Allow-Origin 头,反而报错了。 这个问题挺隐蔽的,浏览器控制台会报: Access to XMLHttpRequest has been blocked by CORS policy: The 'Access-Control-Allow-Origin' header contains multiple values 解决方案:只在一个地方配 CORS,我们选择了在后端配,Nginx 只做转发不加 CORS 头。 坑三:大文件上传 413 用户上传超过 1MB 的图片就报 413 Request Entity Too Large。Nginx 默认 client_max_body_size 是 1MB。 http { client_max_body_size 20m; # 根据业务需要设置 # 如果文件很大,还需要调整这些 proxy_connect_timeout 300s; proxy_read_timeout 300s; proxy_send_timeout 300s; } 坑四:后端拿不到真实 IP 经过 Nginx 反代后,后端拿到的客户端 IP 全是 127.0.0.1。需要在 Nginx 里传递真实 IP: location /api/ { proxy_pass http://backend; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header Host $host; } 后端 Spring Boot 里也要配置信任代理: server: forward-headers-strategy: framework 总结 Nginx 配置最怕"看起来能用",很多问题是在特定场景下才会暴露的。建议每次改完配置都用 nginx -t 检查语法,然后实际测试一下 WebSocket、文件上传、CORS 这些容易出问题的场景。


Nginx reverse proxy looks simple but has many hidden pitfalls. Here are common issues and solutions. WebSocket Disconnects After 60s Default proxy_read_timeout is 60s. Set to 3600s for WebSocket connections and add application-level heartbeats. Duplicate CORS Headers If both Nginx and backend set CORS headers, browsers reject the response. Configure CORS in only one place. 413 on File Upload Default client_max_body_size is 1MB. Increase it and adjust proxy timeouts for large files. Lost Client IP Pass X-Real-IP and X-Forwarded-For headers, and configure Spring Boot to trust the proxy.

← Back to News