Webpack Dev Server的WebSocket代理失效,配置问题排查求助
问题分析与修复方案
咱们先从你抛出的错误说起:WebSocket connection to 'ws://api2/someSocket' failed: Error in connection establishment: net::ERR_NAME_NOT_RESOLVED —— 这个错误本质是api2这个域名浏览器找不到,说明你前端代码里的WebSocket请求地址写错了,应该指向webpack-dev-server的地址(比如ws://localhost:3000/someSocket),而不是莫名其妙的api2。
再看你的devServer proxy配置,还有俩关键问题:
1. WebSocket代理的path配置完全错了
webpack-dev-server的proxy里,path是用来匹配请求URL的路径部分的,不是写协议的。你写path: 'ws://'完全不符合规则,proxy根本识别不了这是要转发WebSocket请求。
2. 没正确区分WebSocket和HTTP请求的转发规则
你需要明确告诉proxy,哪些请求要走WebSocket转发,哪些走HTTP。
给你俩修正后的配置方案,选一个用就行
方案一:精准区分WebSocket和HTTP请求
这种方式更清晰,不会混淆两种请求:
devServer: {
contentBase: path.join(__dirname, 'dist'),
port: 3000,
hot: false,
inline: false,
historyApiFallback: true,
proxy: [
{
// 专门匹配WebSocket请求:通过请求头的upgrade字段判断
context: (pathname, req) => req.headers.upgrade === 'websocket',
target: 'ws://localhost:9000',
ws: true,
secure: false,
},
{
// 剩下的都是HTTP请求
context: (pathname, req) => req.headers.upgrade !== 'websocket',
target: 'http://localhost:9000',
secure: false,
changeOrigin: true,
},
]
}
方案二:简洁版,自动处理WebSocket
如果你的所有请求(包括WebSocket)都要转发到同一个后端,直接开启ws: true就行,webpack会自动识别WebSocket请求:
devServer: {
contentBase: path.join(__dirname, 'dist'),
port: 3000,
hot: false,
inline: false,
historyApiFallback: true,
proxy: {
'/': {
target: 'http://localhost:9000',
secure: false,
changeOrigin: true,
ws: true, // 开启这个,自动处理WebSocket的upgrade请求
}
}
}
最后别忘了改前端的请求地址
把你前端代码里的WebSocket请求改成指向devServer的端口,比如:
// 要么写完整地址
const socket = new WebSocket('ws://localhost:3000/someSocket');
// 要么用相对路径(推荐,部署时不用改)
const socket = new WebSocket('/someSocket');
这样请求会被devServer捕获,然后通过proxy转发到后端的9000端口的WebSocket服务,就不会再出现域名解析失败的问题了。
内容的提问来源于stack exchange,提问作者user3712353




