Python http.server服务端无法向客户端返回响应问题排查求助
问题根因排查
- 服务端无全局消息存储结构,收到客户端发送的消息后仅打印未存储,其他客户端轮询时无法获取新消息
- 服务端
do_POST方法处理轮询请求(仅带port参数的请求)时,未返回任何消息数据 - 当前服务端使用单线程
HTTPServer,并发轮询场景下会出现阻塞,需替换为ThreadingHTTPServer - 客户端
load回调函数仅打印返回数据,未将收到的消息渲染到聊天区域 - jQuery POST发送JSON数据时未指定
contentType: 'application/json',部分场景下服务端解析会出错 - 服务端响应头Content-Type错误设置为
text/html,应改为application/json匹配返回的JSON格式
修复后代码
Python服务端代码
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer import json # 全局消息队列存储所有聊天消息 message_queue = [] class handler(BaseHTTPRequestHandler): # 禁用默认日志输出,可根据需要开启 def log_message(self, format, *args): return def do_GET(self): self.send_response(200) self.send_header("Access-Control-Allow-Origin", "*") self.send_header('Content-type', 'application/json') self.end_headers() message = {"room4":1,"room5":1,"room6":1} self.wfile.write(json.dumps(message).encode()) def do_POST(self): content_length = int(self.headers['Content-Length']) body = self.rfile.read(content_length) data = json.loads(body.decode()) if content_length else {} self.send_response(200) self.send_header("Access-Control-Allow-Origin", "*") self.send_header('Content-type', 'application/json') self.send_header('Cache-Control', 'no-store') self.end_headers() # 处理发送消息的请求 if "message" in data: # 把消息存到全局队列 message_queue.append({ "content": data["message"], "port": data.get("port", "unknown") }) self.wfile.write(json.dumps({"status": "success"}).encode()) print("收到新消息:", data["message"]) # 处理轮询拉取消息的请求 else: # 返回所有消息,也可以优化为增量返回减少传输量 self.wfile.write(json.dumps({"messages": message_queue}).encode()) if __name__ == "__main__": # 替换为多线程服务端支持并发请求 serv = ThreadingHTTPServer(("localhost", 9889), handler) print("服务端启动,端口9889") serv.serve_forever()
修复后JavaScript代码
$(document).ready(function(){ // 记录当前已加载的消息长度,实现增量更新 let lastMsgLength = 0; load(); var entereddata; $("#submitbtn").click(function(){ var d=new Date() var time = d.toLocaleTimeString(); entereddata=$("#msgarea").val() if(!entereddata.trim()) return; // 空消息不发送 $("#chat").append("<div style='background-color:#dcf8c6;padding:5px 10px; border-radius:5px;margin-bottom:8px;width:fit-content;margin-left:auto;'>"+"你: "+entereddata+"<p class='time-right'> "+time+"</p>"+"</div>") $("#msgarea").val('') // 发送后清空输入框 // 发送时指定contentType为json $.ajax({ url: "http://localhost:9889/", type: 'POST', contentType: 'application/json', data: JSON.stringify({ "message":entereddata, "port":location.port, }) }) // 滚动到聊天底部 $("#chat").scrollTop($("#chat")[0].scrollHeight); }) function load(){ $.ajax({ url: "http://localhost:9889/", type: 'POST', contentType: 'application/json', data: JSON.stringify({ "port":location.port, }), success: function(res){ const messages = res.messages || []; // 仅渲染新收到的消息 for(let i = lastMsgLength; i < messages.length; i++){ const msg = messages[i]; // 跳过自己发的消息,因为发送时已经渲染过了 if(msg.port == location.port) continue; var d=new Date() var time = d.toLocaleTimeString(); $("#chat").append("<div style='background-color:#f1f1f1;padding:5px 10px; border-radius:5px;margin-bottom:8px;width:fit-content;'>"+"对方: "+msg.content+"<p class='time-left'> "+time+"</p>"+"</div>") } // 更新已加载消息长度 lastMsgLength = messages.length; // 滚动到聊天底部 $("#chat").scrollTop($("#chat")[0].scrollHeight); } }) } setInterval(load,1000) })
HTML样式调整
修改原有#chat样式的overflow属性,支持消息滚动:
#chat{ height:88vh; overflow-y: auto; padding: 10px; }
内容的提问来源于stack exchange,提问作者Raj
相关产品推荐
相关产品推荐

