修改Nginx处理Open WebUI的WebSocket连接失败问题
问题背景
笔者近期在本地部署了Open WebUI,并通过Nginx反向代理将服务暴露到公网。部署完成后,前端页面出现以下关键报错:
浏览器控制台报错(已脱敏处理):
javascript
WebSocket connection to 'ws://app.example.com/ws/socket.io/?EIO=4&transport=websocket' failed:
doOpen @ websocket.js:43
(anonymous) @ transport.js:46
connect_error @ socket.js:170
xe: websocket error
at Ie.onError (http://app.example.com/_app/chunks/index.abc123.js:1:6173)
at ws.onerror (http://app.example.com/_app/chunks/index.abc123.js:1:12730)
关键现象:
普通HTTP请求(如页面加载、API调用)正常
WebSocket握手阶段直接失败,状态码非101 Switching Protocols
控制台明确提示Upgrade头未正确处理
问题定位过程
1. 通过浏览器开发者工具排查
按下 F12 打开调试工具,按以下路径分析:
Network → WS 筛选器 → 查看WebSocket请求
目标地址:ws://app.example.com/ws/socket.io/...
状态码:(failed),无具体HTTP响应码
错误详情:Error during WebSocket handshake: Unexpected response code: 200
Console 面板 → 捕获到connect_error事件,提示协议升级失败
2. Nginx配置初步检查
原始Nginx配置如下:
nginx
server {
listen 80;
server_name app.example.com; # 实际域名已脱敏
location / {
proxy_pass http://localhost:7034;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
发现问题:
缺失WebSocket必需的Upgrade和Connection头处理
未强制使用HTTP/1.1协议
完整解决方案
1. 修改后的Nginx配置
server {
listen 80;
server_name app.example.com; # 示例域名,实际需替换
location / {
proxy_pass http://localhost:7034;
# 基础代理标头
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_set_header X-Forwarded-Proto $scheme;
# WebSocket核心配置
proxy_http_version 1.1; # 强制HTTP/1.1协议
proxy_set_header Upgrade $http_upgrade; # 传递协议升级请求
proxy_set_header Connection "upgrade"; # 保持长连接
# 长连接超时优化(适合Open WebUI高频交互场景)
proxy_read_timeout 7d; # 7天无操作断开
proxy_send_timeout 7d;
}
}
2. 配置生效命令
sudo nginx -t # 验证语法
sudo nginx -s reload # 热重载配置
核心配置解析
配置指令 | 功能描述 | 必要性 |
---|---|---|
proxy_http_version 1.1 | 强制使用HTTP/1.1协议 | 必需 |
proxy_set_header Upgrade | 转发协议升级请求 | 必需 |
proxy_set_header Connection | 保持长连接状态 | 必需 |