前端使用axios如何调用uWebSockets的HTTP路由?非GET路由无响应求助
非GET类HTTP请求无响应的原因与修复方案
前端请求端的错误点
- 协议头使用错误:你在axios请求中使用了
wss://作为URL开头,该协议是WebSocket连接专属标识,axios检测到wss协议后会直接走WebSocket连接初始化逻辑,根本不会触发普通HTTP方法(PUT/POST/PATCH/DELETE)的请求发送流程,自然无法命中服务端的对应路由。普通HTTP请求需要根据部署场景使用http://或https://作为协议前缀。 - 请求头配置错误:你在客户端请求头中加入了
Access-Control-Allow-Origin字段,该字段是服务端返回给浏览器的CORS响应头,不属于客户端可携带的请求头字段,错误添加会触发浏览器的CORS预检拦截,导致请求直接被前置拦截,无法发送到服务端。
服务端uWebSockets配置的问题
- 路由匹配冲突:你将WebSocket服务的匹配路径设为了空字符串、
*、/*这类通配规则,根据uWebSockets的路由优先级规则,通配路径的匹配优先级高于具体路径的HTTP路由,只要请求命中了WebSocket的通配规则,所有请求都会被WebSocket服务接管,根本不会走到你定义的.put/.post等HTTP路由逻辑里。你使用的18.04版本uWebSockets.js对这类静默拦截没有额外告警,这也是你调试时没有发现路由被抢占的核心原因。正确的做法是将WebSocket的监听路径收敛为固定的专属路径(如/ws),避免通配规则拦截其他普通HTTP路径的请求。 - 响应流程缺失:你在各HTTP路由的逻辑中只添加了日志打印,没有主动调用
res.end()方法给客户端返回响应。uWebSockets不会自动为未手动结束的请求返回200响应,只要服务端不主动结束连接,客户端就会一直等待响应,表现为请求超时、无返回结果。另外对于带请求体的PUT/POST类请求,必须通过res.onData事件手动接收请求体内容,否则也会导致请求流程挂起。 - 路由注册顺序不影响最终匹配结果:你之前尝试将HTTP路由放在
.ws()方法前后都没生效,本质原因还是通配的WebSocket路径优先级更高,不是代码书写顺序的问题。
修正后的参考代码
服务端配置
const uWS = require('uWebSockets.js'); const SOCKET_PORT = 3023; const app = uWS.App() .put('/route1', (req, res) => { // 接收完整请求体 let requestBody = Buffer.alloc(0); res.onData((chunk, isLast) => { requestBody = Buffer.concat([requestBody, Buffer.from(chunk)]); if (isLast) { console.log('收到/route1请求,请求内容:', requestBody.toString()); // 必须手动结束响应 res.end('{"code":0, "msg":"success"}'); } }) }) .patch('/route2', (req, res) => { res.end('{"code":0, "msg":"success"}'); }) .post('/route3', (req, res) => { res.end('{"code":0, "msg":"success"}'); }) .delete('/route4', (req, res) => { res.end('{"code":0, "msg":"success"}'); }) // 将WebSocket路径固定为/ws,避免通配拦截 .ws('/ws', { compression: uWS.SHARED_COMPRESSOR, idleTimeout: 30, maxBackpressure: 1024, maxPayloadLength: 512, open: ws => ws.subscribe('all') }); app.listen(SOCKET_PORT, (listenSocket) => { if (listenSocket) console.log(`Listening to port ${SOCKET_PORT}`); });
前端请求代码
// 移除客户端配置的Access-Control-Allow-Origin字段 const headers = { "Content-Type": "application/json", "key": "test_key" }; const serverResponse = await axios({ method: "PUT", // 替换为https协议前缀,去掉wss标识 url: "https://subdomain.domain.xyz/route1", data: { "val1": "test", "val2": 5 }, headers }) .then(res => res.data) .catch(err => err.response?.data);
内容的提问来源于stack exchange,提问作者DIIMIIM
相关产品推荐
相关产品推荐

