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

macOS下Firefox原生消息传递调用失败问题求助

Firefox原生消息传递失败排查(macOS)

错误日志

Bookmarks: 
Array(5) [ {…}, {…}, {…}, {…}, {…} ]
background.js:13:11
Native messaging failed: Error: An unexpected error occurred background.js:21:29
    exportBookmarks moz-extension://e32bef2f-a8ae-4b3e-b67c-49730ae7bcc1/background.js:21
    (Async: promise callback)
    exportBookmarks moz-extension://e32bef2f-a8ae-4b3e-b67c-49730ae7bcc1/background.js:21
    <anonym> moz-extension://e32bef2f-a8ae-4b3e-b67c-49730ae7bcc1/background.js:29

扩展清单 (manifest.json)

{
  "manifest_version": 2,
  "name": "Albert bookmark export",
  "version": "1.0",
  "permissions": [
    "bookmarks",
    "nativeMessaging"
  ],
  "background": {
    "scripts": [
      "background.js"
    ]
  },
  "browser_specific_settings": {
    "gecko": {
      "id": "bookmark_export@albertlauncher.org",
      "strict_min_version": "50.0"
    }
  }
}

扩展后台脚本 (background.js)

async function getBookmarks() {
  let bookmarks = [];

  function traverse(nodes) {
    for (let n of nodes) {
      if (n.url) bookmarks.push({id: n.id, title: n.title, url: n.url});
      if (n.children) traverse(n.children);
    }
  }

  const tree = await browser.bookmarks.getTree();
  traverse(tree);
  console.log("Bookmarks:", bookmarks);
  return bookmarks;
}

async function exportBookmarks() {
    let bookmarks = await getBookmarks();
    browser.runtime.sendNativeMessage("bookmark_export", { bookmarks })
    .then(response => { console.log("Received response from native host:", response); })
    .catch(err => { console.error("Native messaging failed:", err); });  // Error: An unexpected error occurred
}

browser.bookmarks.onCreated.addListener(exportBookmarks);
browser.bookmarks.onRemoved.addListener(exportBookmarks);
browser.bookmarks.onChanged.addListener(exportBookmarks);
browser.bookmarks.onMoved.addListener(exportBookmarks);

exportBookmarks();

原生宿主清单 (bookmark_export.json)

{
  "name": "bookmark_export",
  "description": "Writes Firefox bookmarks to a JSON file",
  "path": "/tmp/bookmark_export.sh",
  "type": "stdio",
  "allowed_extensions": ["bookmark_export@albertlauncher.org"]
}

原生宿主脚本 (bookmark_export.py)

#!/usr/bin/env python3

import sys, json, struct, traceback

with open("/tmp/0_albert_bookmark_export.txt", "w") as f:
    f.write("I have been called\n")

def get_message():
    rawLength = sys.stdin.buffer.read(4)
    if len(rawLength) == 0:
        sys.exit(0)
    messageLength = struct.unpack('@I', rawLength)[0]
    message = sys.stdin.buffer.read(messageLength).decode('utf-8')
    return json.loads(message)

# Encode a message for transmission,
# given its content.
def encode_message(messageContent):
    # https://docs.python.org/3/library/json.html#basic-usage
    # To get the most compact JSON representation, you should specify
    # (',', ':') to eliminate whitespace.
    # We want the most compact representation because the browser rejects # messages that exceed 1 MB.
    encodedContent = json.dumps(messageContent, separators=(',', ':')).encode('utf-8')
    encodedLength = struct.pack('@I', len(encodedContent))
    return {'length': encodedLength, 'content': encodedContent}

# Send an encoded message to stdout
def send_message(encodedMessage):
    sys.stdout.buffer.write(encodedMessage['length'])
    sys.stdout.buffer.write(encodedMessage['content'])
    sys.stdout.buffer.flush()

def write_bookmarks_file(data):
    with open("Bookmarks.json", "w", encoding="utf-8") as f:
        json.dump(data, f, indent=2)

def send_response(data):
    encoded = json.dumps(data).encode("utf-8")
    sys.stdout.buffer.write(struct.pack("<I", len(encoded)))
    sys.stdout.buffer.write(encoded)
    sys.stdout.buffer.flush()

if __name__ == "__main__":

    with open("debug.log", "w") as f:
        f.write("I have been called\n")

        try:
            f.write("get_message\n")
            msg = get_message()
            f.write("write_bookmarks_file\n")
            write_bookmarks_file(msg)
            f.write("send_message\n")
            send_message(encode_message(json.dumps({"status": "ok"})))
            f.write(json.dumps(msg) + "\n")
        except Exception as e:
                f.write(traceback.format_exc())

问题排查关键点

  • 宿主路径不匹配:清单中path指向不存在的/tmp/bookmark_export.sh,需改为Python脚本的绝对路径,比如/Users/你的用户名/albert/plugins/python/plugins/firefox/firefox_extension/bookmark_export.py。
  • 脚本权限不足:给Python脚本添加可执行权限,执行chmod +x /Users/你的用户名/albert/plugins/python/plugins/firefox/firefox_extension/bookmark_export.py。
  • 工作目录写入权限:脚本中Bookmarks.json和debug.log默认写入Firefox启动目录,改为绝对路径(如/tmp/Bookmarks.json)避免权限问题。
  • 消息格式不一致:get_message用@I解析长度,send_response用<I打包,需统一字节序;send_message传递json.dumps结果会导致JSON嵌套,直接传字典{"status": "ok"}即可。
  • 宿主清单权限:确保bookmark_export.json权限为644,执行chmod 644 ~/Library/Application\ Support/Mozilla/NativeMessagingHosts/bookmark_export.json。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 10:17:10