【问题标题】:Chrome extension not populating form with web dataChrome 扩展程序未使用 Web 数据填充表单
【发布时间】:2014-08-28 14:05:58
【问题描述】:

第一次使用 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://*/*"]
  }]
}

【问题讨论】:

  • 为什么我被否决了?请解释
  • 我正在写一个答案,但我投了反对票,因为我发现这个问题没有用。
  • 好的。我还在等你的回答...@Xan
  • 我用更好的解决方案更新了我的答案。

标签: javascript google-chrome-extension messaging


【解决方案1】:

请阅读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" 键即可。

【讨论】:

  • 注意:你的内容脚本甚至不需要jQuery,你可以省略第一个executeScript
  • 好的,确实有效。你能告诉我将我的 ajax 调用放在哪里以将数据提交到我的服务器吗?我可以把它做成一个单独的脚本吗?
  • 我会用一个单独的脚本来制作它,我会放在后台页面中(这样即使弹出窗口被破坏,它也可以安全地执行)。您可以使用消息传递或chrome.runtime.getBackgroundPage 从弹出窗口中调用它。
  • 所以我将把它标记为正确答案。但是您能否澄清一些事情:a)在这个插件的上下文中,popup.js 到底是什么?它应该控制什么? b) content.js 是内容脚本——我现在明白了。那么我应该只将它用于消息传递吗?
  • 您的最后两个问题毫无意义。 a)popup.js 是弹出窗口中包含的脚本的更合理名称 b)您应该将内容脚本用于您需要的任何内容
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-11-10
  • 1970-01-01
  • 2019-06-09
  • 1970-01-01
  • 1970-01-01
  • 2018-02-27
  • 1970-01-01
相关资源
最近更新 更多