微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

内容脚本和后台脚本之间的 Chrome.runtime.sendmessage 有时不起作用

如何解决内容脚本和后台脚本之间的 Chrome.runtime.sendmessage 有时不起作用

我有一个 chrome 扩展程序可以捕获 DOM 元素属性

  • 内容脚本和后台脚本之间存在消息通信。
  • 使用executeScript 函数内容脚本注入到选项卡中 runAt:document_end
  • 请注意,这并不总是可重现的,但在 5 次尝试中几乎 4 次我们可以轻松解决此问题。
  • 每当检测到 I-Frame 时,就会使用 chrome.runtime.sendmessage() 将消息从内容脚本发送到后台脚本
  • 重现此错误的具体情况是:打开一个新窗口并打开所需的 URL。
  • 后台脚本没有收到消息,通过 chrome.runtime.onMessage.addListener(onRuntimeMessageHandler); 添加事件处理程序;

我在下面的 MVCE 之后添加代码片段(它将是最小的代码片段

 
//We inject scripts to the specific tab as below:
let options = { frameId: frameId,file:"Background.js",runAt:"document_end"};
let scriptReturn = await new Promise((resolve) =>
{
chrome.tabs.executeScript(tabId,options,(result) =>
{
if (!result || result.length == 0)
{
logging.error("[Script Insertion] Script error while inserting script: " + chrome.runtime.lastError.message,source);
resolve(undefined);
}
else
resolve(result[0]);
});
});

/////Content-Script.js
///////We call the function which sends message to background script as below:
 
//If not top frame,send message to parent with our id,only on visible iframe in case frameElement is accessible 
if (window !== top && (!window.frameElement || window.frameElement && window.frameElement.style.display != "none"))
{
    if (matchFrameByIndex) 
    {
        //Try to find out which frame id we are for our parent
        for (var i = 0; i < parent.frames.length; ++i)
            if (parent.frames[i] === window)
            {
                console.log("Calling matchframeindex")
                matchFrameByIndex(scriptInfo.frameId,scriptInfo.parentFrameId,i);
                break;
            }
    }
}
 
 
 
    this.matchFrameByIndex = function (frameId,parentFrameId,index) {
        /// <summary>Use (i)frame name to match a (i)frame tag with its actual document.</summary>
        /// <param name="frameId" type="Int" optional="false">Id of the child (i)frame</param>
        /// <param name="parentFrameId" type="Int" optional="false">Id of the parent (i)frame</param>
        /// <param name="index" type="Int" optional="false">Index of the child on parent's frame collection</param>
 
        console.log(`[${(new Date()).toISOString()}]`+"Setting (I)FRAME id. child: " + frameId + ",parent: " + parentFrameId + ",index: " + index );
        chrome.runtime.sendMessage({
            command: commands.MATCH_FRAME,frameId: frameId,parentFrameId: parentFrameId,index: index
        });
    };
 
 
////Background script's handler for receiving message:
BackgroundScript.js
 //In the initial functions itself:
        chrome.runtime.onMessage.addListener(onRuntimeMessageHandler);

 function onMessageHandler(msg,sender,sendResponseCallback) {
        /// <summary>Receives messages from the background page</summary>
        /// <param name="msg" type="Any" optional="true">The message sent by the calling script.</param>
        /// <param name="sender" type="Object" optional="false"></param>
        /// <param name="sendResponseCallback" type="Function" optional="true">Function to call after processing the message</param>
 
        // The message is only valid if there is a command property
        if (msg && msg.command) {
            console.log(`[${(new Date()).toISOString()}]`+"Grabber: Message received",msg);
 
            switch (msg.command) {
                case commands.MATCH_FRAME:
                     console.log("Message received by background script");
                    break;
                default:
                    console.log("UnkNown command in message: " + msg.command);
                    break;
            }
        }
    }
}
 

尝试过的方法

  • 收到消息失败,尝试重新发送。仍然没有帮助

有什么想法为什么在特定场景中没有收到消息?

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。