WebSocket服務(wù)器返回401后瀏覽器無(wú)反應(yīng)的原因是什么?如何解決?

WebSocket服務(wù)器返回401后瀏覽器無(wú)反應(yīng)的原因是什么?如何解決?

Netty websocket服務(wù)器返回401,瀏覽器無(wú)響應(yīng)的解決策略

在使用Netty構(gòu)建WebSocket服務(wù)器并進(jìn)行Token驗(yàn)證時(shí),如果token無(wú)效,服務(wù)器返回401狀態(tài)碼并關(guān)閉連接,瀏覽器卻可能無(wú)任何反應(yīng)。本文分析此問(wèn)題并提供解決方案。

問(wèn)題描述

使用Netty開(kāi)發(fā)WebSocket服務(wù)器,需要驗(yàn)證token。token驗(yàn)證失敗時(shí),服務(wù)器返回401并關(guān)閉連接,但瀏覽器沒(méi)有響應(yīng),前端無(wú)法得知連接關(guān)閉原因。 服務(wù)器端代碼示例:

private void httpResponse401(ChannelHandlerContext ctx, FullHttpRequest request) {     FullHttpResponse response = new DefaultFullHttpResponse(request.protocolVersion(), HttpResponseStatus.UNAUTHORIZED);     response.headers().set(HttpHeaderNames.CONTENT_LENGTH, 0);     ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);     ReferenceCountUtil.release(request); }

前端JavaScript代碼:

var socket = new WebSocket("ws://127.0.0.1:18080/ws?token=xxxx");

服務(wù)器雖然返回401并關(guān)閉連接,但瀏覽器卻沒(méi)有任何反應(yīng)。

解決方案

瀏覽器無(wú)響應(yīng)是因?yàn)?01響應(yīng)在WebSocket握手階段被忽略了。 我們需要在握手階段或連接建立后進(jìn)行處理。

方案一:在握手階段返回401響應(yīng)

在WebSocket握手階段(HTTP請(qǐng)求階段),token驗(yàn)證失敗則直接返回HTTP 401響應(yīng),避免建立WebSocket連接。 修改服務(wù)器端代碼:

if (!validateToken(request)) {     FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.UNAUTHORIZED);     response.headers().set(HttpHeaderNames.CONTENT_TYPE, "text/plain; charset=utf-8");     response.headers().set(HttpHeaderNames.CONTENT_LENGTH, response.content().readableBytes());     ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);     return; }

方案二:連接建立后發(fā)送自定義消息

如果需要在WebSocket連接建立后再處理401,可以在連接建立后立即發(fā)送自定義消息通知前端。 在Netty的WebSocketServerProtocolHandler中添加自定義處理器

channel.pipeline().addLast(new WebSocketServerProtocolHandler("/ws") {     @Override     public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {         if (evt == WebSocketServerProtocolHandler.ServerHandshakeStateEvent.HANDSHAKE_COMPLETE) {             if (!validateToken()) {                 ctx.writeAndFlush(new TextWebSocketFrame("401 Unauthorized")).addListener(ChannelFutureListener.CLOSE);             }         }         super.userEventTriggered(ctx, evt);     } });

前端JavaScript代碼需要監(jiān)聽(tīng)onmessage事件

socket.onmessage = function(event) {     if (event.data === "401 Unauthorized") {         console.log("連接關(guān)閉,原因:401 Unauthorized");         socket.close();     } };

通過(guò)以上方法,瀏覽器就能正確處理401狀態(tài)碼,前端也能收到相應(yīng)的反饋信息,從而解決瀏覽器無(wú)響應(yīng)的問(wèn)題。 選擇哪種方案取決于具體的應(yīng)用場(chǎng)景和需求。

? 版權(quán)聲明
THE END
喜歡就支持一下吧
點(diǎn)贊14 分享
站長(zhǎng)的頭像-小浪學(xué)習(xí)網(wǎng)月度會(huì)員