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

插入Unicode字符到SQLite后Python3程序假死问题求助

嘿,这个问题我之前踩过坑!大概率是原生消息通信时的编码和长度计算不匹配导致的Python假死,咱们一步步来解决:

问题核心原因

Firefox和原生程序的原生消息协议有严格的格式要求:

每条消息由「4字节小端无符号整数(表示后续JSON字符串的UTF-8字节数)」 + 「UTF-8编码的JSON字符串」组成

当消息包含西里尔字母这类非ASCII字符时,每个字符会占用2~4个UTF-8字节。如果你的Python代码错误地用字符数代替UTF-8字节数来计算消息长度,就会导致程序一直等待“缺失”的字节,最终表现为假死。

解决方案步骤

1. 修复Python端的消息接收逻辑

确保你是按二进制方式读取stdin,并且正确解析长度前缀:

import struct
import sys
import json

# 切换stdin/stdout为二进制模式(Windows下尤其重要)
sys.stdin = open(sys.stdin.fileno(), 'rb')
sys.stdout = open(sys.stdout.fileno(), 'wb')

def receive_message():
    # 读取4字节的长度前缀(小端无符号整数)
    length_bytes = sys.stdin.read(4)
    if not length_bytes:
        return None
    # 解析长度
    message_length = struct.unpack('<I', length_bytes)[0]
    # 读取对应字节数的消息内容
    message_bytes = sys.stdin.read(message_length)
    # 用UTF-8解码为字符串,再解析JSON
    return json.loads(message_bytes.decode('utf-8'))

# 接收消息循环
while True:
    msg = receive_message()
    if not msg:
        break
    print(f"Received data: {msg}")
    # 执行数据写入SQLite的逻辑
    # ...

2. 确保Python端的响应发送逻辑正确

给Firefox回消息时,同样要遵循协议格式,并且强制刷新输出缓冲区(否则数据可能卡在缓冲区里,导致扩展收不到响应):

def send_response(response_data):
    # 序列化为JSON字符串,再转成UTF-8字节
    response_json = json.dumps(response_data)
    response_bytes = response_json.encode('utf-8')
    # 写入4字节长度前缀
    sys.stdout.write(struct.pack('<I', len(response_bytes)))
    # 写入响应内容
    sys.stdout.write(response_bytes)
    # 必须flush,否则数据不会立即发送
    sys.stdout.flush()

3. 检查Firefox扩展端的发送逻辑

如果你的扩展是手动处理消息编码,一定要确保用UTF-8计算字节长度。不过更推荐直接用browser.runtime.sendNativeMessage传入JavaScript对象——Firefox会自动帮你完成JSON序列化、UTF-8编码和长度前缀的处理:

// 直接传对象即可,Firefox会自动处理编码和长度
browser.runtime.sendNativeMessage('你的原生应用ID', {
    data: 'Привет, мир!' // 包含西里尔字母的测试数据
}).then(response => {
    console.log('收到响应:', response);
}).catch(error => {
    console.error('发送失败:', error);
});

4. 排查SQLite写入的潜在问题

如果前面的步骤都没问题,还要确认SQLite数据库的编码是否为UTF-8。创建数据库时可以指定编码:

import sqlite3
conn = sqlite3.connect('your_db.db')
# 确保连接使用UTF-8编码
conn.execute('PRAGMA encoding = "UTF-8"')

测试验证

构造一个包含非ASCII字符的测试消息,比如{"content": "Привет, это тест с кириллицей!"},运行Python程序和扩展,观察Python是否能正常接收、处理并响应,不会出现假死。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 09:43:09