在注入的脚本

时间:2015-10-22 07:27:06

标签: javascript google-chrome-extension

我的扩展程序的内容脚本通过<script>元素(main.js)将脚本注入gmail页面。注入的脚本需要来自选项页面的localStorage脚本的扩展程序options.js中存储的设置中的一些数据。

选项页面脚本可以成功使用读取loadDomain()值的localStorage.domain函数。此函数在公共函数脚本storage.js中定义,该脚本也通过<script>元素与main.js一起注入gmail页面。

问题loadDomain()在注入的undefined中调用而不是存储在选项页面上的实际值时返回main.js

的manifest.json:

  "permissions": [
    "tabs", "https://mail.google.com/*", "http://*/*, https://*/*"
  ],
  "background": {
    "scripts": ["js/background.js"],
    "persistent": false
  },
  "browser_action": {
    "default_icon": {
      "38": "icon.png"
    },
    "default_title": "SalesUp",
    "default_popup": "index.html"
  },
  "content_scripts": [
    {
      "matches": ["https://mail.google.com/*"],
      "js": ["content.js"]
    }
  ],
  "web_accessible_resources": [
    "js/jquery-1.10.2.min.js",
    "js/gmail.js",
    "main.js"
  ]
}

1 个答案:

答案 0 :(得分:1)

聊天讨论显示loadDomain()是从<script>注入的main.js调用的。

问题的一部分原因是Chrome从内容脚本以及后台页面中隔离了网页(包括其脚本,也包括注入的脚本)。另一部分是localStorage在每个域上都是不同的(实际上,origin),因此在扩展的选项页面中存储的内容在Web上下文中运行的内容脚本中不可用页面只能访问localStorage,而不能访问localStorage

解决方案包括两件事:

  1. 而不是localStorage使用chrome.storage.sync来存储扩展程序设置,或chrome.storage.local来存储不应该同步到Google服务器的临时内容。

  2. 使用自定义DOM事件在注入的脚本和内容脚本之间进行通信。

  3. 代码:

    注入的main.js:

    • 发送请求(detail密钥可用于传递某些数据):

      document.dispatchEvent(new CustomEvent("getDomains", {detail: {something: "hello"}}));
      
    • 听取回复:

      document.addEventListener("receiveDomains", function(e) {
          var domains = e.detail;
          console.log("Received domains", domains);
          ...............
      });
      

    内容脚本content.js:

    document.addEventListener("getDomains", function(e) {
        chrome.storage.sync.get("domains", function(result) {
            document.dispatchEvent(new CustomEvent("receiveDomains", {detail: result.domains}));
        });
    });
    

    选项页面options.js:

    function save_options() {
        chrome.storage.sync.set({domains: ["domain1", "domain2"]});
    }