示例七:加入统计代码
建议先阅读:【老鼠讲故事系列 004】油猴子加入统计代码
第一步:判断用户设置
如果用户拒绝追踪,那就不要插入统计代码。
if (!navigator.doNotTrack) {
// 这里是后续的代码
}
如果 navigator.doNotTrack
结果为 1,则禁止跟踪。0 为允许,未设置为 null
。
第二步:插入一个框架
这是因为我们可以对框架进行更好的操作,比如修改网址和标题,而不会影响到用户对页面浏览的体验。而这些修改可以让统计携带回更多有效的数据。
这并不是打算做什么坏事,是因为我们要跟踪的是脚本的使用情况,而脚本相关的一些数据并不能够通过普通的统计来获得。
框架中的页面最好是一个十分分简单,并且访问速度非常快的页面,比较好的选择就是一些网站的 404 页面,我使用了,提供统计服务的网站的某个页面。这样如果这个页面都无法访问,那么统计代码大概率也无法生效。
const href = 'https://c.statcounter.com/' + window.location.hostname + '/';
const iframe = document.createElement('iframe');
iframe.src = href;
iframe.style = 'display: none !important; width: 0; height: 0;';
document.body.appendChild(iframe);
就是很简单的在页面中追加一个元素,在加入之前对元素的一些属性进行必要的设置。这里我将当前页面的域名部分附加在了这个页面网址之后,我们可以以类似的方式附加一些有效信息。当然要确保最后这个网址所获得的页面符合我们的预期。
记得设置这个框架隐藏起来,不要显示。
第三步:对这个页面进行修改
首先我们要把上一个页面放入脚本的匹配( @match )之中。然后我们的脚本要可以在框架下运行。
如果发现当前页面的网址和我们预设的这个页面相匹配。就去修改这个页面的标题,让它携带更多信息,比如我让他携带了脚本管理器的名称、版本、当前脚本的版本号等。
if (/^https:\/\/c\.statcounter\.com\//i.test(window.location.href)) {
// 在标题中放入脚本相关信息
document.title = GM_info.scriptHandler+
'-' + GM_info.version +
'-' + GM_info.script.version
}
第四步:加入统计代码
这里要注意,不能直接通过修改 html 代码来插入,因为可能导致脚本没有正确的运行,所以还是要像上面那样,通过追加元素的方式进行插入,但在这之前可以先简单清空一下 body
元素中的内容。下面代码中项目编号和加密的识别码,我都用变量替代了。
document.body.innerHTML = '';
const scriptA = document.createElement('script');
scriptA.type = 'text/javascript';
scriptA.innerHTML =
`var sc_project=` + sc_project + `;
var sc_invisible=1;
var sc_security="` + sc_security + `";
var sc_https=1;
var sc_remove_link=1;
`;
document.body.append(scriptA);
第五步:优化兼容性
一般统计代码在脚本无法正确运行的时候,会采取备用方式,就是插入一张图片。这里我们准备好这张图片,当上面的代码没有能够正确注入时,就插入这一张图片。同样的,代码中项目编号和加密的识别码,我都用变量替代了。
scriptB.type = 'text/javascript';
scriptB.src = 'https://www.statcounter.com/counter/counter.js';
document.body.append(scriptB);
scriptB.onerror = () => {
const img = document.createElement('img');
img.src =
'https://c.statcounter.com/' +
sc_project +
'/0/' +
sc_security +
'/1/#' +
Number(new Date());
img.style = 'display: none';
document.body.append(img);
第六步:降低干扰
这个干扰是双方向的,一方面在页面打开时就插入统计代码,虽然影响本身是很小的,但终归会让页面打开的速度稍微慢一丢丢。如果等页面彻底打开之后,再去加入统计代码,这样对用户的影响会更小。
同时如果用户还没有等这个页面彻底打开,就将页面关闭了,那么对这个页面进行统计也没有什么必要。所以我将插入框架的时间进行了一个延迟。
第七步:控制次数
但是我只是希望了解用户使用的脚本管理器和一些版本号的情况。就没有必要用户访问,每一个页面都进行统计。所以我设置了每天只统计一次。但这一点需要脚本管理器提供数据存储的接口才能够实现。
首先我获取当前的时间,然后除以一天的好秒数,将结果取整数作为一个标记。
然后查看脚本存取的数据里的标记和这个标记是否相同,如果相同那么意味着今天已经做过统计了,就无需再插入统计代码。如果不同,那么插入统计代码,同时更新储存的这个标记为当前标记。
以上便是在脚本中放入统计代码的思路分析,都不复杂,但是这些细节我也确实思考了好久,尽自己的可能去降低对用户的影响。
下面放出相对完整的代码:
// 如果用户拒绝追踪,则不添加统计代码
if (!navigator.doNotTrack) {
// 如果是预定页面,则进行改造
if (/^https:\/\/c\.statcounter\.com\//i.test(window.location.href)) {
// 在标题中放入脚本相关信息
document.title = GM_info
? GM_info.scriptHandler.replace(/monkey/i, '') +
'-' +
GM_info.version +
'-' +
GM_info.script.version
: navigator.userAgent + '-' + scriptVersion;
// 插入统计代码
document.body.innerHTML = '';
const scriptA = document.createElement('script');
scriptA.type = 'text/javascript';
scriptA.innerHTML =
`var sc_project=` + sc_project + `;
var sc_invisible=1;
var sc_security="` + sc_security + `";
var sc_https=1;
var sc_remove_link=1;
`;
document.body.append(scriptA);
const scriptB = document.createElement('script');
scriptB.type = 'text/javascript';
scriptB.src = 'https://www.statcounter.com/counter/counter.js';
document.body.append(scriptB);
scriptB.onerror = () => {
const img = document.createElement('img');
img.src =
'https://c.statcounter.com/' +
sc_project +
'/0/' +
sc_security +
'/1/#' +
Number(new Date());
img.style = 'display: none';
document.body.append(img);
};
} else {
// 非预定页面则插入统计代码
setTimeout(() => {
const todayMark = Math.floor(+new Date() / 864e5); // 获取今日时间标记
const recordMark = GM_getValue('timeMark', 0); // 获取记录中时间标记
if (todayMark !== recordMark) {
// 时间标记不同则插入统计代码
const href =
'https://c.statcounter.com/' + window.location.hostname + '/';
const iframe = document.createElement('iframe');
iframe.src = href;
iframe.style = 'display: none !important; width: 0; height: 0;';
document.body.appendChild(iframe);
GM_setValue('timeMark', todayMark); // 将新的时间标记存入记录
}
}, delay);
}
}