首次使用Chrome扩展程序 - 我正在进行书签扩展。我希望我的content script
在从网页上抓取数据后将数据发送到我的后台弹出页面。
我关注official documentation for message passing。所以我有一个内容脚本background.js
,代码如下:
var pageInfo = {
'title': document.title,
'url': window.location.href,
'summary': window.getSelection().toString()
};
// Send the information back to the extension
chrome.runtime.sendMessage(pageInfo, function(response){
console.log(response);
});
然后我的后台页面脚本main.js
拦截此消息,如下所示:
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
$('#title').val(request.title); // this is not working
console.log('request: ', request);
console.log('sender: ', sender);
sendResponse('funky');
}
);
现在数据正在来回传递。上面的控制台语句有效!但我的表单字段#title
仍未填充。我的背景页面html(弹出式)表单是这样的:
<form id="addbookmark">
<p><label for="title">Title</label><br />
<input type="text" id="title" name="title" size="50" value="" /></p>
<p><label for="url">Url</label><br />
<input type="text" id="url" name="url" size="50" value="" /></p>
<p><label for="summary">Summary</label><br />
<textarea id="summary" name="summary" rows="6" cols="35"></textarea></p>
<p><label for="tags">Tags</label><br />
<input type="text" id="tags" name="tags" size="50" value="" /></p>
<p>
<input id="save" type="submit" value="Save Bookmark" />
<span id="status-display"></span>
</p>
</form>
<script src="jquery.min.js">
</script>
<script src="main.js"></script>
刷新网页时,我的表单字段显示为空
那么我做错了什么?我该如何调试和修复它?
以下是我的manifest.json
供参考
{
"name": "plugin name",
"version": "0",
"description": "What do I do as an extension",
"background": {
"scripts": ["jquery.min.js", "main.js"]
},
"manifest_version": 2,
"browser_action": {
"name": "Manipulate DOM",
"icons": ["icon.png"],
"default_icon": "icon.png",
"default_popup": "background.html"
},
"permissions": [
"tabs",
"http://*/",
"https://*/"
],
"web_accessible_resources": ["jquery.min.map"],
"content_scripts": [ {
"js": [ "jquery.min.js", "background.js" ],
"matches": [ "http://*/*", "https://*/*"]
}]
}
答案 0 :(得分:2)
请阅读Architecture Overview和直截了当。
命名内容脚本 background.js
以及弹出页面 background.html
非常令人困惑,我们可以从它有效地困扰了你。
后台网页是一个不可见的页面,只要Chrome运行,该页面就会处于活动状态。它与弹出页面不同,它是在您点击浏览器操作时创建的,并在失去焦点时被销毁。
因此,在两者上运行相同的脚本(main.js
)很少有用 - 它们用于不同的目的。
目前发生的情况是:您的内容脚本在页面加载时运行一次,并发送消息。此时,可能是弹出窗口已关闭,因此您的背景页面会收到消息和答案。请注意,此时它会抛出错误,因为后台页面上不存在#title
。如果您在chrome://extensions
打开扩展名列表并启用开发者模式,则可以看到此信息。
如果您的弹出窗口完全在内容脚本执行时打开,那么它还接收该消息并按预期工作。
编辑:更好的解决方案
更好的解决方案是保留原始逻辑,但是从弹出窗口以编程方式注入脚本。为什么更好?从弹出窗口调用脚本时,activeTab
会为您授予该选项卡的权限。这意味着需要更少的可怕权限。
1)将您的内容脚本放入content.js
// content.js
var pageInfo = {
'title': document.title,
'url': window.location.href,
'summary': window.getSelection().toString()
};
// Send the information back to the extension
chrome.runtime.sendMessage(pageInfo);
2)从清单中删除content_scripts
并调整权限:
"permissions": [ "activeTab" ],
3)在弹出代码中,注入脚本并侦听消息:
// popup.js
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
$('#title').val(request.title);
// ...
}
);
// Injection defaults to current tab, no need to query
chrome.tabs.executeScript({file: "jquery.min.js"}, function(){
chrome.tabs.executeScript({file: "content.js"});
});
最终结果:在您单击按钮之前,没有permission warnings,标签中没有“杂散代码”。
注意:使用此解决方案,您根本不需要背景页面。在您需要它之前,只需从清单中删除"background"
密钥。