我正在构建一个chrome扩展,它通过websocket与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 contentn');
//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);
}
内容脚本-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);
问题是sendContent中的数据有时是未定义的,而有时是可以的。有什么想法如何调试这个或者我做错了什么吗
我试过用硬编码的"test"字符串替换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
}
}
首先,您对sendContent
100%执行的理解是错误的。
如注释中所述,sendMessage
回调也会在出现错误时执行;在您的情况下,这个错误是"Receiving end does not exist"
错误在于内容脚本的清单声明中。匹配模式"*://*/"
将仅匹配http
和https
URI上的顶级页面。即http://example.com/
将匹配,而http://example.com/test
将不匹配。
最简单的修复方法是"*://*/*"
,但我建议使用通用匹配模式"<all_urls>"
。
修复后,您的代码仍有一些改进。
- 替换
chrome.extension.onMessage
(已弃用)并使用chrome.runtime.onMessage
- 通过检查
chrome.runtime.lastError
,将sendMessage
部分修改为更有弹性。尽管有广泛的权限,Chrome仍然不会在某些页面中注入任何内容脚本(例如chrome://
页面、Chrome Web Store) - 请确保在内容脚本中使用
"run_at" : "document_start"
,以确保在脚本准备好之前未激发带有"complete"
的onUpdated