消息回调不经常返回一个值 - Chrome扩展

Ign*_*nas 3 javascript websocket google-chrome-extension node.js

我正在构建一个chrome扩展,它通过websockets与nodejs服务器通信.其重点是跟踪内容的浏览历史记录.这一切似乎都有效,但偶尔(30%的时间)传递给onMessage.addListener的函数中的回调不会正确触发.我来告诉你代码:

background.js

var socket = io('http://localhost:3000/');

var tabLoad = function (tab) {
    socket.emit('page load', tab);
};

var tabUpdate = function (tabid, changeinfo, tab) {
    var url = tab.url;
    if (url !== undefined && changeinfo.status == "complete") {
        tab.user_agent = navigator.userAgent;
        tab.description = '';
        tab.content = '';

        socket.emit('insert', tab);
    }
};

socket.on('inserted', function(page){
    socket.emit('event', 'Requesting page content\n');
    //page = {tab: page, id: docs._id};
    chrome.tabs.sendMessage(page.tab_id, {requested: "content", page: page}, function(data) {
        socket.emit('content', data);
    });

});

try {
    chrome.tabs.onCreated.addListener(tabLoad);
    chrome.tabs.onUpdated.addListener(tabUpdate);
} catch(e) {
    alert('Error in background.js: ' + e.message);
}
Run Code Online (Sandbox Code Playgroud)

内容脚本 - public.js

var messageHandler = function(request, sender, sendContent) {
    if (request.requested == "content") {
        var html = document.getElementsByTagName('html')[0].innerHTML;
        var data = {
            content: html,
            page: request.page
        };
        sendContent(data);
        return true;
    }
};

chrome.extension.onMessage.addListener(messageHandler);
Run Code Online (Sandbox Code Playgroud)

问题是有时sendContent中的数据是未定义的,有时候它是正常的.任何想法如何调试这个或我做错了什么?

我尝试用document.getElementsByTagName('html')[0].innerHTML硬编码的"测试"字符串替换,但这没有帮助.

像youtube/wikipedia这样的页面似乎永远不会起作用,而facebook/google也可以.

编辑:sendContent回调在100%的时间内触发,只是传递给它的数据是未定义的.

编辑:这是清单文件

{
    "manifest_version": 2,

    "name": "Socket test",
    "description": "sockets are cool",
    "version": "1.0",

    "permissions": [
        "http://st-api.localhost/",
        "http://localhost:3000/",
        "tabs",
        "background",
        "history",
        "idle",
        "notifications"
    ],
    "content_scripts": [{
        "matches": ["*://*/"],
        "js": ["public/public.js"]
        //"run_at": "document_start"
    }],
    //"browser_action": {
    //    "default_icon": "logo.png",
    //    "default_popup": "index.html"
    //},
    "background": {
        //"page" : "background.html",
        "scripts": ["socket-io.js", "background.js"],
        "persistent": true
    }
}
Run Code Online (Sandbox Code Playgroud)

Xan*_*Xan 6

首先,你sendContent在100%的时间内执行的理解是错误的.

正如在注释中建立的那样,sendMessage回调也会在出错时执行; 在你的情况下,这个错误是"Receiving end does not exist"


错误在于您的内容脚本的清单声明.一个匹配模式 "*://*/"匹配顶级的网页httphttpsURI的.即http://example.com/会匹配,而http://example.com/test不会.

最简单的解决方法是"*://*/*",但我会推荐通用匹配模式"<all_urls>".


修复后,您的代码仍有一些改进.

  • 替换chrome.extension.onMessage(已弃用)并使用chrome.runtime.onMessage
  • sendMessage通过检查将部件修改为更具弹性chrome.runtime.lastError.尽管获得了广泛的许可,Chrome仍然不会将任何内容脚本注入某些页面(例如chrome://页面,Chrome Web Store)
  • 请确保您使用"run_at" : "document_start"您的内容脚本,以确保onUpdated"complete"没有解雇之前你的脚本准备.