window.postMessage 在页面和内容脚本之间发送消息的替代方法是什么?
What are the alternatives to window.postMessage for sending a message between the page and content script?
我正在使用 Firefox WebExtension,它在网页和本机可执行文件之间创建 link(使用本机消息传递 API)。
到目前为止,我一直在使用一对内容/后台脚本,并且我使用 window.PostMessage
发送/接收消息,如下所示:
页面脚本
// Method used to communicate with content sript of the Firefox WebExtension
var callExtension = function(JSONmessage, timeout, callbackFnk) {
var promiseRequest = new Promise((resolve, reject) => {
const listener = (event) => {
if (
event.source == window && event.data.direction
&& event.data.direction == "my-extension-from-content-script"
) {
resolve(event.data.message);
}
}
setTimeout(() => {
window.removeEventListener("message", listener);
resolve(false); // Timeout
}, timeout);
window.addEventListener("message", listener);
window.postMessage({
direction: "my-extension-from-page-script",
message: JSONmessage
}, "*");
});
promiseRequest.then((result) => {
// now we are calling our own callback function
if(typeof callbackFnk == 'function'){
callbackFnk.call(this, result);
}
});
};
// Checks the presence of the extension
callExtension("areYouThere", 200, function(result) {
if(result) {
$("#result").text("Extension installed");
} else {
$("#result").text("Extension not installed");
}
});
内容脚本
window.addEventListener("message", function(event) {
if (event.source == window &&
event.data.direction &&
event.data.direction == "my-extension-from-page-script") {
if(event.data.message == "areYouThere") {
/** Checks the presence of the extension **/
window.postMessage({
direction: "my-extension-from-content-script",
message: "OK"
}, "*");
}
}
});
该代码在一个简单的网页上运行良好,但是当我尝试使其在已经使用 window.postMessage
和 window.addEventListener ("message", ...)
的页面上运行时,从该页面发送的消息不是被扩展捕获,所以我的扩展无法工作。
有没有办法从页面脚本向不使用window.postMessage
和window.addEventListener
的内容脚本发送消息?
如果不是,如何确保从页面 window.postMessage
发送的消息只会发送到我的分机,而不会被其他侦听器捕获?
您正在使用的网页似乎无法与 window.postMessage
兼容。这是可以理解的,因为这样的网页通常期望是页面中唯一使用它的东西。
您有四种选择:
- 在网页 scritps 安装任何侦听器之前,在
window
上安装您的 message
事件侦听器,以便您首先收到事件。这很可能是通过在 document_start
注入并在加载页面脚本之前安装监听器来完成的。除了您为那些属于您的消息而调用 .addEventListener()
being prior to any script on the page acting (i.e. injecting at document_start
), you should indicate that your listener will useCapture
. This will cause your listener to be called prior to any listener added by page scripts. You will need to uniquely identify in the message content that messages are to/from your extension code. You will need to cancel the event (.stopImmediatePropagation()
and .stopPropagation()
) 之外,还允许事件为那些不是您的消息传播。
- 只为您的分机使用 custom event。
- 通过插入额外的
<script>
元素,在页面上下文中直接操作 variables/functions and/or 调用函数。
- 动态更改网页脚本的代码,使其运行良好。这仅适用于单个 page/domain,并且如果网页更改其代码,则很容易中断。虽然可能,但这不是一个好的选择。
从您的内容脚本中导出一个函数,然后可以从页面调用它。
内容脚本
var myContentScriptFunction = function(myVariable) {
alert(myVariable);
}
exportFunction(myContentScriptFunction, window, {defineAs: 'myContentScriptFunction'});
页面脚本
if (window.myContentScriptFunction) window.myContentScriptFunction('Working');
我正在使用 Firefox WebExtension,它在网页和本机可执行文件之间创建 link(使用本机消息传递 API)。
到目前为止,我一直在使用一对内容/后台脚本,并且我使用 window.PostMessage
发送/接收消息,如下所示:
页面脚本
// Method used to communicate with content sript of the Firefox WebExtension
var callExtension = function(JSONmessage, timeout, callbackFnk) {
var promiseRequest = new Promise((resolve, reject) => {
const listener = (event) => {
if (
event.source == window && event.data.direction
&& event.data.direction == "my-extension-from-content-script"
) {
resolve(event.data.message);
}
}
setTimeout(() => {
window.removeEventListener("message", listener);
resolve(false); // Timeout
}, timeout);
window.addEventListener("message", listener);
window.postMessage({
direction: "my-extension-from-page-script",
message: JSONmessage
}, "*");
});
promiseRequest.then((result) => {
// now we are calling our own callback function
if(typeof callbackFnk == 'function'){
callbackFnk.call(this, result);
}
});
};
// Checks the presence of the extension
callExtension("areYouThere", 200, function(result) {
if(result) {
$("#result").text("Extension installed");
} else {
$("#result").text("Extension not installed");
}
});
内容脚本
window.addEventListener("message", function(event) {
if (event.source == window &&
event.data.direction &&
event.data.direction == "my-extension-from-page-script") {
if(event.data.message == "areYouThere") {
/** Checks the presence of the extension **/
window.postMessage({
direction: "my-extension-from-content-script",
message: "OK"
}, "*");
}
}
});
该代码在一个简单的网页上运行良好,但是当我尝试使其在已经使用 window.postMessage
和 window.addEventListener ("message", ...)
的页面上运行时,从该页面发送的消息不是被扩展捕获,所以我的扩展无法工作。
有没有办法从页面脚本向不使用
window.postMessage
和window.addEventListener
的内容脚本发送消息?如果不是,如何确保从页面
window.postMessage
发送的消息只会发送到我的分机,而不会被其他侦听器捕获?
您正在使用的网页似乎无法与 window.postMessage
兼容。这是可以理解的,因为这样的网页通常期望是页面中唯一使用它的东西。
您有四种选择:
- 在网页 scritps 安装任何侦听器之前,在
window
上安装您的message
事件侦听器,以便您首先收到事件。这很可能是通过在document_start
注入并在加载页面脚本之前安装监听器来完成的。除了您为那些属于您的消息而调用.addEventListener()
being prior to any script on the page acting (i.e. injecting atdocument_start
), you should indicate that your listener willuseCapture
. This will cause your listener to be called prior to any listener added by page scripts. You will need to uniquely identify in the message content that messages are to/from your extension code. You will need to cancel the event (.stopImmediatePropagation()
and.stopPropagation()
) 之外,还允许事件为那些不是您的消息传播。 - 只为您的分机使用 custom event。
- 通过插入额外的
<script>
元素,在页面上下文中直接操作 variables/functions and/or 调用函数。 - 动态更改网页脚本的代码,使其运行良好。这仅适用于单个 page/domain,并且如果网页更改其代码,则很容易中断。虽然可能,但这不是一个好的选择。
从您的内容脚本中导出一个函数,然后可以从页面调用它。
内容脚本
var myContentScriptFunction = function(myVariable) {
alert(myVariable);
}
exportFunction(myContentScriptFunction, window, {defineAs: 'myContentScriptFunction'});
页面脚本
if (window.myContentScriptFunction) window.myContentScriptFunction('Working');