gpt4 book ai didi

javascript - 所有在后台上下文中发送给一个脚本的消息都会被接收

转载 作者:行者123 更新时间:2023-12-03 03:59:13 24 4
gpt4 key购买 nike

我有一个具有以下结构的 WebExtension:

webextension [directory]
- background.js
- page1.html
- page1.js
- page2.html
- page2.js

background.js 监听错误。如果有的话,它会指示其回调函数使用包含按钮的 HTML 页面 page2.js 更新选项卡。

HTML 脚本 page2.js 首先向 background.js 发送一条消息,然后 background.js 回复 page2 .js。这部分工作正常。

然后,正如您在代码中看到的,page2.html包含一个按钮,如果单击,它将执行回调函数中的代码。然后,它将调用 refreshIndexPage,该消息应向 page1.js 发送一条消息,该消息附加到 page1.html

问题:当我在 refreshIndexPage 中的 page2.jspage1.js 之间添加消息 API 时>,来自 page2 的消息被发送到 background.js。我不希望这种情况发生。正如我将在输出中显示的那样,我得到: In background.js: returned: undefined

问题:

  1. 如何从 page2.jspage1.js 发送消息,而不使 background.js 也监听来自以下位置的消息page2.js 感到困惑并收到不适合它的消息?如何指定该消息是从 page2.jspage1.js

以下是将消息从 page2.js 添加到 page1.js 后的输出。控制台输出

inside refreshIndexPage
In background.js: received: undefined
inside handleRefreshResponse
  1. page1.html:
<html>
<head>
<meta charset="UTF-8">
</head>
<body>
<h1>Pag1.html</h1>
<input type="button" id="page1-button" value="click"></input>
<script src="page1.js"></script>
</body>
</html>
  • page1.js:
  • function displayAll() {
    console.log("inside display all");
    } //end displayAll

    //should listen to messages from pag2.js
    browser.runtime.onMessage.addListener(handleRefreshMessage);

    function handleRefreshMessage(request, sender, sendResponse) {
    console.log("In page1.js: message received" + request.refreshRequest);
    sendResponse("response from page1.js to page2.js");
    }
  • background.js:
  • console.log("inside background");

    //add a listener for the toolbar icon. If clicked, open page1.html
    browser.browserAction.onClicked.addListener((tab) => {
    // disable the active tab
    var creating = browser.tabs.create({"url": "page1.html"});
    creating.then((tab) => {
    browser.browserAction.setIcon({tabId: tab.id, path: "icons/red-64.png"});
    });//end creating.then
    });//end addListener

    var target = "<all_urls>";
    function log(responseDetails) {
    console.log("inside response details");
    errorTab = responseDetails.tabId;
    if(true) {
    console.log("inside if");
    browser.tabs.update(responseDetails.tabId,{url: "page2.html"});

    //this message to wait request from page2.js
    browser.runtime.onMessage.addListener(handleMessage);
    } //end if
    }//end log

    function handleMessage(request, sender, sendResponse) {
    console.log("In background.js: received: " + request.scriptRequest);
    sendResponse({errorTab: errorTab});
    }

    var errorListening = browser.webRequest.onErrorOccurred.addListener(log, {
    urls: [target],
    types: ["main_frame"]
    });
  • page2.html:
  • <html>
    <head>
    <meta charset="UTF-8">
    </head>
    <body>
    <h1>Pag2.html</h1>
    <input type="button" id="page2-button" value="click"></input>
    <script src="page2.js"></script>
    </body>
    </html>
  • page2.js:
  • /*self-calling function conatins sendMessage to background script*/
    (function notifyBackgroundPage() {
    var sending = browser.runtime.sendMessage({
    scriptRequest: "From pag2.js. request for data"
    });
    sending.then(handleResponse);
    })();

    function handleResponse(message) {
    console.log(`In page2.js: data from background is: ${message.errorTab}`);
    } //handleResponse

    function myFunction() {
    refreshIndexPage();//end .then
    }//end myFunction

    //refreshIndexPage should send message to page1.js only when the button is clicked.
    function refreshIndexPage() {
    console.log("inside refreshIndexPage");
    var sending = browser.runtime.sendMessage({
    refreshRequest: "From page2.js"
    });
    sending.then(handleRefreshResponse);
    }//end refreshIndex

    function handleRefreshResponse() {
    console.log("inside handleRefreshResponse");
    }//end handleRefreshResponse

    var page2Button = document.getElementById("page2-button");
    page2Button.addEventListener('click', myFunction);

    最佳答案

    runtime.sendMessage()发送的消息在后台上下文中的所有脚本中都会收到 runtime.onMessage监听器已注册,发送消息的脚本除外。1您无法限制此类消息的收件人。

    因此,您必须创建一些方法来确定该消息是否适用于接收它的每个脚本。这可以通过多种方式完成,但所有方式都基于以下任一方式:

    1. message 的内容和/或
    2. sender

    这两者都作为参数提供给 runtime.onMessage() 监听器。

    使用消息

    要使用消息,您必须选择消息上强加一些结构。 消息可以是您选择发送的任何 JSON 数据。强加一些结构可以让您更轻松地使用更复杂的消息,并更可靠地在脚本之间传递信息。没有什么是预先定义的。您可以使用任何您想要的东西。然而,保持一致的选择通常会使编程变得更容易,并且几乎总是使代码更易于维护。

    就我个人而言,我通常出于不同的原因发送消息。对于每个分机,我通常会选择始终发送 Object具有特定的格式。每个扩展的格式可能不同,但通常看起来像:

    var message = {
    type: 'requestFoo',
    //subType: 'Used if the type needs to be further split',
    data: dataNeededForRequest
    //You can add whatever other properties you want here.
    };

    如果扩展程序有多个可能的接收者,则 A) 只有一个接收者会理解如何处理 requestFoo type 消息,而所有其他接收者都会忽略此类 message types,或者如果有多个后台上下文脚本可以处理 requestFoo 类型,那么我会添加一个 recipientdestination 属性。因此,消息将如下所示:

    var message = {
    type: 'requestFoo',
    //subType: 'Used if the type needs to be further split',
    recipient: 'page2.js',
    data: dataNeededForRequest
    //You can add whatever other properties you want here.
    };

    当每个脚本收到消息时,它们会检查接收者是否与接收消息的脚本匹配,以及代码是否理解如何处理 消息的类型

    请记住,上面的结构正是我碰巧使用的。您可以定义任何您想要的结构,这也能满足您的需求。

    使用发送者

    如果脚本从不对从特定发件人收到的消息进行操作,或者如果它对来自特定发件人的消息进行操作,那么脚本可以检查发件人 runtime.MessageSender对象以查看参数是否与要对其执行消息的发送者的参数匹配。如果您使用此方法,您通常会检查 sender.url .

    仅根据发送者来选择对消息采取行动,比根据消息的内容选择采取行动的局限性要大得多。然而,当除了消息中提供的信息之外使用时,它会非常有用。它还提供了一种了解消息发送者的方法,该方法不能被欺骗。此外,这意味着您不需要传达关于哪个范围是消息发送者的信息,当然,除非您在该范围内(即在 URL/页面中)有多个可能的发送者。

    <小时/>

    1。一个bug in Firefox在 51 之前的版本中,消息会在发送消息的脚本中被接收。如果您希望您的扩展程序在该版本或更早版本中使用,您必须考虑到这种可能性(即忽略它们),因为某些情况可能会导致 Firefox 锁定(例如,如果您总是发送新消息)当您收到消息时)。

    关于javascript - 所有在后台上下文中发送给一个脚本的消息都会被接收,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44804009/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com