等待浏览器的响应。

发布于 2025-02-13 23:48:12 字数 2275 浏览 1 评论 0原文

我已经成功地使用了浏览器。 等待浏览器。在Content Script Inject.js中,sendResponse应在1000ms超时之后调用。

我附上了一个简约的例子。任何想法等待浏览器.tabs.sendmessage 返回什么SendResponse仅在Chrome中设置,而不是在Firefox中设置?

//inject.js
(async () => {
    if (typeof browser === "undefined") {
        var browser = chrome;
    }

    browser.runtime.onMessage.addListener((msg, sender, sendResponse) => {
        console.log(msg);
        setTimeout(function(){
            let pageObject = {a:1};
             sendResponse(pageObject);
        },1000)
        return true;
    });

})();



//background.js
(async () => {
      if (typeof browser === "undefined") {
        var browser = chrome;
      }


//**code for injecting content scripts on extension reload**

  browser.runtime.onInstalled.addListener(async () => {
    let manifest = browser.runtime.getManifest();
    for (const cs of manifest.content_scripts) {
      for (const tab of await browser.tabs.query({ url: cs.matches })) {
        browser.scripting.executeScript({
          target: { tabId: tab.id },
          files: cs.js,
        });
      }
    }
  });

      async function SendMessageToFront(message) {
        let resolve;
        const promise = new Promise(r => resolve = r);
        browser.tabs.query({}, async function (tabs) {
          for (let index = 0; index < tabs.length; index++) {
            const tab = tabs[index];
    
            if (tab.url) {
              let url = new URL(tab.url)
              if (url.hostname.includes("tragetdomain.com")) {
                var startTime = performance.now()
                let response = await browser.tabs.sendMessage(tab.id, { message: message });
                var endTime = performance.now()
                console.log(`Call to doSomething took ${endTime - startTime} milliseconds`) // this takes 0ms
    
                console.log("got response");
                console.log(response); // this is undefined
                console.log(browser.runtime.lastError); // this is empty
                resolve(response);
                break;
              }
            }
          }
        });
    
        return promise;
      }


      await SendMessageToFront();
})();
  

I have successfully used await browser.tabs.sendMessage in chrome to get response from the listener, but the same code in firefox does not work. await browser.tabs.sendMessage return immediately and sets response to undefined. In content script inject.js, sendResponse should be called after 1000ms timeout.

I attached a minimalistic example. Any idea why await browser.tabs.sendMessage
returns what sendResponse set only in chrome, but not in firefox?

//inject.js
(async () => {
    if (typeof browser === "undefined") {
        var browser = chrome;
    }

    browser.runtime.onMessage.addListener((msg, sender, sendResponse) => {
        console.log(msg);
        setTimeout(function(){
            let pageObject = {a:1};
             sendResponse(pageObject);
        },1000)
        return true;
    });

})();



//background.js
(async () => {
      if (typeof browser === "undefined") {
        var browser = chrome;
      }


//**code for injecting content scripts on extension reload**

  browser.runtime.onInstalled.addListener(async () => {
    let manifest = browser.runtime.getManifest();
    for (const cs of manifest.content_scripts) {
      for (const tab of await browser.tabs.query({ url: cs.matches })) {
        browser.scripting.executeScript({
          target: { tabId: tab.id },
          files: cs.js,
        });
      }
    }
  });

      async function SendMessageToFront(message) {
        let resolve;
        const promise = new Promise(r => resolve = r);
        browser.tabs.query({}, async function (tabs) {
          for (let index = 0; index < tabs.length; index++) {
            const tab = tabs[index];
    
            if (tab.url) {
              let url = new URL(tab.url)
              if (url.hostname.includes("tragetdomain.com")) {
                var startTime = performance.now()
                let response = await browser.tabs.sendMessage(tab.id, { message: message });
                var endTime = performance.now()
                console.log(`Call to doSomething took ${endTime - startTime} milliseconds`) // this takes 0ms
    
                console.log("got response");
                console.log(response); // this is undefined
                console.log(browser.runtime.lastError); // this is empty
                resolve(response);
                break;
              }
            }
          }
        });
    
        return promise;
      }


      await SendMessageToFront();
})();
  

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

水水月牙 2025-02-20 23:48:12

我想对于Firefox中的测试,您可以重新加载背景脚本(F5或DevTools中的特定按钮)
正如您对背景进行了编码一样,您几乎没有希望得到答案,因为每次您重新加载背景时,都会用注入页面中的所有内容脚本打破电线。
将浏览器检查在“ sendmessagetofront”功能中。将“ sendmessagetofront”函数(不需要async)移至主线程中,并在主线程中运行该函数。

/*async*/ function SendMessageToFront(message) {
    if (typeof browser === "undefined")
        var browser = chrome;
    let resolve;
    const promise = new Promise(r => resolve = r);
    browser.tabs.query({}, async function(tabs) {
        for (let index = 0; index < tabs.length; index++) {
            const tab = tabs[index];
            if (tab.url) {
                let url = new URL(tab.url);
                if (url.hostname.includes("tragetdomain.com")) {
                    var startTime = performance.now()
                    let response = await browser.tabs.sendMessage(tab.id, {'message': message});
                    var endTime = performance.now()
                    console.log(`Call to doSomething took ${endTime - startTime} milliseconds`) // this takes 0ms
                    console.log("got response");
                    console.log(response); // this is undefined
                    console.log(browser.runtime.lastError); // this is empty
                    resolve(response);
                    break
                }
            }
        }
    });
    return promise
}

(async _ => {
    await SendMessageToFront()
})();

通过这种方式,您一旦准备就绪后,您就会收到一条错误消息,这告诉您另一侧的内容脚本不存在或尚未准备就绪,但是现在,当内容脚本准备就绪时,您应该只有从背景脚本DevTools重新启动函数

(async _ => {
    await SendMessageToFront()
})();

,您将获得正确的答案{a:1}

I guess for the tests in firefox you do the reload of the background script (F5 or the specific button in devtools)
Just as you have coded the background you have little hope of getting an answer because every time you reload the background you break the wire with all content scripts injected into the page(s).
Move the browser check inside the "SendMessageToFront" function. Move the "SendMessageToFront" function (async is not needed) to the main thread and run that function in the main thread.

/*async*/ function SendMessageToFront(message) {
    if (typeof browser === "undefined")
        var browser = chrome;
    let resolve;
    const promise = new Promise(r => resolve = r);
    browser.tabs.query({}, async function(tabs) {
        for (let index = 0; index < tabs.length; index++) {
            const tab = tabs[index];
            if (tab.url) {
                let url = new URL(tab.url);
                if (url.hostname.includes("tragetdomain.com")) {
                    var startTime = performance.now()
                    let response = await browser.tabs.sendMessage(tab.id, {'message': message});
                    var endTime = performance.now()
                    console.log(`Call to doSomething took ${endTime - startTime} milliseconds`) // this takes 0ms
                    console.log("got response");
                    console.log(response); // this is undefined
                    console.log(browser.runtime.lastError); // this is empty
                    resolve(response);
                    break
                }
            }
        }
    });
    return promise
}

(async _ => {
    await SendMessageToFront()
})();

in this way you will get an error message as soon as the background is ready which tells you that the content script on the other side does not exists or it's not ready yet, but now, when the content script will be ready, you should just re-launch the function from the background script devtools

(async _ => {
    await SendMessageToFront()
})();

this time you will get the correct answer {a: 1}

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文