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

Chrome原生消息主机消息长度为256倍数时无法读取问题求助

Chrome原生消息(Native Messaging)特定长度消息解析失败问题解决

问题现象

开发Chrome扩展通过Native Messaging Host传输DOM信息时,发现当纯消息长度为256的倍数加10/20/30(比如266=256+10,对应含头总长度270)时,Chrome停止解析原生主机的stdout,触发异常:The sender sent an invalid JSON message; message ignored.,随后关闭连接。原生主机持续发送数据但无响应。

核心原因

Windows平台下,C++的std::cout默认使用文本模式,而非Native Messaging要求的二进制模式。文本模式会自动转换换行符(如\n转\r\n),或把特定字节(如0x1A)视为EOF截断输出,导致实际发送的字节数与头部声明的长度不匹配,Chrome解析JSON时因数据损坏报错。

你的代码仅设置了stdin的二进制模式,但遗漏了stdout的二进制模式配置,这是问题的根本所在。

解决方案

在原生主机的main函数中,同时将stdout设置为二进制模式:

修改后的C++代码片段

int main(int argc, char *argv[]) {

    // 设置stdin为二进制模式
    if (_setmode(_fileno(stdin), _O_BINARY) == -1) {
        Log("[Error]. Could not set input mode to binary");
        return 1;
    }
    // 设置stdout为二进制模式(关键修复)
    if (_setmode(_fileno(stdout), _O_BINARY) == -1) {
        Log("[Error]. Could not set output mode to binary");
        return 1;
    }
    
    // 后续逻辑保持不变
    std::this_thread::sleep_for(std::chrono::seconds(5));
    for (int i = 1; i < 100000; i++) {
        nlohmann::json jj = {{"msg", ""}};
        for (int j = 0; j < i; j++) {
            jj["msg"] += "a";
        }
        std::string s = jj.dump();
        SendExtMessage(s);
        std::this_thread::sleep_for(std::chrono::milliseconds(10));
    }
    return 0;
}

额外优化建议

  1. 移除临时添加的虚拟字节逻辑,因为根本问题解决后无需再规避长度:
// 恢复原始的SendExtMessage函数,去掉长度判断和虚拟字段
void SendExtMessage(std::string msg) {
    uint32_t responseLen = msg.length();
    char *bt_len = reinterpret_cast<char *>(&responseLen);
    std::cout.write(bt_len, 4);
    std::cout.write(msg.c_str(), responseLen);
    std::cout.flush();
    Log("[Log] Writing " + std::to_string(responseLen) + " bytes to stdout");
}
  1. 确保JSON序列化无异常:使用nlohmann::json的dump时,默认会处理特殊字符,无需额外转义,但可以添加错误检查确保JSON有效:
try {
    std::string s = jj.dump();
    SendExtMessage(s);
} catch (const nlohmann::json::exception& e) {
    Log("[Error] JSON serialization failed: " + std::string(e.what()));
}

验证步骤

  1. 重新编译原生主机,确保stdout二进制模式已设置;
  2. 运行扩展,测试原问题中的敏感长度(如2560+10=2570字节的纯消息);
  3. 查看Chrome后台日志,确认所有长度的消息都能正常接收,无连接断开或JSON错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 00:39:51