Safari Web Extension Native Messaging问题:页面信息无法发送至原生应用
Safari扩展Native Messaging无响应排查与修复
问题场景
尝试将页面信息发送到原生应用,已在manifest.json中声明nativeMessaging权限。点击popup按钮后,popup→content→background的消息流转正常,但background向原生应用发送消息环节无响应。
代码片段
popup.js
//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
相关产品推荐
相关产品推荐

