Расширение Chrome добавляет внешний javascript на текущую страницу html
Я добавляю некоторые внешние JavaScript в конец страницы через мое расширение chrome. Внешний JavaScript затем пытается отправить некоторые данные обратно на сервер, однако это не происходит.
JavaScript хочет получить URL-адрес текущей страницы и реферера и отправить его обратно на сервер.
Кто-нибудь может посоветовать мне, что здесь не так, и как я могу, если это невозможно, таким образом, я могу отправить данные с текущей страницы обратно на сервер.
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"]
}
]
}
теперь 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);
})();
Ответы
Ответ 1
Сценарии содержимого не выполняются в области страницы (см. Также), они выполняются в контексте между вашим расширением и веб-страницей.
Поскольку трекеры относятся к типу "Injected script", они полностью запускаются в контексте веб-страницы. Но переменные _gaq
и Hasync
этого не делают. В результате сценарии отслеживания не могут читать переменные конфигурации.
Есть два (три) способа это исправить.
- Введите свой код (как написано в вопросе), используя этот метод. Использование этого метода для ваших целей не рекомендуется, потому что ваш скрипт перезаписывает обычно используемую глобальную переменную. Реализация вашего сценария с использованием этого метода нарушит отслеживание на многих веб-сайтах - не используйте его.
- Полностью запустите код в рамках скрипта содержимого:
Два варианта: - Включить внешние файлы в расширение
- Включить внешние файлы в расширение, а также реализовать функцию автоматического обновления.
Способ 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, необходимо использовать сложный способ внедрения кода, поскольку скрипты содержимого не могут быть включены из внешнего URL-адреса.
Для этой цели старая версия этого ответа основывалась на фоновой странице и chrome.tabs.executeScript
, но после Chrome 20 стал доступен лучший метод: используйте API chrome.storage
для кэширования кода JavaScript. Чтобы обновлять код, я буду хранить отметку времени "последнего обновления" в хранилище; Вы также можете использовать API chrome.alarms
.
Примечание. Не забудьте включить локальную копию внешнего файла в ваше расширение, если у пользователя нет подключения к Интернету и т.д. Без подключения к Интернету 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
.
Ответ 2
Я прочитал эту ветку: https://groups.google.com/a/chromium.org/forum/#!topic/chromium-extensions/yc-ouDqfMw0 и обнаружил, что существует официальный метод chrome для добавления сценария аналитики в страница, и это не в официальных документах.
Вы можете обратиться к этому расширению для справки: https://github.com/GoogleChrome/chrome-app-samples/tree/master/samples/analytics, и оно использует эту библиотеку: https://github.com/GoogleChrome/chrome- платформа-аналитика
в основном вы вручную включаете скрипт локально:
<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);
};
}
примечание: очевидно, у вас должна быть отключена функция 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;
Ответ 3
2015 Update
Новый фрагмент Universal Analytics определенно может обрабатывать несколько трекеров, поэтому при условии, что вы дадите свое уникальное имя и запустите все Код аналитики в контексте страницы, вам должно быть хорошо идти.
// 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 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 предполагает, что вы добавляете аналитику в встроенный блок script, тогда как здесь вы добавляете его из содержимого script.