英文:
How to use node on localhost with nginx reverse proxy
问题
我理解的是,在这个设置中,我在本地主机上运行了一个 WebSocket 服务器(node),并使用位于其前面的 Nginx 反向代理来处理握手和持久连接。
我遇到的问题是:
混合内容:页面加载于 HTTPS,但尝试连接到不安全的 WebSocket 端点 'ws://domain.com:8020/'。此请求已被阻止;该端点必须通过 WSS 可用。
未捕获的 DOM 异常:无法构造 'WebSocket':不安全的 WebSocket 连接可能不会在加载了 HTTPS 的页面上启动。
所以,我是否也需要为 WebSocket 获取另一个证书?
以下是 Nginx 配置:
http {
...
upstream websocket {
server 127.0.0.1:8080;
}
server {
listen 8020;
location / {
proxy_pass http://websocket;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $host;
proxy_read_timeout 1d;
proxy_send_timeout 1d;
}
}
server {
listen 80 default_server;
listen [::]:80 default_server;
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
ssl_certificate /location/cert.pem;
ssl_certificate_key /location/cert-key.pem;
root /var/www/html/app;
index index.php index.html index.htm index.nginx-debian.html;
server_name _;
location / {
try_files $uri $uri/ =404;
}
}
}
Node:
const wss = new WebSocketServer({port: 8080})
客户端:
const socket = new WebSocket('wss://domain.com:8020')
需要注意的是,使用 http
时一切正常运行,只是不确定如何使其在 https
下正常工作。
英文:
My understanding is that, in this setup I run a websocket server(node) on localhost and use the Nginx reverse proxy that sits in front of it to handle the handshake and persistent connection.
The problem that I'm facing is:
> Mixed Content: The page at 'domain.com' was loaded over HTTPS,
> but attempted to connect to the insecure WebSocket endpoint
> 'ws://domain.com:8020/'. This request has been blocked; this endpoint
> must be available over WSS.
>
> Uncaught DOMException: Failed to construct 'WebSocket': An insecure
> WebSocket connection may not be initiated from a page loaded over
> HTTPS.
So, do I need to have another certificate for the websocket as well ?
Here is the nginx config:
http {
...
upstream websocket {
server 127.0.0.1:8080;
}
server {
listen 8020;
location / {
proxy_pass http://websocket;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $host;
proxy_read_timeout 1d;
proxy_send_timeout 1d;
}
}
server {
listen 80 default_server;
listen [::]:80 default_server;
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
ssl_certificate /location/cert.pem;
ssl_certificate_key /location/cert-key.pem;
root /var/www/html/app;
# Add index.php to the list if you are using PHP
index index.php index.html index.htm index.nginx-debian.html;
server_name _;
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;
}
}
}
----------------------------------------
Node:
const wss = new WebSocketServer({port: 8080})
Client:
const socket = new WebSocket('ws://domain.com:8020')
Should note that everything works while using http
, just not sure how to make it work with https
.
答案1
得分: 0
发现了,只需将ssl_certificate
和ssl_certificate_key
移到http
块中,在nginx中是这样继承它们的。
还要在js中将ws
更改为wss
。
http {
...
ssl on; # 或者使用 listen ssl on 已经过时
ssl_certificate /location/cert.pem;
ssl_certificate_key /location/cert-key.pem;
...
upstream websocket {
server 127.0.0.1:8080;
}
server {
listen 8020;
location / {
proxy_pass http://websocket;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $host;
proxy_read_timeout 1d;
proxy_send_timeout 1d;
}
}
server {
listen 80 default_server;
listen [::]:80 default_server;
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
root /var/www/html/app;
index index.php index.html index.htm index.nginx-debian.html;
server_name _;
location / {
try_files $uri $uri/ =404;
}
}
}
Node:
const wss = new WebSocketServer({port: 8080})
Client:
const socket = new WebSocket('wss://domain.com:8020')
英文:
Found it, just hat to move the ssl_certificate
and sl_certificate_key
in the http
block, new to nginx but I'm guessing that way they get inherited in both server blocks.
Also change ws
to wss
in js.
http {
...
ssl on; # or use listen ssl on is deprecated
ssl_certificate /location/cert.pem;
sl_certificate_key /location/cert-key.pem;
upstream websocket {
server 127.0.0.1:8080;
}
server {
listen 8020;
location / {
proxy_pass http://websocket;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $host;
proxy_read_timeout 1d;
proxy_send_timeout 1d;
}
}
server {
listen 80 default_server;
listen [::]:80 default_server;
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
root /var/www/html/app;
# Add index.php to the list if you are using PHP
index index.php index.html index.htm index.nginx-debian.html;
server_name _;
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;
}
}
}
----------------------------------------
Node:
const wss = new WebSocketServer({port: 8080})
Client:
const socket = new WebSocket('wss://domain.com:8020')
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论