记录一个用 nginx
配置 websocket
和跨域的问题。
配置 websocket
反向代理
WebSocket
应用程序可以在客户端和服务端保持长连接,实现实时通信。并且 WebSocket
协议的握手与 HTTP
协议兼容,所以可以通过 HTTP
服务器代理 WebSocket
请求。
所以一开始的配置是直接基于 Nginx
的 443
端口,使用 proxy_pass
代理 WebSocket
请求。
1 | server{ |
出于业务的需求,在原本的服务器块里加上一个新的 location
块,用于代理 WebSocket
请求。第一行的 location /service
是代理的路径,proxy_pass
后面的地址是 WebSocket
服务的地址。
然后设置 proxy_http_version
为 1.1
,proxy_buffering
为 off
,proxy_set_header Upgrade $http_upgrade
和 proxy_set_header Connection "upgrade"
是为了让 WebSocket
协议生效。
解决跨域问题
在配置 WebSocket
代理的时候,发现 WebSocket
连接失败,控制台报错 WebSocket connection to 'ws://xxx' failed: Error during WebSocket handshake: Unexpected response code: 403
。直接访问 WebSocket
服务的地址是可以正常连接的,走 443
端口的代理和走 80
端口的代理到 WebSocket
服务的地址都会出现这个问题。看了一下 Nginx
的日志,发现是被代理的服务端返回了 403
错误。对比了一下直接访问和代理访问的请求头,发现了一个问题,Origin
请求头和 Host
请求头不一样。判断大概率是后端服务做了跨域限制,所以需要在 Nginx
配置中加上跨域的配置。
在 location
块中加上 proxy_set_header Origin http://localhost:9090;
,将 Origin
请求头设置为 http://localhost:9090
,这样就可以解决问题了。
1 | server{ |