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

基于HTML/JS/Flask/SQLite3的消息系统异常问题求助

消息系统异常修复方案

异常1:消息无限重复加载

问题根源

长轮询的GET /sendmsg接口每次返回全部历史消息,前端通过$('.chat-area').append(newMessages)重复追加所有消息到聊天区域,导致消息持续堆积、滚动条不断下移。

修复方案

后端修改(增量返回消息)

调整GET接口,支持传递最后已接收消息的ID,仅返回新增消息:

@app.route('/sendmsg', methods=["GET", "POST"])
def sendmsg():
    if 'token' in session:
        with sqlite3.connect('users.db', check_same_thread=False) as db:
            c = db.cursor()
            token = session['token']
            c.execute("SELECT username FROM users WHERE token=?", (token,))
            result = c.fetchone()
            if result:
                username= result[0]  # 优化重复查询逻辑
                if request.method == 'POST':
                    message = request.form['message']
                    if message.strip():
                        db = sqlite3.connect('chat.db', check_same_thread=False)
                        c = db.cursor()
                        c.execute("INSERT INTO messages (username, message) VALUES (?, ?)", (username, message))
                        db.commit()
                        # 获取刚插入消息的ID
                        msg_id = c.lastrowid
                        c.execute("SELECT * FROM messages WHERE id=?", (msg_id,))
                        latest_message = c.fetchone()
                        db.close()
                        return render_template('msg_item.html', username=username, message=latest_message)

                # 处理GET请求,仅返回新增消息
                last_id = request.args.get('last_id', 0, type=int)
                db = sqlite3.connect('chat.db', check_same_thread=False)
                c = db.cursor()
                c.execute("SELECT * FROM messages WHERE id > ? ORDER BY timestamp", (last_id,))
                messages = c.fetchall()
                db.close()
                return render_template('msg_list.html', username=username, messages=messages)

    flash("You need to login first", "error")
    return redirect(url_for("login"))

拆分模板文件

  • msg_item.html(仅渲染单条消息):
<div class="msg-container {% if message[1] == username %}sender{% else %}receiver{% endif %}" data-id="{{ message[0] }}">
  <div class="username">{{ message[1] }}</div>
  <div class="message">{{ message[2] }}</div>
</div>
  • msg_list.html(仅渲染消息列表):
{% for message in messages %}
  <div class="msg-container {% if message[1] == username %}sender{% else %}receiver{% endif %}" data-id="{{ message[0] }}">
    <div class="username">{{ message[1] }}</div>
    <div class="message">{{ message[2] }}</div>
  </div>
{% endfor %}

前端长轮询逻辑修改

记录最后一条消息ID,仅追加新增内容:

let lastMsgId = 0;

function longPoll() {
    $.ajax({
        url: '/sendmsg',
        type: 'GET',
        data: { last_id: lastMsgId },
        timeout: 10000,
        success: function(data) {
            if (data.trim()) {
                $('.chat-area').append(data);
                // 更新最后消息ID
                const lastMsg = $('.chat-area .msg-container').last();
                if (lastMsg.length) {
                    lastMsgId = parseInt(lastMsg.data('id'));
                }
                $('.chat-area').scrollTop($('.chat-area')[0].scrollHeight);
            }
            longPoll();
        },
        error: function() {
            setTimeout(longPoll, 1000); // 出错后延迟重试,避免频繁请求
        }
    });
}

异常2:发送消息后无法继续发送,表单重复显示

问题根源

  1. 表单提交时,刚禁用按钮就立刻启用,未真正锁定按钮,可能触发多次提交
  2. POST请求成功后手动追加消息,与长轮询逻辑重复,可能导致DOM异常

修复方案

调整表单提交逻辑,仅在请求完成后启用按钮,移除重复的消息追加操作:

$('#sendmsg-form').submit(function(event) {
    event.preventDefault();
    const $form = $(this);
    const $button = $form.find('button[type="submit"]');
    const $input = $form.find('input[name="message"]');
    const message = $input.val().trim();
    
    if (!message) return; // 空消息不提交
    
    $button.prop('disabled', true);
    
    $.ajax({
        type: 'POST',
        url: '/sendmsg',
        data: $form.serialize(),
        success: function() {
            $input.val('');
            const isScrolledToBottom = $('.chat-area').scrollTop() + $('.chat-area').outerHeight() >= $('.chat-area')[0].scrollHeight;
            if (isScrolledToBottom) {
                $('.chat-area').scrollTop($('.chat-area')[0].scrollHeight);
            }
        },
        error: function(xhr) {
            console.error(`发送失败: ${xhr.statusText}`);
        },
        complete: function() {
            // 请求完成后再启用按钮
            $button.prop('disabled', false);
        }
    });
});

额外优化提示

  • 确保messages表有自增id主键(这是增量获取消息的基础)
  • 生产环境避免使用check_same_thread=False,建议用SQLite连接池
  • 长轮询可替换为Server-Sent Events,提升实时通信效率

内容的提问来源于stack exchange,提问作者pydal1

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 17:17:26