You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 13:47:50