Chrome扩展程序不会使用网络数据填充表单

时间:2014-08-28 14:05:59

标签: javascript google-chrome-extension messaging

首次使用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>

刷新网页时,我的表单字段显示为空

empty extension form

那么我做错了什么?我该如何调试和修复它?

以下是我的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://*/*"]
  }]
}

1 个答案:

答案 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"密钥。