Python Flask聊天应用:实现消息无刷新自动更新求助
Flask聊天应用实现无刷新消息自动更新求助
我正在用Python Flask开发一款聊天应用,需要实现无需刷新页面就能自动接收新消息的功能,之前尝试用Ajax但没成功。以下是我目前的代码:
Python后端代码
from flask import Flask, render_template, request, url_for, redirect, make_response app = Flask(__name__) messages = [] @app.route('/log-in', methods=['GET', 'POST']) def log_in(): if request.method == 'POST': username = request.form['username'] resp = make_response(redirect(url_for('index'))) resp.set_cookie('username', username) return resp return render_template('log_in.html') @app.route('/', methods=['GET', 'POST']) def index(): username = request.cookies.get('username') if username is None: return redirect(url_for('log_in')) if request.method == 'POST': message = request.form['message'] messages.append({'message': message, 'username': username}) return redirect(url_for('index')) return render_template('index.html', messages=messages, username=username) if __name__ == '__main__': app.run(host='0.0.0.0', port=81)
Jinja前端模板(index.html)
<!DOCTYPE html> <html> <head> <title>Chat App</title> </head> <body> <h1>Chat App - welcome {{ username }}</h1> <div id="chat"> {% for message in messages %} <p><strong>{{ message.username }}:</strong> {{ message.message }}</p> {% endfor %} </div> <form method="POST"> <input type="text" name="message" placeholder="Enter your message" required> <button type="submit">Send</button> </form> </body> </html>
解决方案:API接口+Ajax轮询实现无刷新更新
要实现无刷新收发消息,需对前后端做以下改造:
1. 改造后端,新增消息API接口
给每条消息添加唯一ID用于追踪新消息,同时新增两个API接口:一个处理消息发送,一个返回最新消息:
from flask import Flask, render_template, request, url_for, redirect, make_response, jsonify import uuid app = Flask(__name__) messages = [] @app.route('/log-in', methods=['GET', 'POST']) def log_in(): if request.method == 'POST': username = request.form['username'] resp = make_response(redirect(url_for('index'))) resp.set_cookie('username', username) return resp return render_template('log_in.html') @app.route('/', methods=['GET']) def index(): username = request.cookies.get('username') if username is None: return redirect(url_for('log_in')) return render_template('index.html', messages=messages, username=username) # 新增:发送消息的API接口 @app.route('/api/send-message', methods=['POST']) def send_message(): username = request.cookies.get('username') if not username: return jsonify({'success': False, 'error': '未登录'}) message = request.json.get('message') if message: messages.append({ 'id': str(uuid.uuid4()), 'message': message, 'username': username }) return jsonify({'success': True}) return jsonify({'success': False, 'error': '消息为空'}) # 新增:获取最新消息的API接口 @app.route('/api/get-messages', methods=['GET']) def get_messages(): last_id = request.args.get('last_id') if not last_id: return jsonify({'messages': messages}) # 仅返回last_id之后的新消息 new_messages = [msg for msg in messages if msg['id'] > last_id] return jsonify({'messages': new_messages}) if __name__ == '__main__': app.run(host='0.0.0.0', port=81, debug=True)
2. 修改前端,用Ajax处理收发逻辑
修改index.html,添加JavaScript代码,实现无刷新发送消息和定时获取新消息:
<!DOCTYPE html> <html> <head> <title>Chat App</title> <script src="https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js"></script> </head> <body> <h1>Chat App - welcome {{ username }}</h1> <div id="chat"> {% for message in messages %} <p data-message-id="{{ message.id }}"><strong>{{ message.username }}:</strong> {{ message.message }}</p> {% endfor %} </div> <form id="message-form"> <input type="text" id="message-input" placeholder="Enter your message" required> <button type="submit">Send</button> </form> <script> // 记录最后收到的消息ID let lastMessageId = '{{ messages[-1].id if messages else "" }}'; // 无刷新发送消息 $('#message-form').submit(function(e) { e.preventDefault(); const message = $('#message-input').val().trim(); if (!message) return; $.ajax({ url: '/api/send-message', method: 'POST', contentType: 'application/json', data: JSON.stringify({ message: message }), success: function() { $('#message-input').val(''); }, error: function() { alert('发送消息失败'); } }); }); // 定时轮询获取新消息(间隔2秒) setInterval(function() { $.ajax({ url: '/api/get-messages', method: 'GET', data: { last_id: lastMessageId }, success: function(response) { if (response.messages.length > 0) { const chatDiv = $('#chat'); response.messages.forEach(function(msg) { chatDiv.append(`<p data-message-id="${msg.id}"><strong>${msg.username}:</strong> ${msg.message}</p>`); lastMessageId = msg.id; }); // 自动滚动到聊天底部 chatDiv.scrollTop(chatDiv[0].scrollHeight); } } }); }, 2000); </script> </body> </html>
补充说明
- 用
uuid生成消息唯一ID,确保能精准筛选未接收的新消息 - 发送消息改用Ajax POST,彻底避免页面跳转
- 定时轮询间隔可根据需求调整(1-5秒均可),如果需要更低延迟的实时推送,可以考虑改用WebSocket方案
内容的提问来源于stack exchange,提问作者Max Liebermann
相关产品推荐
相关产品推荐

