手写HTTP服务301重定向在Brave浏览器无法正常跳转问题
问题原因
Brave是Chromium内核浏览器,对HTTP/1.1协议规范的校验比Firefox严格,你手写的重定向响应存在不符合规范的问题,导致浏览器解析Location头失败,误判为自定义协议唤起请求,才会弹出xdg-open调用提示:
- HTTP/1.1默认启用长连接,你返回的响应没有携带
Content-Length头明确响应体长度,也没有Connection: close头告知浏览器连接即将关闭,浏览器会认为响应不完整,无法正确解析重定向地址。 - 响应头结束后你多写了一组
\r\n,相当于在响应体里插入了多余的空行,和实际响应长度不匹配;写完响应后直接暴力关闭Socket会发送TCP RST包,打断浏览器的响应解析流程,进一步导致解析失败。
修改方案
补全必要的HTTP响应头,修正响应格式,调整连接关闭逻辑即可,核心修改点:
- 增加
Content-Length: 0头,明确告知浏览器该响应没有响应体 - 增加
Connection: close头,明确告知浏览器请求处理完成后直接关闭连接,无需复用长连接 - 增加
Content-Type头避免浏览器做多余的内容嗅探 - 去掉多余的空行,响应头结束只需要保留一组
\r\n作为头和体的分隔符 - 先关闭输出流再关闭Socket,避免发送RST包打断解析
修改后的核心示例代码:
OutputStream os = clientSocket.getOutputStream(); os.write("HTTP/1.1 301 Moved Permanently\r\n".getBytes()); os.write("Location: http://www.google.com/\r\n".getBytes()); os.write("Content-Length: 0\r\n".getBytes()); os.write("Connection: close\r\n".getBytes()); os.write("Content-Type: text/plain\r\n".getBytes()); os.write("\r\n".getBytes()); os.flush(); os.close(); clientSocket.close();
额外注意事项
回写响应前请先读完客户端Socket输入流里的完整请求头(读取到\r\n\r\n标识即代表请求头结束),不要在客户端还没发送完请求头的时候就提前回写响应,否则部分版本的Chromium内核浏览器会判定响应无效。如果是POST等带请求体的请求,不需要读取完整请求体,读完请求头就可以回写重定向响应。
内容的提问来源于stack exchange,提问作者l2poca
相关产品推荐
相关产品推荐

