我有一个网站的解决方案,得到部署到几个不同的url,每个都是品牌为不同的客户端。部署过程在web中设置各种特定于客户端的配置数据。配置、数据库等。相同的网站代码用于所有客户端,但不同的配置数据意味着网站的外观和行为对每个客户端都不同。
我想在每个客户端基础上设置的一件事是Google通用分析跟踪代码。这是出现在被添加到每个页面的脚本块中的代码(在下面的示例中'UA-12345678-1'):
<script>
(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),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-12345678-1', 'auto');
ga('send', 'pageview');
</script>
我在ViewBag中有跟踪代码,所以如果我准备把这个脚本块直接放在我的HTML页面中(或在我的主布局中),那么插入跟踪代码将是非常容易的:
ga('create', '@ViewBag.GoogleTrackingCode', 'auto');
然而,我正在使用内容安全策略(CSP)功能来锁定网站,并且作为其中的一部分,我已经禁用了内联脚本:所有脚本必须从.js文件加载。
因此,我创建了一个JavaScript文件,其中包含上面脚本块的修改版本,我从HTML页面引用它:(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),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', ga_token, 'auto');
ga('send', 'pageview');
我的计划是在这段脚本运行之前设置ga_token
变量的值。我想我应该把变量值隐藏在HTML的某个地方(在data-*属性中):
<div id="ga-token-data" data-ga-token="@ViewBag.GoogleAnalyticsToken">
…并使用一些JavaScript(当然是在。js文件中)获取该值:
$(document).ready(function () {
ga_token = $("#ga-token-data").data("ga-token");
})
然而,由于执行的顺序,这被证明是棘手的。根据谷歌的文档,脚本块应该放在HTML页面关闭<head>
标签之前,虽然有一些花哨的东西在进行,所以它不试图做任何事情,直到页面加载,ga('create', ...
调用跟踪代码实际上立即执行。因此,ga_token
的值在使用之前没有设置。
理论上,我可以将设置ga_token
值的代码移动到Google脚本块的上方,但是这样做的话,我将在加载DOM之前执行该代码-在这种情况下,我可能无法获取我需要的值。(我当然不能使用jQuery,因为我不加载jQuery库,直到后来)。
还有别的方法吗?
在完全加载之前读取DOM是可以的,操作节点是有风险的。所以你的解决方案可以像这样:
生成的HTML页面
<form id="serverData">
<input type="hidden" name="gaToken" value="@ViewBag.GoogleAnalyticsToken" />
</form>
修改后的分析加载器
<script>
var ga_token = document.getElementById("serverData").gaToken.value;
(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),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', ga_token, 'auto');
ga('send', 'pageview');
</script>
另一个没有jQuery和<form>
的实现…
<html id="dashboard" data-ga_id="{{ settings.GOOGLE_ANALYTICS_ACCOUNT }}">
然后…
var ga_id = document.getElementById("push-dashboard").dataset.ga_id;
if (ga_id) {
(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),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js,'ga');
ga('create', ga_id, 'auto');
ga('send', 'pageview');
}