前几天开始测试的时候出现了点问题,项目用到了 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";
-
-
}