Nginx代理WebSocket失敗的完整排查過程
問題現(xiàn)象
- 后端服務運行在
192.168.1.10:8080,提供 WebSocket 接口/ws/xxx - 使用
wscat或瀏覽器直連ws://192.168.1.10:8080/ws/xxx? 成功 - 配置 Nginx 反向代理后,前端連接
ws://localhost/ws/xxx? 失敗 - 瀏覽器 Network 面板顯示 WebSocket 請求失?。o 101 響應)
- 關鍵線索:Nginx 的
access_log中 沒有任何 WebSocket 請求日志
初步懷疑:Nginx 配置錯誤?
首先檢查 Nginx 配置:
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
upstream webservers {
server 192.168.1.10:8080;
}
server {
listen 80;
server_name localhost;
location /ws/ {
proxy_pass http://webservers/ws/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "$connection_upgrade"; # ?? 這里有坑!
proxy_read_timeout 3600s;
}
}
常見錯誤包括:
Connection頭加了雙引號 → 變成字面量map沒放在http塊頂層- 缺少
proxy_buffering off
但即使修正這些,日志依然為空,說明:請求根本沒到 Nginx!
關鍵轉折:前端頁面來源被忽略
通過 docker ps 確認端口映射正常:
nginx 0.0.0.0:80->80/tcp
但發(fā)現(xiàn)一個致命細節(jié):
前端頁面是通過虛擬機 IP 打開的:http://192.168.228.128/
而 WebSocket 地址寫的是:ws://localhost/ws/xxx
問題本質
- 瀏覽器中的
localhost永遠指向客戶端本機(Windows 電腦) - 而我的 Nginx 運行在 虛擬機中
- 所以
ws://localhost/...實際請求的是 我 Windows 的 80 端口,而非虛擬機!
→ 請求壓根沒發(fā)給 Nginx,自然沒有日志!
解決方案
方法 1:顯式指定虛擬機 IP(臨時可用)
// 前端 JS
const ws = new WebSocket('ws://192.168.228.128/ws/xxx');
立即生效!
方法 2:使用相對路徑(推薦 ?)
// 自動繼承當前頁面的 host
const ws = new WebSocket('/ws/xxx');
優(yōu)勢:
- 頁面在
http://localhost→ 連ws://localhost - 頁面在
http://192.168.228.128→ 連ws://192.168.228.128 - 部署到域名也無需修改代碼
附:正確的 Nginx 配置模板
http {
# 必須在 http 塊頂層!
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
upstream backend {
server host.docker.internal:8080; # Docker Desktop 推薦
# 或 server 192.168.1.10:8080;
}
server {
listen 80;
server_name _; # 匹配任意 Host
location / {
root /usr/share/nginx/html;
index index.html;
}
location /ws/ {
access_log /var/log/nginx/ws_access.log;
proxy_pass http://backend/ws/;
proxy_http_version 1.1;
proxy_buffering off; # 必須關閉
proxy_cache off;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade; # 無引號!
proxy_read_timeout 3600s;
}
}
}
經(jīng)驗總結
| 問題類型 | 排查要點 |
|---|---|
| Nginx 無日志 | 先確認請求是否真的發(fā)到了 Nginx(檢查前端地址、端口映射) |
| WebSocket 426 | 檢查 Upgrade 和 Connection 頭是否正確傳遞 |
| 前端連接失敗 | 確保 WebSocket 地址與頁面同源(避免硬編碼 localhost) |
| Docker 環(huán)境 | 用 host.docker.internal 代替 IP 更可靠 |
最后提醒
localhost 在前端代碼中 ≠ 你的服務器!
它永遠指向用戶瀏覽器所在的機器。
開發(fā)時務必注意頁面來源與 WebSocket 目標的匹配關系,這是 WebSocket 代理失敗的最高頻原因。
結語
從“426 Upgrade Required”到“連接成功”,看似是配置問題,實則是網(wǎng)絡拓撲理解偏差。希望本文能幫你少走彎路!
到此這篇關于Nginx代理WebSocket失敗的完整排查過程的文章就介紹到這了,更多相關Nginx代理WebSocket失敗內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
通過Nginx的proxy_set_header設置請求頭無效的解決
這篇文章主要介紹了通過Nginx的proxy_set_header設置請求頭無效的解決,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-12-12
WordPress與Drupal的Nginx配置rewrite重寫規(guī)則示例
這篇文章主要介紹了WordPress與Drupal的Nginx配置重寫規(guī)則示例,文中介紹的rewrite寫法簡單而突出配置重點,需要的朋友可以參考下2016-01-01
nginx啟動服務提示98: Address already in use錯誤的解決
這篇文章主要給大家介紹了nginx啟動服務提示98: Address already in use錯誤的解決方法,文中介紹的非常詳細,對大家具有一定的參考學習價值,需要的朋友們下面來一起看看吧。2017-05-05
18個運維必知的Nginx代理緩存配置技巧(你都掌握了哪些呢)
這篇文章主要介紹了18個運維必知的Nginx代理緩存配置技巧(你都掌握了哪些呢),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2019-09-09
nginx中配置https的詳細步驟及配置SSL/TLS證書的完整流程
本文將詳細介紹如何在 Nginx 服務器上配置 SSL/TLS 證書,包括獲取證書、配置 Nginx、強化安全性等完整流程,無論您是使用 Let’s Encrypt 的免費證書還是自簽名證書,都能在本指南中找到對應的配置方法,感興趣的朋友跟隨小編一起看看吧2025-10-10
Ubuntu16.04上為Nginx創(chuàng)建自簽名SSL證書
SSL證書是實現(xiàn)HTTPS的關鍵組成部分,本文主要介紹了Ubuntu16.04上為Nginx創(chuàng)建自簽名SSL證書,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2024-05-05

