Расширение Chrome добавление внешнего javascript в html текущей страницы

Я добавляю внешний JavaScript в конец страницы через расширение chrome. Затем внешний JavaScript пытается отправить некоторые данные обратно на сервер, однако этого не происходит.

JavaScript хочет получить url текущей страницы и реферера и отправить его обратно на сервер.

может ли кто-нибудь посоветовать мне, что здесь не так, и как я могу, если это невозможно, я могу опубликовать данные с текущей страницы обратно на сервер.

манифест.в 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);
})();

3 ответов


скрипты контент не выполнить в области страницы (см. также), то они выполняются в контексте, между расширением и веб-страницы.

поскольку трекеры имеют тип "Injected script", они полностью запускаются в контексте веб-страницы. Но ... --4--> и Hasync переменные не делают. В результате скрипты треков не могут считывать переменные конфигурации.

есть два (три) способа исправить он.

  1. введите свой код (как указано в вопросе), используя этот метод. Использование этого метода для вашей цели -уныние, потому что ваш скрипт перезаписывает часто используемую глобальную переменную. Реализация вашего скрипта с помощью этого метода будет перерыв отслеживание на многих сайтах - не использовать.
  2. полностью запустите код в рамках сценария содержимого:
    Два опции:
    1. включить внешние файлы в расширении
    2. включить внешние файлы в расширение, а также реализовать функцию автоматического обновления.

метод 1: полностью локальная копия

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: впрыскивание современного GA

если вы хотите иметь актуальную версию GA, должен использоваться запутанный способ ввода кода, потому что скрипты контента невозможно включить из внешнего URL.

An старая версия этого ответа опиралась на фоновую страницу и chrome.tabs.executeScript для этой цели, но начиная с Chrome 20, стал доступен лучший метод: используйте chrome.storage API для кэширования кода JavaScript. Чтобы сохранить код обновленным, я сохраню" последнюю обновленную " метку времени в хранилище; вы также можете использовать chrome.alarms API вместо этого.

Примечание: не забудьте включить локальную копию внешнего файла в расширение, в если у пользователя нет подключения к интернету и т. д. без подключения к интернету Google Analytics все равно не будет работать.

сценарий содержимого, 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();
}

минимальный файл манифеста:

{
  "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.

Я прочитал эту тему: https://groups.google.com/a/chromium.org/forum/#!topic/chromium-extensions/yc-ouDqfMw0 и обнаружил, что существует официальный метод chrome для добавления сценария аналитики на страницу, и его нет в официальных документах.

вы можете обратиться к этому расширению для справки:https://github.com/GoogleChrome/chrome-app-samples/tree/master/analytics и он использует этот lib: https://github.com/GoogleChrome/chrome-platform-analytics

в основном вы вручную включаете скрипт локально:

  <script src="your_path/google-analytics-bundle.js"></script>
  <script src="main.js"></script>

затем вы вызываете некоторые библиотечные функции:

var service, tracker, out;

function initAnalyticsConfig(config) {
  document.getElementById('settings-loading').hidden = true;
  document.getElementById('settings-loaded').hidden = false;

  var checkbox = document.getElementById('analytics');
  checkbox.checked = config.isTrackingPermitted();
  checkbox.onchange = function() {
    config.setTrackingPermitted(checkbox.checked);
  };
}

примечание: по-видимому, вы есть чтобы иметь функцию opt out https://github.com/GoogleChrome/chrome-platform-analytics/wiki#add-privacy-support-aka-opt-out

function startApp() {
  // Initialize the Analytics service object with the name of your app.
  service = analytics.getService('ice_cream_app');
  service.getConfig().addCallback(initAnalyticsConfig);

  // Get a Tracker using your Google Analytics app Tracking ID.
  tracker = service.getTracker('UA-XXXXX-X');

  // Record an "appView" each time the user launches your app or goes to a new
  // screen within the app.
  tracker.sendAppView('MainView');
}

window.onload = startApp;

обновление 2015

новая Универсальный Аналитики фрагмент определенно может обрабатывать несколько трекеров, поэтому предположим, что вы дадите свое уникальное имя и запустите все аналитики код в контексте страницы, вы должны быть хорошо идти.

// add Universal Analytics to the page (could be made conditional)
runFunctionInPageContext(function () {
  (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
  (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o);
  a.async=1;a.src=g;document.documentElement.appendChild(a)
  })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
});

// all Google Analytics calls should use our tracker name  
// and be run inside the page's context
runFunctionInPageContext(function () {
  ga('create', 'UA-12345-6', 'auto', {'name': 'myTracker'});
  ga('myTracker.send', 'pageview'); // note the prefix
});

// simple helper function
function runFunctionInPageContext(fn) {
  var script = document.createElement('script');
  script.textContent = '(' + fn.toString() + '());';
  document.documentElement.appendChild(script);
  document.documentElement.removeChild(script);
}

обратите внимание, есть одна небольшая модификация в фрагменте аналитики для использования document.documentElement вместо первого <script> элемент. Это потому, что google предполагает вы добавляете аналитику в блок встроенного сценария, а здесь вы добавляете ее из сценария содержимого.