Chrome扩展程序将外部JavaScript添加到当前页面的HTML

我通过我的Chrome扩展在页面的末尾添加了一些外部JavaScript。 然后外部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 = '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 = ('js15_as.js'); (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(hs); })(); 

内容脚本不在页面的范围内运行( 另请参阅 ),它们在扩展和网页之间的上下文中运行。

由于跟踪器是“注入脚本”types的,所以这些完全运行在网页的上下文中。 但_gaqHasyncvariables不。 因此,跟踪脚本无法读取configurationvariables。

有两(三)种方法来解决它。

  1. 使用这种方法注入您的代码(如发布在问题中)。 不鼓励使用这种方法,因为你的脚本覆盖了一个常用的全局variables。 使用这种方法实现您的脚本将打破许多网站的跟踪 – 不要使用它
  2. 在内容脚本的范围内完全运行代码:
    两个选项:
    1. 将外部文件包含在扩展中
    2. 将外部文件包含在扩展中,并执行自动更新function。

方法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 ,如下定义variables:

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

下载ga.js ,并将其保存为ga.js
下载js15_as.js ,并保存为js15_as.js

方法2:注入最新的GA

如果您想要获得最新版本的GA,则必须使用注入代码的复杂方式,因为内容脚本不能包含在外部URL中

这个答案的旧版本依赖于背景页面和chrome.tabs.executeScript来实现此目的,但是从Chrome 20开始,更好的方法已经可用了:使用chrome.storage API来cachingJavaScript代码。 为了保持代码更新,我将在存储中存储“上次更新”的时间戳; 您也可以使用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('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"] } 

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

  • 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-分析

基本上你手动在本地包含脚本:

  <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); }; } 

注意:显然,你必须有一个退出functionhttps://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更新

全新的Universal Analytics代码段绝对可以处理多个跟踪器 ,因此,假设您为您提供了一个唯一的名称并在页面的上下文中运行了所有的 Google 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'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>元素进行了一些修改。 这是因为谷歌假设你在内联脚本块中添加分析,而在这里你从内容脚本中添加分析。