nginx在https环境下代理WebSocket遇到的问题
前几天开始测试的时候出现了点问题,项目用到了WebSocket协议,访问直接抛403,也是,如果是nginx处理WebSocket请求不做点特殊配置就直接返回403,所以就添加了一下nginx代理WebSocket的配置。
nginx代理WebSocket配置
在nginx.conf的http模块添加如下内容
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
域名location
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
配置完以上内容即可正常访问WebSocket,经过测试没有发现问题,http环境下。
启用全站https之后发现的问题
再然后,昨天吧,某汪表示想先开启全站https,然后我就随便搞了个证书,调了一下配置,也就启了全站https,但是启完之后没有做测试,以为没出什么叉子,结果今天下午准备正式对外了,才发现websocket又特么崩了,访问直接返回403,卧槽?怎么崩的?有人改配置了?我看了一下配置文件,没变,还是之前的样子,相关配置也都在。
然而他的后台也抛异常了
SockJS
in a frame because it set multiple 'x-frame-options' headers with conflicting values ('deny, sameorigin'). falling back to 'deny'.
服务端报警告:
o.s.w.s.s.t.h.DefaultSockJsService: Origin check enabled but transport 'jsonp' does not support it.
同时过几秒后 Freemarker 会大量抛出异常
java.lang.IllegalStateException: getOutputStream() has already been called for this response
最后把矛头指向了https,是不是启https才出现的问题,然后又把https的注释掉了,以http的形式访问了一下,返回101,http就木有问题,而https就崩了。
原因:某汪表示原因是因为tomcat没有获取到正确的协议,需要配置nginx将客户端请求的协议和端口也要传给tomcat,所以在域名location添加了以下两行。
proxy_set_header X-Forwarded-Port $Server_port;
proxy_set_header X-Forwarded-Proto $scheme;
Spring Boot 配置文件里也要加上如下配置:
server:
use-forward-headers: true
添加之后重载nginx,再次访问,恢复正常了。
最后,附上完整的域名location配置文件
location / {
proxy_set_header Host $Host;
proxy_pass http://127.0.0.1:8080;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Port $Server_port;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。