Chrome 扩展程序将外部 javascript 添加到当前页面的 html [英] Chrome extension adding external javascript to current page's html

查看:28
本文介绍了Chrome 扩展程序将外部 javascript 添加到当前页面的 html的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在通过我的 chrome 扩展程序向页面末尾添加一些外部 JavaScript.然后,外部 JavaScript 会尝试将一些数据发送回服务器,但这并没有发生.

JavaScript 想要获取当前页面的 url 和引用链接并将其发送回服务器.

任何人都可以请教我这里出了什么问题,如果不可能,我如何才能将当前页面的数据发布回服务器.

manifest.json

<代码>{"name": "网站安全","版本": "1.0",清单版本":2,"description": "网站安全扩展.",浏览器动作":{"name": "查看网站信息","default_icon": "icon.png","default_popup": "popup.html"},权限":[标签"、http://*/*"、https://*/*"],背景": {//"脚本": ["refresh.js"]页面":背景.html"},"content_security_policy": "script-src 'self' https://ssl.google-analytics.com; object-src 'self'",//"background_page": "background.html"内容脚本":[{"匹配": [""],"js": ["contentScript.js"]}]}

现在 contentScript.js

var _gaq = _gaq ||[];_gaq.push(['_setAccount', 'UA-31046309-1']);_gaq.push(['_setAllowLinker', true]);_gaq.push(['_trackPageview']);(功能() {var ga = document.createElement('script');ga.type = '文本/javascript';ga.async = 真;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', '']);(功能() {var hs = document.createElement('script');hs.type = '文本/javascript';hs.async = 真;hs.src = ('http://s10.histats.com/js15_as.js');(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(hs);})();

解决方案

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

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

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

  1. 使用 这个方法.不鼓励为您的目的使用此方法,因为您的脚本会覆盖常用的全局变量.使用此方法实现您的脚本将破坏许多网站上的跟踪 - 不要使用它.
  2. 在内容脚本范围内完全运行代码:
    两种选择:

    1. 在扩展中包含外部文件
    2. 在扩展中包含外部文件,并实现自动更新功能.

方法一:完全本地复制

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

<代码>{"name": "网站安全","版本": "1.0",清单版本":2,"description": "网站安全扩展.",权限":[标签"、http://*/*"、https://*/*"],内容脚本":[{"匹配": [""],"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:注入最新的 GA

如果您想拥有最新版本的 GA,则必须使用复杂的代码注入方式,因为内容脚本无法从外部 URL 中包含.>

此答案的旧版本依赖于背景页面和 chrome.tabs.executeScript 用于此目的,但自 Chrome 20 以来,有更好的方法可用:使用 chrome.storage API 来缓存 JavaScript 代码.为了保持代码更新,我将在存储中存储一个上次更新"时间戳;您也可以改用 chrome.alarms API.

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

内容脚本,activate-ga.js.

var UPDATE_INTERVAL = 2 * 60 * 60 * 1000;//2小时后更新//从存储中检索 GAchrome.storage.local.get({最后更新:0,代码: ''},功能(项目){if (Date.now() - items.lastUpdated > UPDATE_INTERVAL) {//获取更新的文件,如果找到,则保存它.get('https://ssl.google-analytics.com/ga.js', function(code) {如果(!代码)返回;chrome.storage.local.set({lastUpdated: Date.now(), code: code});});}if (items.code)//缓存 GA 可用,使用它执行(项目.代码);else//还没有缓存版本.从扩展加载get(chrome.extension.getURL('ga.js'), 执行);});//通常在几毫秒内运行函数执行(代码){尝试 { window.eval(code);} catch (e) { console.error(e);}//运行其余的代码.//如果你的扩展依赖于 GA,从这里初始化它.//...}函数获取(网址,回调){var x = new XMLHttpRequest();x.onload = x.onerror = function() { callback(x.responseText);};x.open('GET', url);x.send();}

最小清单文件:

<代码>{"name": "网站安全","版本": "1.0",清单版本":2,权限":[标签"、http://*/*"、https://*/*"],内容脚本":[{"匹配": [""],"js": ["activate-ga.js"]}],web_accessible_resources":[ga.js"]}

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

  • https://ssl.google-analytics.com/ga.js,因此应在权限部分添加.https://*/* 也足够了.
  • 可选:unlimitedStorage - 如果您想使用 chrome.storage 存储大量数据.

I am adding some external JavaScript to the end of the page via my chrome extension. The external JavaScript then tries to post some data back to the server, however that is not taking place.

The JavaScript wants to get the url of the current page and the referrer and post it back to the server.

Can anyone please advice me what is wrong here and how can I if not possible this way can I post data from the current page back to the server.

manifest.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"]
    }
  ]
}

for now 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);
})();

解决方案

Content scripts do not run in the scope of the page (see also), they run in a context between your extension and the web page.

Since the trackers are of the type "Injected script", these fully run in the context of the web page. But the _gaq and Hasync variables don't. As a result, the track scripts cannot read the configuration variables.

There are two (three) ways to fix it.

  1. Inject your code (as posted in the question) using this method. Using this method for your purpose is discouraged, because your script overwrites a commonly used global variable. Implementing your script using this method will break the tracking on many websites - do not use it.
  2. Fully run the code within the scope of a content script:
    Two options:

    1. Include the external files in the extension
    2. Include the external files in the extension, plus implement an auto-update feature.

Method 1: Fully local copy

manifest.json (only the relevant parts are shown):

{
  "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"]
    }
  ]
}

In ga-config.js, define the variables as follows:

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', '']);

Download https://ssl.google-analytics.com/ga.js, and save it as ga.js.
Download http://s10.histats.com/js15_as.js, and save it as js15_as.js.

Method 2: Injecting a Up-to-date GA

If you want to have an up-to-date version of GA, a convoluted way of injecting the code has to be used, because Content scripts cannot be included from an external URL.

An old version of this answer relied on the background page and chrome.tabs.executeScript for this purpose, but since Chrome 20, a better method has become available: Use the chrome.storage API to cache the JavaScript code. To keep the code updated, I will store a "last updated" timestamp in the storage; you can also use the chrome.alarms API instead.

Note: Do not forget to include a local copy of the external file in your extension, in case the user does not have an internet connection, etc. Without an internet connection, Google Analytics wouldn't work anyway.

Content script, 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();
}

Minimum manifest file:

{
  "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"]
}

The same method can be used for other trackers. The minimum permission requirements:

  • https://ssl.google-analytics.com/ga.js, so that should be added at the permissions section. https://*/* or <all_urls> is also sufficient.
  • optional: unlimitedStorage - If you want to store a large piece of data with chrome.storage.

这篇关于Chrome 扩展程序将外部 javascript 添加到当前页面的 html的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆