Nginx文件上传无限加载与WebSocket协议切换错误排查
解决Nginx反向代理下文件上传无限加载与WebSocket切换协议错误
问题背景
上传文件时页面无限加载,但文件实际已上传成功;为了让Nginx优先处理静态文件添加try_files $uri @proxy后,WebSocket出现101 Switching Protocol错误。以下是原有配置:
原有/etc/nginx/nginx.conf配置
user www-data; worker_processes auto; pid /run/nginx.pid; include /etc/nginx/modules-enabled/*.conf; events { worker_connections 768; # multi_accept on; } http { ## # Basic Settings ## sendfile on; tcp_nopush on; types_hash_max_size 2048; # server_tokens off; # server_names_hash_bucket_size 64; # server_name_in_redirect off; include /etc/nginx/mime.types; default_type application/octet-stream; ## # SSL Settings ## ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE ssl_prefer_server_ciphers on; ## # Logging Settings ## access_log /var/log/nginx/access.log; error_log /var/log/nginx/error.log; ## # Virtual Host Configs ## include /etc/nginx/conf.d/*.conf; include /etc/nginx/sites-enabled/*; client_max_body_size 128M; proxy_max_temp_file_size 0; proxy_buffering off; server_names_hash_bucket_size 256; }
原有/etc/nginx/sites-available/default配置
server { server_name zizzu.com; listen 80; # We miss all the declarations to make tls happens # But they should be somewhere here root /home/zizzu/Zizzu-API/Public/; # Serve all public/static files via nginx and then fallback to Vapor for the rest location / { proxy_pass http://127.0.0.1:8080; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } client_max_body_size 128M; # Proxy configuration for binding to Vapor port location @proxy { proxy_pass http://127.0.0.1:8080; proxy_pass_header Server; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_pass_header Server; proxy_connect_timeout 3s; proxy_read_timeout 10s; } }
修改location /后触发WebSocket错误的配置片段:
... location / { proxy_pass http://127.0.0.1:8080; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; try_files $uri @proxy; } ...
解决方案
1. 调整/etc/nginx/nginx.conf
在http块中添加WebSocket连接头映射,并延长全局代理超时时间:
http { # ... 保留原有所有配置 ... # 处理WebSocket的Connection头,兼容非WebSocket请求 map $http_upgrade $connection_upgrade { default upgrade; '' close; } # 延长代理读取超时,适配大文件上传 proxy_read_timeout 300s; }
2. 修改/etc/nginx/sites-available/default
拆分静态文件、普通请求和WebSocket请求的代理规则,避免冲突:
server { server_name zizzu.com; listen 80; root /home/zizzu/Zizzu-API/Public/; client_max_body_size 128M; # 优先处理静态文件,找不到再转发到后端服务 location / { try_files $uri @proxy; } # 普通API请求的代理配置 location @proxy { proxy_pass http://127.0.0.1:8080; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_connect_timeout 3s; proxy_read_timeout 300s; # 继承全局超时,确保大文件上传完成 } # 单独配置WebSocket路由(请根据实际WebSocket路径修改/ws) location /ws { proxy_pass http://127.0.0.1:8080; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_read_timeout 86400s; # 保持WebSocket长连接需要的超时时间 } }
关键修改说明
- 文件上传无限加载:原配置中
proxy_read_timeout仅10秒,Nginx会在大文件上传完成前主动断开连接,前端因收不到响应进入无限加载状态,延长超时时间即可解决。 - WebSocket 101错误:之前将WebSocket的协议升级头全局应用到所有请求,加上
try_files后静态文件请求也被带上Upgrade头,导致协议切换逻辑混乱。单独为WebSocket路径配置升级规则,并用$connection_upgrade变量替代固定值,确保只有真实的WebSocket请求触发协议升级。
内容的提问来源于stack exchange,提问作者Artemiy Ziuzin
相关产品推荐
相关产品推荐

