我正在尝试构建一个简单的Safari应用扩展程序。在about:blank
上,我从扩展名的resources文件夹加载html页面。以下是该代码。
//script.js - injected script
if(window.location.href=="about:blank"){
window.location.href = safari.extension.baseURI + "page.html";
}
我想要此加载的页面与Safari应用之间进行通信。显然,已插入的脚本script.js
在已加载的html页面上不可用。
我尝试将script.js
链接到html页面内联,但是safari
对象本身不适用于safari.extension.dispatchMessage
或safari.self.addEventListener
。
编辑:
这样做(注入的脚本script.js在加载的html页面/加载页面的选项卡上不可用)是指在资源选项卡中打开Web检查器时,我们看不到任何extension scripts
答案 0 :(得分:1)
如果我正确理解了您的问题,则需要在页面的javascript和Safari应用程序扩展的本机主机应用程序之间进行通信。只能使用API safari.extension.dispatchMessage 与主机应用程序联系,该API仅可从注入的 script.js 脚本访问,而不能从页面的JS访问。
您可以通过从页面发送请求事件和注册响应事件来解决此问题。您的HTML页面将包含脚本:
function sendEventToInjected() {
var storeEvent = new CustomEvent('myCustomEvent', {"detail": "testData"});
document.dispatchEvent(storeEvent);
var responseEventID = 'myResponseEvent';
document.addEventListener(responseEventID, function respListener(event)
{
console.log("Got data from injected script: " + event.detail);
document.removeEventListener(responseEventID, respListener);
});
}
您的 script.js 将通过注册事件侦听器来捕获此事件,然后可以将数据传递到扩展程序的本机宿主应用程序。获取本机主机的响应后,可以将响应事件分派回页面。
document.addEventListener("myCustomEvent", function(event) {
console.log("myCustomEvent:" + event.detail);
safari.extension.dispatchMessage(event.detail);
});
// Listens for messages sent from the app extension's Swift code.
safari.self.addEventListener("message", messageHandler);
function messageHandler(event)
{
var resp = {detail: "respData"};
var respEvent = new CustomEvent('myResponseEvent', resp);
document.dispatchEvent(respEvent);
}
答案 1 :(得分:0)
您可能不会将页面“重定位”到safari-extensions://网址,而是从Safari应用程序扩展(使用消息传递)获取要显示的HTML代码,然后将代码插入about:blank页面。 结果将是相同的,除了页面网址将保持大约:空白
答案 2 :(得分:0)
这似乎是Apple的错误。我已经向BugReporter提交了文件。
答案 3 :(得分:0)
您可以在 HTML 中添加零高度 iframe
以“强制注入”扩展脚本。
<!DOCTYPE html>
<html lang=en>
<head>
<title>My Extension!</title>
</head>
<body>
<noscript><strong>We're sorry but App doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript>
<p>Hi!</p>
<iframe id="myID" src="https://example.com" height="0" style="border: none;"></iframe>
</body>
</html>
这是可能的 JS:
function handleMessage(event) {
console.log(event.name);
console.log(event.message);
}
if (window.top === window) {
document.addEventListener("DOMContentLoaded", function(event) {
console.log("[app] Content loaded: main");
safari.extension.dispatchMessage("Hello from Main!");
safari.self.addEventListener("message", handleMessage);
});
} else {
document.addEventListener("DOMContentLoaded", function(event) {
console.log("[app] Content loaded: iframe");
safari.extension.dispatchMessage("Hello from iframe!");
safari.self.addEventListener("message", handleMessage);
});
}
结果: