我如何删除 Google Analytics 并仍然有良好的数据可供分析我的解决方案,无需分析即可进行分析其他人如何做到您如何在您的网站上进行分析?

2025-05-25

我如何删除 Google Analytics 并仍然保留有用的数据进行分析

我的解决方案:无需分析即可进行分析

其他人如何做

您如何分析您的网站?

就在最近,我开通了我的谷歌分析账户,并将其添加到这个网站。我想了解一下我网站访客的情况。但与谷歌搜索控制台相比,我并没有太多感兴趣的信息。

事实上,我有点担心。直接添加分析数据合法吗?添加分析数据很容易,只需在我的页面中添加一个脚本标签即可。在欧盟,需要告知用户非必要的 Cookie。设置 Cookie 之前,需要征求用户的同意。然而,分析数据是使用静态 HTML 标签添加的,无法控制哪些 Cookie 会被立即设置。

我不确定是否应该在询问用户后使用一些客户端 javascript 动态创建该脚本标签。并且分析是否仍然有效?

在互联网上搜索不使用 Cookie 的分析工具时,很多网站都建议使用motomo。这是一个用 PHP 和 MySQL 实现的非常好的解决方案。但对于我的小博客来说,搭建这么大的服务器似乎有点太麻烦了。另外,我还得确保它保持最新状态,并采取一些更严格的安全措施。对于实际的生产应用来说,Google Analytics 和motomo都是更好的选择,因为它们可以记录大量你现在不知道将来会用到的数据。

我的解决方案:无需分析即可进行分析

我在我的网站上添加了一个小脚本。它使用本地存储而不是 Cookie。本地存储不能用于在其他网站上追踪用户。所以我认为这应该符合法律规定。而且,本地存储中没有任何可以识别用户的信息。


// analytics
const lastViewTime = parseInt(localStorage.getItem('lastViewTime')) || 0;
const viewCount = parseInt(localStorage.getItem('viewCount')) || 0;
const lastViewPage = localStorage.getItem('lastViewedPage') || '';

localStorage.setItem('lastViewTime', Date.now())
localStorage.setItem('viewCount', viewCount+1)
localStorage.setItem('lastViewedPage', document.location.href);

fetch('/api/pageViews', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    page: document.location.href,
    viewCount,
    time: Date.now(),
    lastViewTime: lastViewTime,
    lastViewPage: lastViewPage,
    userLanguage: navigator.language,
    userAgent: navigator.userAgent,
    referrer: document.referrer,
    dayTime: parseInt(req.body.dayTime+''),
  })
})  
  .then( r => r.json())
  .then(data => console.log('pageViewResult:', data);

Enter fullscreen mode Exit fullscreen mode

在服务器上,我只是将这些信息转储到一个 jsonl 文件中,也就是说每行一个 json 日志条目。它可以通过 轻松转换为 csv 进行分析excel。绘制一些图表,或者按周、月、间隔进行计数。

const router = require('express').Router();
module.export.pageViewRouter = router;

const file = fs.createWriteStream(fileName, {
  flags: 'a' // 'a' means appending (old data will be preserved)
});

router.post('/api/pageViews',async (req,res) => {
  res.json(true);
  file.write(JSON.stringify({
    page: body.page,
    time: Date.now(),
    userLanguage: (req.body.userLanguage+'').substr(0,500),
    userAgent: userAgent.id,
    viewCount: parseInt(req.body.viewCount),
    lastViewTime: parseInt(req.body.lastViewTime+''),
    lastViewPage: req.body.lastViewPage,
    referrer: req.body.referrer,
    dayTime: new Date().getHours()
  })+'\n', (err)=>{
    if(err) console.log(err)
  });
});
Enter fullscreen mode Exit fullscreen mode

你看到了吗,我没有检查浏览器是否支持fetchAPI 和现代箭头函数?我考虑了一下,觉得这个可选功能不需要考虑旧浏览器的兼容性。

您会看到所有正在存储的字段。这些都是我想出来的,我觉得很有意思。说实话,显示的 API 与 tnickel.de 上运行的 API 并不完全相同,但概念是这样的。在我的运行实现中,我会验证收到的数据,将 URL 和用户代理字符串存储到一个单独的JSON 文件数据库中,并将 ID 写入日志文件。但通过这个例子,您可以了解如何自己实现服务器端。

其他人如何做

巧合的是,dev.to 社区刚刚被问到关于分析工具的问题。我描述了我的小解决方案。Charanjit Chana回复了这条评论,说他正在使用类似的解决方案。以下是我在他的网站源代码中找到的(代码经过了压缩,所以我稍微格式化了一下):

function allowedToTrack() {
  return !(window.doNotTrack || navigator.doNotTrack || navigator.msDoNotTrack || window.external && "msTrackingProtectionEnabled" in window.external) || "1" != window.doNotTrack && "yes" != navigator.doNotTrack && "1" != navigator.doNotTrack && "1" != navigator.msDoNotTrack && !window.external.msTrackingProtectionEnabled()
}
if (allowedToTrack()) {
  let o = Math.floor(8999999 * Math.random()) + 1e6;
  let n = window.innerHeight + "x" + window.innerWidth; 
  // this request then set the cookie. 
  fetch("https://123.charanj.it/xyz/api/" + o + "/false/" + n);
}

if (void 0 !== console) {
  console.log("%c👋 Hey!", "font-size: 16px; font-weight: 600");
  console.log("%cIf you can see this I would love to hear from you.", "font-size: 16px;");
  console.log("%cYou can find me at https://twitter.com/cchana.", "font-size: 16px;");
  console.log("%cUse the hashtag #cchanaconsole", "font-size: 16px;");
  console.log("%c🤙 🖖", "font-size: 16px;");
}
Enter fullscreen mode Exit fullscreen mode

作为开发主管,他似乎有意为团队寻找新的开发人才。我喜欢allowToTrack在发出分析请求之前使用的功能。该请求会设置一个 Cookie,这样多个页面浏览量就可以与同一个用户和会话关联。我不知道英国脱欧后的规定,但我相信在德国,需要一个额外的弹出横幅。除了我之外,Charanjit 也对用户的屏幕分辨率感兴趣,以便了解页面的优化目标。

您如何分析您的网站?

现在你已经了解了两种构建客户端以收集分析信息的有效方法。希望通过本文,你能了解这个网站是如何进行分析的,而无需在互联网上追踪用户,甚至追踪到他们最黑暗的梦境。

一月更新

在许多评论中,人们指出,将身份数据存储在本地存储中与直接将其存储为 cookie 在法律上是类似的。

我以为这样应该没问题,因为这意味着你不会被其他网站追踪。但无论如何,我没有存储个人身份信息。或者说,我存储了?

我认为现在你必须真正相信网站运营商试图欺骗你。如果他们真的想,直接显示一个 Cookie 横幅来获得你的同意会更容易。

假设我想追踪你在我的(你的)网站上的个人旅程。记录的信息包括浏览次数、浏览时间、当前和最后一个 URL。这些信息可以描绘出一段旅程,但与个人无关。然而,当我或其他提供此类解决方案的网络服务提供商计划将旅程与用户信息关联起来时,可以通过以下方式实现:在需要身份验证的页面上提供功能或内容。在身份验证时,就有可能将该用户与其之前的旅程联系起来。这可不是什么好事。

这里有一些想法,可以让您更难将旅程与用户联系起来,但仍然可以为用户保持良好的洞察力。

  1. 将时间戳四舍五入为一分钟或几分钟。
  2. 和 viewCount 一样。我想出了下面的函数。该函数仍然能让你知道访客是常客还是随机访客。
function normalizeViewCound(count){
  const sqrt = parseInt(Math.sqrt(count).toString())
  return sqrt * sqrt;
}
Enter fullscreen mode Exit fullscreen mode

以下是我目前在我的网站上使用的版本:


const lastViewTime = parseInt(localStorage.getItem('lastViewTime')) || 0;
const viewCount = parseInt(localStorage.getItem('viewCount')) || 0;
const lastViewPage = localStorage.getItem('lastViewedPage') || '';

const now = Date.now();
const visitTime = now - (now % 60000); // normalize the time

localStorage.setItem('lastViewTime', visitTime)
localStorage.setItem('viewCount', viewCount + 1)
localStorage.setItem('lastViewedPage', document.location.href);

function normalizeViewCound(count){
  const sqrt = parseInt(Math.sqrt(count).toString())
  return sqrt * sqrt;
}

fetch('/api/pageViews', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    page: document.location.href,
    viewCount: normalizeViewCound(viewCount),
    time: visitTime,
    lastViewTime: lastViewTime,
    lastViewPage: lastViewPage,
    userLanguage: navigator.language,
    userAgent: navigator.userAgent,
    referrer: document.referrer,
    dayTime: new Date(visitTime).getHours()
  })
}).then(function (r) {
  return r.json();
}).then(function (data) {
  console.log('pageViewResult:', data)
});
Enter fullscreen mode Exit fullscreen mode

通过这些改变,我和你们用户的隐私都得到了极大的改善。然而,我无法在此提供法律建议,也无法确定这些措施是否足够。或许,更简单的办法是直接向用户显示 Cookie 信息,然后厚颜无耻地追踪他们最私密的梦境。

文章来源:https://dev.to/bias/how-i-removed-google-analytics-and-still-have-good-data-to-analyze-1c50
PREV
JavaScript 中的错误处理(Golang 风格)
NEXT
2020 年帮助我完成工作的 Web 开发工具 我每天使用的 4 个 Git 片段 在 VS Code 中构建第二个大脑 一切都是状态机 使用 RamdaJS 进行函数式编程 就这样结束了!