Vite 开发代理里的 ws 是什么,什么时候该开
什么是 ws
ws 指的是 WebSocket。
它和普通 HTTP 请求不一样,不是一次请求一次响应,而是浏览器和服务端建立一条持续连接,后续双方都可以持续收发消息。
常见用途:
- 聊天
- 实时通知
- 推送消息
- 开发环境里的热更新(HMR)
proxy 里的 ws: true 是什么意思
在 Vite server.proxy 里:
ts
proxy: {
'/ws': {
target: 'http://xxx.com',
ws: true
}
}
这里的 ws: true 不是"开启 WebSocket 功能",而是:
允许这条代理规则去转发 WebSocket 请求。
也就是这条规则不仅代理 HTTP,也代理 ws。
为什么没开 ws: true,热更新还是正常
因为 Vite 的 HMR WebSocket 是 Vite dev server 自己提供的,不需要你在 proxy 里手动开启。
也就是说:
- 你没开的是 proxy 是否转发 WebSocket
- 不是 Vite 自己有没有 WebSocket
所以即使 proxy 里没写 ws: true:
- 浏览器还是会直接连接本地 5173
- Vite 还是会建立 HMR WebSocket
- 热更新照样正常
一句话:
ws: true只影响代理,不影响 Vite 自己的 HMR。
什么时候该开 ws: true
只有一种情况:
你的业务真的有 WebSocket 接口,需要通过 Vite 代理转发。
例如前端会连接:
/ws/socket.io/websocket
这时候才应该写:
ts
proxy: {
'/ws': {
target: 'ws://backend-server',
changeOrigin: true,
ws: true
}
}
什么时候不该开
下面这些情况一般都不该开:
1. 普通接口代理
比如:
/api/gateway
这些是普通 HTTP 请求,不是 WebSocket,不需要 ws: true。
2. 页面壳代理
比如你只是想:
/xx-ui走子应用/走父应用壳
这本质是页面请求代理,也不需要 ws: true。
3. 大范围兜底代理
比如:
ts
'^/(?!xx-ui|@vite|src|...)'
这种规则范围很大,如果再开 ws: true,很容易把不该代理的 ws 也带进去。
你的场景里为什么会出问题
你的意图是:
/xx-ui走子应用自己/代理到父应用壳/api、/gateway走后端
这个思路本身没问题。
问题出在你用了大范围兜底代理 ,同时开了 ws: true。
这样一来,页面加载后,一些 WebSocket 请求也可能命中这条规则,被转发到 target。
而 Vite 开发环境本身就有一条重要的 WebSocket:HMR 热更新通道。
你这次其实不是业务 ws 出问题,而是:
Vite 的 HMR WebSocket 被代理规则误伤了。
为什么会一直刷新
因为 HMR 依赖这条 ws 连接。
如果它被代理到错误的 target:
- 连接失败
- 不断重连
- 热更新失效
- 页面反复 reload
所以现象就是:
/xx-ui首屏能打开- 但页面停一会儿就开始一直刷新
这说明问题不是首屏 HTML,而是页面起来后 HMR 的 ws 链路坏了。
为什么本地 8080 没问题,线上 target 有问题
不是因为 8080 配对了,而是:
- 本地环境对错误 ws 更宽容
- 线上网关 / nginx / 代理更严格
- 同样的错误配置,线上更容易直接暴露
所以本质上不是"线上有问题",而是:
这条 ws 本来就不该被代理。
正确做法
普通接口单独代理
ts
proxy: {
'/api': {
target: 'https://xxx.com',
changeOrigin: true
},
'/gateway': {
target: 'https://xxx.com',
changeOrigin: true
}
}
只有明确业务 ws 才单独开
ts
proxy: {
'/ws': {
target: 'wss://xxx.com',
changeOrigin: true,
ws: true
}
}
大兜底规则不要开 ws: true
ts
proxy: {
'^/(?!xx-ui(/|$)|@vite/|@id/|@fs/|src/|node_modules/|public/)': {
target: 'http://localhost:8080',
changeOrigin: true
}
}
一句话结论
ws: true= 这条代理规则也处理 WebSocket- 只有明确业务 ws 路径时才开
- 不要给大范围兜底代理开
ws: true - 你这次的问题,本质是 Vite 的 HMR WebSocket 被误代理了