Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Chrome扩展如何将数据从内容脚本发送到popup.html_Javascript_Jquery_Html_Google Chrome_Google Chrome Extension - Fatal编程技术网

Javascript Chrome扩展如何将数据从内容脚本发送到popup.html

Javascript Chrome扩展如何将数据从内容脚本发送到popup.html,javascript,jquery,html,google-chrome,google-chrome-extension,Javascript,Jquery,Html,Google Chrome,Google Chrome Extension,我知道很多帖子都问过这个问题,但老实说,我不明白。我对JavaScript、Chrome扩展和所有东西都是新手,我有这个类分配。 所以我需要制作一个插件,使用跨域请求计算任何给定页面上的DOM对象。 到目前为止,我已经能够使用Chrome扩展API实现这一点。 现在的问题是我需要在我的popup.html页面上显示contentScript.js文件中的数据。 我不知道如何做到这一点,我试着阅读文档,但在chrome中的消息我就是不知道该怎么做 以下是迄今为止的代码 manifest.json

我知道很多帖子都问过这个问题,但老实说,我不明白。我对JavaScript、Chrome扩展和所有东西都是新手,我有这个类分配。 所以我需要制作一个插件,使用跨域请求计算任何给定页面上的DOM对象。 到目前为止,我已经能够使用Chrome扩展API实现这一点。 现在的问题是我需要在我的popup.html页面上显示contentScript.js文件中的数据。 我不知道如何做到这一点,我试着阅读文档,但在chrome中的消息我就是不知道该怎么做

以下是迄今为止的代码

manifest.json

{
"manifest_version":2,

"name":"Dom Reader",
"description":"Counts Dom Objects",
"version":"1.0",

"page_action": {
    "default_icon":"icon.png",
    "default_title":"Dom Reader",
    "default_popup":"popup.html"
},

"background":{
    "scripts":["eventPage.js"],
    "persistent":false
},

"content_scripts":[
    {
        "matches":["http://pluralsight.com/training/Courses/*", "http://pluralsight.com/training/Authors/Details/*",                                          "https://www.youtube.com/user/*", "https://sites.google.com/site/*", "http://127.0.0.1:3667/popup.html"],
        "js":["domReader_cs.js","jquery-1.10.2.js"]
        //"css":["pluralsight_cs.css"]
    }
],

"permissions":[
    "tabs",
    "http://pluralsight.com/*",
    "http://youtube.com/*",
    "https://sites.google.com/*",
    "http://127.0.0.1:3667/*"
]
popup.html

<!doctype html>
<html>

    <title> Dom Reader </title>    
    <script src="jquery-1.10.2.js" type="text/javascript"></script>
    <script src="popup.js" type="text/javascript"></script>

<body>
    <H1> Dom Reader </H1>
    <input type="submit" id="readDom" value="Read DOM Objects" />

   <div id="domInfo">

    </div>
</body>
</html>
popup.js

$(function (){
$('#readDom').click(function(){
chrome.tabs.query({active: true, currentWindow: true}, function (tabs){
    chrome.tabs.sendMessage(tabs[0].id, {action: "readDom"});

 });
});
});
内容脚本

var totalElements;
var inputFields;
var buttonElement;

chrome.runtime.onMessage.addListener(function (request, sender, sendResponse){
if(request.action == "readDom"){

    totalElements = $("*").length;
    inputFields = $("input").length;
    buttonElement = $("button").length;


}
})

chrome.runtime.sendMessage({ 
action: "show", 
tElements: totalElements, 
Ifields: inputFields, 
bElements: buttonElement 

});

任何帮助都将不胜感激,请避免我所做的任何错误:)

您可以使用localStorage来实现这一点。您可以在浏览器内存中以哈希表格式存储任何数据,然后随时访问它。我不确定我们是否可以从内容脚本(它以前被阻止)访问localStorage,请尝试自己访问。以下是如何通过后台页面完成此操作(我首先将数据从内容脚本传递到后台页面,然后将其保存在localStorage中):

在contentScript.js中:

chrome.runtime.sendMessage({
  total_elements: totalElements // or whatever you want to send
});
在eventPage.js(您的背景页面)中:

然后可以使用localStorage[“total_elements”]在popup.js中访问该变量

在现代浏览器中,您可以直接从内容脚本访问localStorage。然后,您不需要通过后台页面传递数据


关于localStorage的阅读很好:

虽然您的方向肯定是正确的(实际上非常接近尾声),但您的代码中有几个(imo)错误的做法(例如,为这样一个琐碎的任务注入整个库(jquery),声明不必要的权限,对API方法进行超级调用等)。
我没有亲自测试您的代码,但从快速概述来看,我相信更正以下内容可以得到一个有效的解决方案(尽管不是非常接近最优):

  • manifest.json中:更改内容脚本的顺序,将jquery放在第一位。根据

    “js”[…]要注入匹配页面的JavaScript文件列表。按照它们在此数组中出现的顺序注入

    (强调矿山)

  • contentscript.js中:将chrome.runtime.sendMessage({…})移动到
    onMessage
    侦听器回调中


  • 也就是说,以下是我提议的方法:

    控制流:
  • 内容脚本被注入到符合某些条件的每个页面中
  • 一旦注入,内容脚本将向事件页面(也称为非持久性后台页面)发送消息,事件页面将页面操作附加到选项卡
  • 一旦页面操作弹出窗口被加载,它就会向内容脚本发送一条消息,询问它需要的信息
  • 内容脚本处理请求并作出响应,以便页面操作弹出窗口可以显示信息

  • 目录结构:
    manifest.json:
    background.js:
    content.js:
    popup.js:
    popup.html:
    
    DOM信息
    元素总数:
    不适用
    输入元素的数量:
    不适用
    按钮元素的数量:
    不适用
    
    请不要推广使用不推荐使用的chrome.extension.onRequest/sendRequest(顺便说一句,执行之前不会加载非持久性后台页面)。使用chrome.runtime.*代替。@ExpertSystem,如果您看到这些过时的信息,请建议/进行编辑。@Xan:那么,您是[Google chrome Extension]的继任者:)我不喜欢编辑别人的帖子(我觉得太烦人了)。此外,有这么多过时的教程和示例(至少在当时),我发现最好明确说明为什么使用
    .extension.xxx
    不好,而不是仅仅展示正确的方法(有些人可能认为这是“同样好的选择”)。我想这更多的是风格问题。继续努力!哇!谢谢兄弟,现在检查你的方法,我感觉我的代码造成了多少问题。非常感谢,这很有魅力。:)您好,对不起,我已经有一段时间没上了,只是查看了您的评论。我不能接受任何答案。上面说你需要15个信誉点才能做到这一点。你介意帮我解决一个非常类似的问题吗?>我目前的这张照片基本上是这个答案中的你的代码。但是我仍然无法让它工作,似乎也找不到任何好的帮助。为什么你在popupjs中使用
    chrome.tabs.sendMessage
    ,在content.js中使用
    chrome.runtime.onMessage.addListener
    为什么
    .tabs
    用于popupjs,在content中使用
    .runtime
    。js@hkm:因为这就是你发送和接收信息的方式。都在里面。
    chrome.runtime.sendMessage({
      total_elements: totalElements // or whatever you want to send
    });
    
    chrome.runtime.onMessage.addListener(
        function(request, sender, sendResponse){
           localStorage["total_elements"] = request.total_elements;
        }
    );
    
              root-directory/
               |_____img
                     |_____icon19.png
                     |_____icon38.png
               |_____manifest.json
               |_____background.js
               |_____content.js
               |_____popup.js
               |_____popup.html
    
    {
      "manifest_version": 2,
      "name": "Test Extension",
      "version": "0.0",
      "offline_enabled": true,
    
      "background": {
        "persistent": false,
        "scripts": ["background.js"]
      },
    
      "content_scripts": [{
        "matches": ["*://*.stackoverflow.com/*"],
        "js": ["content.js"],
        "run_at": "document_idle",
        "all_frames": false
      }],
    
      "page_action": {
        "default_title": "Test Extension",
        //"default_icon": {
        //  "19": "img/icon19.png",
        //  "38": "img/icon38.png"
        //},
        "default_popup": "popup.html"
      }
    
      // No special permissions required...
      //"permissions": []
    }
    
    chrome.runtime.onMessage.addListener((msg, sender) => {
      // First, validate the message's structure.
      if ((msg.from === 'content') && (msg.subject === 'showPageAction')) {
        // Enable the page-action for the requesting tab.
        chrome.pageAction.show(sender.tab.id);
      }
    });
    
    // Inform the background page that 
    // this tab should have a page-action.
    chrome.runtime.sendMessage({
      from: 'content',
      subject: 'showPageAction',
    });
    
    // Listen for messages from the popup.
    chrome.runtime.onMessage.addListener((msg, sender, response) => {
      // First, validate the message's structure.
      if ((msg.from === 'popup') && (msg.subject === 'DOMInfo')) {
        // Collect the necessary data. 
        // (For your specific requirements `document.querySelectorAll(...)`
        //  should be equivalent to jquery's `$(...)`.)
        var domInfo = {
          total: document.querySelectorAll('*').length,
          inputs: document.querySelectorAll('input').length,
          buttons: document.querySelectorAll('button').length,
        };
    
        // Directly respond to the sender (popup), 
        // through the specified callback.
        response(domInfo);
      }
    });
    
    // Update the relevant fields with the new data.
    const setDOMInfo = info => {
      document.getElementById('total').textContent = info.total;
      document.getElementById('inputs').textContent = info.inputs;
      document.getElementById('buttons').textContent = info.buttons;
    };
    
    // Once the DOM is ready...
    window.addEventListener('DOMContentLoaded', () => {
      // ...query for the active tab...
      chrome.tabs.query({
        active: true,
        currentWindow: true
      }, tabs => {
        // ...and send a request for the DOM info...
        chrome.tabs.sendMessage(
            tabs[0].id,
            {from: 'popup', subject: 'DOMInfo'},
            // ...also specifying a callback to be called 
            //    from the receiving end (content script).
            setDOMInfo);
      });
    });
    
    <!DOCTYPE html>
    <html>
      <head>
        <script type="text/javascript" src="popup.js"></script>
      </head>
      <body>
        <h3 style="font-weight:bold; text-align:center;">DOM Info</h3>
        <table border="1" cellpadding="3" style="border-collapse:collapse;">
          <tr>
            <td nowrap>Total number of elements:</td>
            <td align="right"><span id="total">N/A</span></td>
          </tr>
          <tr>
            <td nowrap>Number of input elements:</td>
            <td align="right"><span id="inputs">N/A</span></td>
          </tr>
          <tr>
            <td nowrap>Number of button elements:</td>
            <td align="right"><span id="buttons">N/A</span></td>
          </tr>
        </table>
      </body>
    </html>