前端连接websocket服务报错 Unexpected response code: 301
引
websocket后端服务正常,监听正常,可以通过简单的前端代码进行连接,但是通过nginx反向代理后报错Error during WebSocket handshake: Unexpected response code: 301
直连测试
假设我的webosocket服务tcp监听端口为8082,服务端ip为192.168.10.3,通过这个简单的js程序,用浏览器打开,查看控制台,网络中的ws,可以看到是能正常连接的,返回状态码为101.
js
<script>
// 创建一个 WebSocket 实例
const socket = new WebSocket('ws://192.168.10.3:8082/ws');
// 当 WebSocket 打开时,输出信息
socket.addEventListener('open', function (event) {
console.log('WebSocket 连接已打开');
});
// 当接收到消息时,输出数据
socket.addEventListener('message', function (event) {
console.log('收到消息:', event.data);
});
// 当 WebSocket 关闭时,输出信息
socket.addEventListener('close', function (event) {
console.log('WebSocket 连接已关闭');
});
// 当遇到错误时,输出错误信息
socket.addEventListener('error', function (event) {
console.error('WebSocket 出现错误');
});
</script>
301重定向
301 是永久重定向状态码,通常发生在:
-
WebSocket 连接请求的 URL 缺少尾部斜杠
-
Nginx 配置中有重写规则导致 WebSocket 请求被重定向
-
WebSocket 连接尝试使用 HTTP 但服务器期望 HTTPS(或反之)
修改nginx配置
原关于websocket代理配置片段如下
shell
location /ws/ {
proxy_pass http://192.168.10.3:8082/ws;
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;
}
修改如下:
shell
location /ws {
proxy_pass http://192.168.10.3:8082/ws;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header 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_set_header X-Forwarded-Proto $scheme;
# 以下为 WebSocket 特定配置
proxy_read_timeout 60s;
proxy_redirect off;
}
重新加载nginx配置
shell
nginx -s reload
前端页面重新加载后ws连接恢复正常。