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

Safari Web Extension Native Messaging问题:页面信息无法发送至原生应用

Safari扩展Native Messaging无响应排查与修复

问题场景

尝试将页面信息发送到原生应用,已在manifest.json中声明nativeMessaging权限。点击popup按钮后,popup→content→background的消息流转正常,但background向原生应用发送消息环节无响应。

代码片段

//handle response/error

function notifyContentPage(e) {  
  browser.tabs.query({active: true, currentWindow: true}, function(tabs) {
    if (tabs.length == 0) {
      console.log("could not send mesage to current tab");
    } else {
      console.log("Popup sending get html message");
      const sendingToContent = browser.tabs.sendMessage(tabs[0].id, {type: "get html"});
      sendingToContent.then(handleResponse, handleError);
    }
  });
}

document.getElementById("parse").addEventListener("click", notifyContentPage);

content.js

browser.runtime.onMessage.addListener((request, sender, sendResponse) => {
  if (!sender.tab && request.type == "get html") {
    
    console.log("Content sending save parsed message");
    browser.runtime.sendMessage({ type: "save parsed" }, function(response) {
        console.log(`Content received save parsed response: ${response}`);
    })
  }
  sendResponse("ok");
});

background.js

browser.runtime.onMessage.addListener((request, sender, sendResponse) => {
  
  if (request.type = "save parsed") {
    browser.runtime.sendNativeMessage("application.id", {message: request}, function(response) {
      sendResponse(`Received native message response ${response[0]}`);
    });
  } else {
    sendResponse(`Received unknown request ${request.type}`);
    return true;
  }
});

SafariWebExtensionHandler.swift

import SafariServices
import os.log

let SFExtensionMessageKey = "message"

class SafariWebExtensionHandler: NSObject, NSExtensionRequestHandling {

    func beginRequest(with context: NSExtensionContext) {
      os_log("started processing request")
        let item = context.inputItems[0] as! NSExtensionItem
        let message = item.userInfo?[SFExtensionMessageKey]
        os_log(.default, "Received message from browser.runtime.sendNativeMessage: %@", message as! CVarArg)

        let response = NSExtensionItem()
        response.userInfo = [ SFExtensionMessageKey: [ "Response to": message ] ]

        context.completeRequest(returningItems: [response], completionHandler: nil)
    }

}

manifest.json

{
    "manifest_version": 3,
    "default_locale": "en",

    "name": "__MSG_extension_name__",
    "description": "__MSG_extension_description__",
    "version": "1.0",

    "icons": {
        "48": "images/icon-48.png",
        "96": "images/icon-96.png",
        "128": "images/icon-128.png",
        "256": "images/icon-256.png",
        "512": "images/icon-512.png"
    },

    "background": {
      "service_worker": "background.js"
    },

    "content_scripts": [{
        "js": [ "content.js" ],
        "matches": [ "<all_urls>" ]
    }],

    "action": {
        "default_popup": "popup.html",
        "default_icon": {
            "16": "images/toolbar-icon-16.png",
            "19": "images/toolbar-icon-19.png",
            "32": "images/toolbar-icon-32.png",
            "38": "images/toolbar-icon-38.png",
            "48": "images/toolbar-icon-48.png",
            "72": "images/toolbar-icon-72.png"
        }
    },

    "permissions": [
        "<all_urls>",
        "nativeMessaging",
        "activeTab"
    ]
}

问题排查与修复

1. 修复background.js条件判断错误

background.js中if (request.type = "save parsed")使用了赋值运算符=,而非比较运算符===,会导致无论请求类型是什么都进入该分支,同时篡改request.type的值。修改为:

if (request.type === "save parsed") {

2. 处理异步响应生命周期

sendNativeMessage是异步操作,需在监听器中返回true,告知浏览器等待异步操作完成后再发送响应,否则sendResponse会失效。同时修正原生响应的取值逻辑(原生端返回字典而非数组):

browser.runtime.onMessage.addListener((request, sender, sendResponse) => {
  if (request.type === "save parsed") {
    browser.runtime.sendNativeMessage("application.id", {message: request}, function(response) {
      sendResponse(`Received native message response ${response?.["Response to"] ?? "no response"}`);
    });
    // 返回true保持消息通道开放
    return true;
  } else {
    sendResponse(`Received unknown request ${request.type}`);
    return true;
  }
});

3. 确认Safari原生消息配置

  • 确保原生应用的Info.plist中配置的Bundle ID与background.js中使用的application.id完全一致。
  • 原生应用需已安装并获得Safari的访问授权。
  • 检查Safari扩展设置,确认当前扩展的Native Messaging权限已启用。

4. 添加错误日志排查

在sendNativeMessage回调中添加错误捕获,定位问题根源:

browser.runtime.sendNativeMessage("application.id", {message: request}, function(response) {
  if (browser.runtime.lastError) {
    console.error("Native messaging error:", browser.runtime.lastError);
    sendResponse(`Native messaging error: ${browser.runtime.lastError.message}`);
  } else {
    sendResponse(`Received native message response ${response?.["Response to"] ?? "no response"}`);
  }
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 11:03:14