我有一个Nginx服务器块,它将请求代理到node.js服务器。此服务器同时提供HTTP内容和WS(websocket(内容。在不应该升级到websocket连接的请求上添加升级头可以吗?
即使用Nginx代理到为HTTP和WS服务的Node.js服务器,使用单独的服务器块是否是一种好的做法?
这是我的Nginx服务器块当前:
server {
listen 443 ssl;
listen [::]:443;
server_name api.mysite.com;
ssl_certificate ...;
ssl_certificate_key ...;
ssl_dhparam ...;
ssl_protocols ...;
ssl_prefer_server_ciphers on;
ssl_ciphers ...;
location / {
proxy_pass http://localhost:5000;
proxy_buffering off;
proxy_redirect off;
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-Host $server_name;
proxy_set_header Access-Control-Allow-Origin *;
}
}
看起来我总是在代理到Node.js服务器的请求中添加Upgrade
和Connection
头,即使我不想升级:
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
第一行看起来像是将请求传递的"Upgrade"标头设置为$http_Upgrade。我假设,如果请求中没有传递此标头,那么"Upgrade"将被设置为null
(或等效值(,这将无效。这是正确的吗?
我发现它在实践中也很好用,尽管至少有一个用户对此有问题
此行:
proxy_set_header Upgrade $http_upgrade;
实际上是在做你想做的事情,因为$http_upgrade
来自客户端发送的头。因此,如果客户端没有请求升级,它就不会被传递。
出于某种原因,似乎没有等效的$http_connection
变量,但您可以使用map
创建一个,这是官方解决方案:
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
...
location /chat/ {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
}
}
什么都没发生。很好。我使用相同的nginx块来代理一个graphqlhttp端点和一个ws端点。