Comparing version 1.0.1 to 1.0.2
@@ -8,3 +8,5 @@ (function (window, document, navigator) { | ||
t = performance && performance.timing, | ||
filterNumber = function (num) { return isNaN(num) || num == Infinity || num < 0 ? void 0 : num; }; | ||
filterNumber = function (num) { return isNaN(num) || num == Infinity || num < 0 ? void 0 : num; }, | ||
randomStr = function (num) { return Math.random().toString(36).slice(-num); }, | ||
randomNum = function (num) { return Math.ceil(Math.random() * (num - 1)) + 1; }; | ||
@@ -14,2 +16,4 @@ // sendGA: collect data and send. | ||
var pv_data = [ | ||
// Random String against Easy Privacy | ||
randomStr(randomNum(4)) + '=' + randomStr(randomNum(6)), | ||
// GA tid | ||
@@ -16,0 +20,0 @@ 'ga=' + window.ga_tid, |
@@ -1,1 +0,1 @@ | ||
!function(t,e,n){var a=t.screen,r=encodeURIComponent,o=Math.max,i=t.performance,d=i&&i.timing,c=function(t){return isNaN(t)||t==1/0||t<0?void 0:t};function g(){var i=["ga="+t.ga_tid,"dt="+r(e.title),"de="+r(e.characterSet||e.charset),"dr="+r(e.referrer),"ul="+(n.language||n.browserLanguage||n.userLanguage),"sd="+a.colorDepth+"-bit","sr="+a.width+"x"+a.height,"vp="+o(e.documentElement.clientWidth,t.innerWidth||0)+"x"+o(e.documentElement.clientHeight,t.innerHeight||0),"plt="+c(d.loadEventStart-d.navigationStart||0),"dns="+c(d.domainLookupEnd-d.domainLookupStart||0),"pdt="+c(d.responseEnd-d.responseStart||0),"rrt="+c(d.redirectEnd-d.redirectStart||0),"tcp="+c(d.connectEnd-d.connectStart||0),"srt="+c(d.responseStart-d.requestStart||0),"dit="+c(d.domInteractive-d.domLoading||0),"clt="+c(d.domContentLoadedEventStart-d.navigationStart||0),"z="+Date.now()];t.__ga_img=new Image,t.__ga_img.src=t.ga_api+"?"+i.join("&")}"complete"===e.readyState?g():t.addEventListener("load",g)}(window,document,navigator); | ||
!function(t,e,n){var r=t.screen,a=encodeURIComponent,o=Math.max,i=t.performance,d=i&&i.timing,c=function(t){return isNaN(t)||t==1/0||t<0?void 0:t},g=function(t){return Math.random().toString(36).slice(-t)},m=function(t){return Math.ceil(Math.random()*(t-1))+1};function s(){var i=[g(m(4))+"="+g(m(6)),"ga="+t.ga_tid,"dt="+a(e.title),"de="+a(e.characterSet||e.charset),"dr="+a(e.referrer),"ul="+(n.language||n.browserLanguage||n.userLanguage),"sd="+r.colorDepth+"-bit","sr="+r.width+"x"+r.height,"vp="+o(e.documentElement.clientWidth,t.innerWidth||0)+"x"+o(e.documentElement.clientHeight,t.innerHeight||0),"plt="+c(d.loadEventStart-d.navigationStart||0),"dns="+c(d.domainLookupEnd-d.domainLookupStart||0),"pdt="+c(d.responseEnd-d.responseStart||0),"rrt="+c(d.redirectEnd-d.redirectStart||0),"tcp="+c(d.connectEnd-d.connectStart||0),"srt="+c(d.responseStart-d.requestStart||0),"dit="+c(d.domInteractive-d.domLoading||0),"clt="+c(d.domContentLoadedEventStart-d.navigationStart||0),"z="+Date.now()];t.__ga_img=new Image,t.__ga_img.src=t.ga_api+"?"+i.join("&")}"complete"===e.readyState?s():t.addEventListener("load",s)}(window,document,navigator); |
{ | ||
"name": "cfga", | ||
"version": "1.0.1", | ||
"version": "1.0.2", | ||
"description": "The Cloudflare Workers implementation of an async Google Analytics", | ||
@@ -5,0 +5,0 @@ "main": "cfga.min.js", |
@@ -32,5 +32,5 @@ # cloudflare-workers-async-google-analytics | ||
window.ga_tid = "UA-XXXXX-Y"; // {String} The trackerID of your site. | ||
window.ga_url = "https://example.com/xxx/"; // {String} The route of your cloudflare workers you just registered before. | ||
window.ga_api = "https://example.com/xxx/"; // {String} The route of your cloudflare workers you just registered before. | ||
</script> | ||
<script src="https://cdn.jsdelivr.net/npm/cfga@1.0.1" async></script> | ||
<script src="https://cdn.jsdelivr.net/npm/cfga@1.0.2" async></script> | ||
``` | ||
@@ -42,2 +42,17 @@ | ||
## Notice | ||
Recently `cloudflare-workers-async-google-analytics` has been blocked by [EasyList](https://github.com/easylist/easylist/commit/2ce2444193f5d479fb131e9dc89bbde9c82c8ad1). Great Job though. So I am going to playing a cat & mouse game. | ||
From `1.0.2` the random string will be added as a parameter to bypass EasyList. Also, this could help, too: | ||
- Add the route `cfga/jquery.js` for your Cloudflare Workers. | ||
- Use setup as below: | ||
```js | ||
window.ga_api = "https://example.com/cfga/jquery.js"; // {String} The route of your cloudflare workers you just registered before. | ||
``` | ||
Block `jquery.js` if you can, haha! | ||
## Advanced | ||
@@ -44,0 +59,0 @@ |
136
worker.js
@@ -1,2 +0,2 @@ | ||
//const AllowedReferrer = 'skk.moe'; | ||
//const AllowedReferrer = 'skk.moe'; // ['skk.moe', 'suka.js.org'] multiple domains is supported in array format | ||
@@ -7,3 +7,26 @@ addEventListener('fetch', (event) => { | ||
async function senData(pvUrl, perfUrl, reqParameter) { | ||
async function senData(event, url, uuid, user_agent, page_url) { | ||
const encode = (data) => encodeURIComponent(decodeURIComponent(data)); | ||
const getReqHeader = (key) => event.request.headers.get(key); | ||
const getQueryString = (name) => url.searchParams.get(name); | ||
const reqParameter = { | ||
headers: { | ||
'Host': 'www.google-analytics.com', | ||
'User-Agent': user_agent, | ||
'Accept': getReqHeader('Accept'), | ||
'Accept-Language': getReqHeader('Accept-Language'), | ||
'Accept-Encoding': getReqHeader('Accept-Encoding'), | ||
'Cache-Control': 'max-age=0' | ||
} | ||
}; | ||
const pvData = `tid=${encode(getQueryString('ga'))}&cid=${uuid}&dl=${encode(page_url)}&uip=${getReqHeader('CF-Connecting-IP')}&ua=${user_agent}&dt=${encode(getQueryString('dt'))}&de=${encode(getQueryString('de'))}&dr=${encode(getQueryString('dr'))}&ul=${getQueryString('ul')}&sd=${getQueryString('sd')}&sr=${getQueryString('sr')}&vp=${getQueryString('vp')}`; | ||
const perfData = `plt=${getQueryString('plt')}&dns=${getQueryString('dns')}&pdt=${getQueryString('pdt')}&rrt=${getQueryString('rrt')}&tcp=${getQueryString('tcp')}&srt=${getQueryString('srt')}&dit=${getQueryString('dit')}&clt=${getQueryString('clt')}` | ||
const pvUrl = `https://www.google-analytics.com/collect?v=1&t=pageview&${pvData}&z=${getQueryString('z')}`; | ||
const perfUrl = `https://www.google-analytics.com/collect?v=1&t=timing&${pvData}&${perfData}&z=${getQueryString('z')}` | ||
await fetch(pvUrl, reqParameter); | ||
@@ -14,49 +37,33 @@ await fetch(perfUrl, reqParameter); | ||
async function response(event) { | ||
const createUuid = () => { | ||
let s = []; | ||
const hexDigits = '0123456789abcdef'; | ||
for (let i = 0; i < 36; i++) { | ||
s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1); | ||
} | ||
s[14] = '4'; // bits 12-15 of the time_hi_and_version field to 0010 | ||
s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1); // bits 6-7 of the clock_seq_hi_and_reserved to 01 | ||
s[8] = s[13] = s[18] = s[23] = '-'; | ||
return s.join(''); | ||
}; | ||
const encode = (data) => encodeURIComponent(decodeURIComponent(data)); | ||
const url = new URL(event.request.url); | ||
const getReqHeader = (key) => event.request.headers.get(key); | ||
const getQueryString = (name) => { | ||
let pattern = new RegExp('(^|&)' + name + '=([^&]*)(&|$)', 'i'); | ||
let r = url.search.substr(1).match(pattern); | ||
return (r !== null) ? unescape(r[2]) : null; | ||
}; | ||
const getCookie = (name) => { | ||
let pattern = new RegExp('(^| )' + name + '=([^;]*)(;|$)'); | ||
let r = (getReqHeader('cookie') || '').match(pattern); | ||
return (r !== null) ? unescape(r[2]) : null; | ||
}; | ||
const Referer = getReqHeader('Referer'); | ||
const user_agent = getReqHeader('User-Agent'); | ||
const ga_tid = getQueryString('ga'); | ||
const ref_host = (() => { | ||
try { | ||
return new URL(Referer).hostname; | ||
} catch (e) { | ||
return '' | ||
} | ||
})(); | ||
const hasUuid = getCookie('uuid'); | ||
const uuid = (hasUuid) ? hasUuid : createUuid(); | ||
let needBlock = false; | ||
let response; | ||
needBlock = (!ref_host || ref_host === '' || !user_agent || !url.search.includes('ga=UA-')) ? true : false; | ||
let needBlock = false; | ||
(!Referer || !user_agent || !ga_tid) ? needBlock = true : needBlock = false; | ||
if (typeof AllowedReferrer !== 'undefined' && AllowedReferrer !== null && AllowedReferrer) { | ||
let _AllowedReferrer = AllowedReferrer; | ||
if (typeof AllowedReferrer !== 'undefined' && AllowedReferrer !== null && AllowedReferrer && Referer) { | ||
(!(Referer.indexOf(AllowedReferrer) > -1)) ? needBlock = true : needBlock = false; | ||
if (!Array.isArray(AllowedReferrer)) _AllowedReferrer = [_AllowedReferrer]; | ||
const rAllowedReferrer = new RegExp(_AllowedReferrer.join('|'), 'g'); | ||
needBlock = (!rAllowedReferrer.test(ref_host)) ? true : false; | ||
console.log(_AllowedReferrer, rAllowedReferrer, ref_host); | ||
} | ||
// Block Request that have no referer, no user-agent and no ga query. | ||
if (needBlock) { | ||
response = new Response('403 Forbidden', { | ||
return new Response('403 Forbidden', { | ||
headers: { 'Content-Type': 'text/html' }, | ||
@@ -66,39 +73,38 @@ status: 403, | ||
}); | ||
} | ||
return response; | ||
} else { | ||
const pvData = `tid=${encode(ga_tid)}&cid=${uuid}&dl=${encode(Referer)}&uip=${getReqHeader('CF-Connecting-IP')}&ua=${user_agent}&dt=${encode(getQueryString('dt'))}&de=${encode(getQueryString('de'))}&dr=${encode(getQueryString('dr'))}&ul=${getQueryString('ul')}&sd=${getQueryString('sd')}&sr=${getQueryString('sr')}&vp=${getQueryString('vp')}`; | ||
const getCookie = (name) => { | ||
const pattern = new RegExp('(^| )' + name + '=([^;]*)(;|$)'); | ||
const r = (getReqHeader('cookie') || '').match(pattern); | ||
return (r !== null) ? unescape(r[2]) : null; | ||
}; | ||
const perfData = `plt=${getQueryString('plt')}&dns=${getQueryString('dns')}&pdt=${getQueryString('pdt')}&rrt=${getQueryString('rrt')}&tcp=${getQueryString('tcp')}&srt=${getQueryString('srt')}&dit=${getQueryString('dit')}&clt=${getQueryString('clt')}` | ||
const createUuid = () => { | ||
let s = []; | ||
const hexDigits = '0123456789abcdef'; | ||
for (let i = 0; i < 36; i++) { | ||
s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1); | ||
} | ||
s[14] = '4'; // bits 12-15 of the time_hi_and_version field to 0010 | ||
s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1); // bits 6-7 of the clock_seq_hi_and_reserved to 01 | ||
s[8] = s[13] = s[18] = s[23] = '-'; | ||
const pvUrl = `https://www.google-analytics.com/collect?v=1&t=pageview&${pvData}&z=${getQueryString('z')}`; | ||
const perfUrl = `https://www.google-analytics.com/collect?v=1&t=timing&${pvData}&${perfData}&z=${getQueryString('z')}` | ||
return s.join(''); | ||
}; | ||
let parameter = { | ||
headers: { | ||
'Host': 'www.google-analytics.com', | ||
'User-Agent': user_agent, | ||
'Accept': getReqHeader('Accept'), | ||
'Accept-Language': getReqHeader('Accept-Language'), | ||
'Accept-Encoding': getReqHeader('Accept-Encoding'), | ||
'Cache-Control': 'max-age=0' | ||
} | ||
}; | ||
const _uuid = getCookie('uuid'); | ||
const uuid = (_uuid) ? _uuid : createUuid(); | ||
// To sent data to google analytics after response id finished | ||
event.waitUntil(senData(pvUrl, perfUrl, parameter)); | ||
// To sent data to google analytics after response id finished | ||
event.waitUntil(senData(event, url, uuid, user_agent, Referer)); | ||
// Return an 204 to speed up: No need to download a gif | ||
response = new Response(null, { | ||
status: 204, | ||
statusText: 'No Content' | ||
}); | ||
// Return an 204 to speed up: No need to download a gif | ||
let response = new Response(null, { | ||
status: 204, | ||
statusText: 'No Content' | ||
}); | ||
if (!hasUuid) { | ||
const cookieContent = `uuid=${uuid}; Expires=${new Date((new Date().getTime() + 365 * 86400 * 30 * 1000)).toGMTString()}; Path='/';`; | ||
response.headers.set('Set-Cookie', cookieContent) | ||
} | ||
if (!_uuid) response.headers.set('Set-Cookie', `uuid=${uuid}; Expires=${new Date((new Date().getTime() + 365 * 86400 * 30 * 1000)).toGMTString()}; Path='/';`); | ||
return response | ||
} | ||
return response | ||
} |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
16744
145
108