javascript - Chrome 扩展将外部 javascript 添加到当前页面的 html

标签 javascript dom google-chrome-extension google-analytics content-script

我正在通过我的 chrome 扩展程序在页面末尾添加一些外部 JavaScript。然后,外部 JavaScript 尝试将一些数据发回服务器,但没有成功。

JavaScript 想要获取当前页面的 url 和 referrer 并将其发回服务器。

任何人都可以告诉我这里有什么问题吗?如果不可能的话,我该如何将当前页面的数据发布回服务器。

list .json

{
  "name": "Website Safety",
  "version": "1.0",
  "manifest_version": 2,
  "description": "The Website Safety Extension.",
  "browser_action": {
    "name": "View the website information for ",
    "default_icon": "icon.png",
    "default_popup": "popup.html"
  },
  "permissions": [
    "tabs", "http://*/*", "https://*/*"
  ],
  "background": {
  //  "scripts": ["refresh.js"]
    "page": "background.html"
  },
  "content_security_policy": "script-src 'self' https://ssl.google-analytics.com; object-src 'self'",
  //"background_page": "background.html"

  "content_scripts": [
    {
      "matches": ["<all_urls>"],
      "js": ["contentScript.js"]
    }
  ]
}

现在是 contentScript.js

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-31046309-1']);
_gaq.push(['_setAllowLinker', true]);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
//ga.src = 'https://ssl.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();

var _Hasync= _Hasync|| [];
_Hasync.push(['Histats.start', '1,1342541,4,0,0,0,00000000']);
_Hasync.push(['Histats.fasi', '1']);
_Hasync.push(['Histats.track_hits', '']);
(function() {
var hs = document.createElement('script'); hs.type = 'text/javascript'; hs.async = true;
hs.src = ('http://s10.histats.com/js15_as.js');
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(hs);
})();

最佳答案

内容脚本在页面范围内运行(see also),它们在您的扩展程序和网页之间的上下文中运行。

由于跟踪器属于“注入(inject)脚本”类型,因此它们完全在网页上下文中运行。但是 _gaqHasync变量没有。因此,跟踪脚本无法读取配置变量。

有两(三)种方法可以修复它。

  1. 使用 this method 注入(inject)您的代码(如问题中所张贴的) . 不鼓励使用此方法,因为您的脚本会覆盖常用的全局变量。使用此方法实现您的脚本将破坏许多网站上的跟踪 - 请勿使用它
  2. 在内容脚本范围内完全运行代码:
    两种选择:
    1. 在扩展中包含外部文件
    2. 在扩展中包含外部文件,并实现自动更新功能。

方法一:完全本地复制

manifest.json (只显示相关部分):

{
  "name": "Website Safety",
  "version": "1.0",
  "manifest_version": 2,
  "description": "The Website Safety Extension.",
  "permissions": [
    "tabs", "http://*/*", "https://*/*"
  ],
  "content_scripts": [
    {
      "matches": ["<all_urls>"],
      "js": ["ga-config.js", "ga.js", "js15_as.js"]
    }
  ]
}

ga-config.js ,定义变量如下:

var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-31046309-1']);
_gaq.push(['_setAllowLinker', true]);
_gaq.push(['_trackPageview']);

var _Hasync= _Hasync|| [];
_Hasync.push(['Histats.start', '1,1342541,4,0,0,0,00000000']);
_Hasync.push(['Histats.fasi', '1']);
_Hasync.push(['Histats.track_hits', '']);

下载https://ssl.google-analytics.com/ga.js , 并将其保存为 ga.js .
下载 http://s10.histats.com/js15_as.js , 并将其保存为 js15_as.js .

方法 2:注入(inject)最新的 GA

如果您想拥有最新版本的 GA,则必须使用复杂的代码注入(inject)方式,因为内容脚本不能从外部 URL 包含。。

此答案的旧版本依赖于背景页面和 chrome.tabs.executeScript 为此目的,但自 Chrome 20 以来,出现了一种更好的方法:使用 chrome.storage 用于缓存 JavaScript 代码的 API。 为了保持代码更新,我将在存储中存储一个“最后更新”的时间戳;你也可以使用 chrome.alarms API 而不是。

注意:不要忘记在您的扩展程序中包含外部文件的本地副本,以防用户没有互联网连接等。 如果没有互联网连接,Google分析无论如何都行不通。

内容脚本, activate-ga.js .

var UPDATE_INTERVAL = 2 * 60 * 60 * 1000; // Update after 2 hour

// Retrieve GA from storage
chrome.storage.local.get({
    lastUpdated: 0,
    code: ''
}, function(items) {
    if (Date.now() - items.lastUpdated > UPDATE_INTERVAL) {
        // Get updated file, and if found, save it.
        get('https://ssl.google-analytics.com/ga.js', function(code) {
            if (!code) return;
            chrome.storage.local.set({lastUpdated: Date.now(), code: code});
        });
    }
    if (items.code) // Cached GA is available, use it
        execute(items.code);
    else // No cached version yet. Load from extension
        get(chrome.extension.getURL('ga.js'), execute);
});

// Typically run within a few milliseconds
function execute(code) {
    try { window.eval(code); } catch (e) { console.error(e); }
    // Run the rest of your code.
    // If your extension depends on GA, initialize it from here.
    // ...
}

function get(url, callback) {
    var x = new XMLHttpRequest();
    x.onload = x.onerror = function() { callback(x.responseText); };
    x.open('GET', url);
    x.send();
}

最小 list 文件:

{
  "name": "Website Safety",
  "version": "1.0",
  "manifest_version": 2,
  "permissions": [
    "tabs", "http://*/*", "https://*/*"
  ],
  "content_scripts": [
    {
      "matches": ["<all_urls>"],
      "js": ["activate-ga.js"]
    }
  ],
  "web_accessible_resources": ["ga.js"]
}

同样的方法可以用于其他跟踪器。最低权限要求:

  • https://ssl.google-analytics.com/ga.js ,所以应该在权限部分添加。 https://*/*<all_urls>也足够了。
  • 可选: unlimitedStorage - 如果你想用 chrome.storage 存储大量数据.

关于javascript - Chrome 扩展将外部 javascript 添加到当前页面的 html,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18044897/

相关文章:

javascript - Ionic v1 ng-model 不更新

JavaScript - 二进制搜索每次都会挂起

javascript - 如何在更新卡片的弹出窗口中获取 2 个 div 值。

javascript - JSDoc 和 JavaScript 单例文档

javascript - 未选中时如何动态更改选项卡标题?

google-maps - 实例化时,Google Map 元素是否必须在 DOM 中?

javascript - 如何使用 JavaScript 从网页中获取突出显示的文本

javascript - 卸载在沙盒 Chrome 应用程序中不可用

javascript - 更改 chrome 扩展程序图标

javascript - 如何从外部 VBScript 在网页中执行 Javascript 函数