[译]只使用 CSS 进行用户追踪

标签: css 用户 | 发表时间:2020-10-25 09:00 | 作者:黄梵高
出处:https://juejin.im/frontend

来源:作者

在浏览器里进行用户追踪会引发关于隐私和数据保护一次又一次的讨论。类似 Google 分析之类的工具几乎可以抓到所有需要的内容,包括来源,语言,设备,停留时间等等。

但是,想获取一些感兴趣的信息,你可能不需要任何外部追踪器,甚至不需要 JavaScript。本文将向你展示,即便用户禁用了 JavaScript,依然可以跟踪用户的行为。

追踪器通常如何工作

通常,这类追踪器分析工具要使用到 JavaScript。因此,大多数等信息可以十分轻松的读取,并且可以立刻发送到服务端。

这就是为什么出现越来越多的方式来阻止浏览器中跟踪器的原因。。某些勇敢的浏览器或者某些 chrome 扩展程序会阻止跟踪器的加载,例如 google 分析。 其中一个诀窍是,例如 Google 分析总是从外部集成的,一段来自 Google CDN 的 JavaScript 代码。嵌入的 URL 总是相同的,因此可以轻松的将它阻止掉。

因此追踪器总是会用 JavaScript 做些什么。甚至如果你通过阻止 URL 限制了追踪器,网站拥有者可能会通过将 JavaScript 代码嵌入页面的方式继续使用。最强有力的保护措施就是禁用 JavaScript,虽然这可能会付出非常大的代价。

最后,我们仍然可以不使用 JavaScript 追踪一些内容,而是使用一些 CSS 技巧。当然 CSS 并不是为追踪使用的,让我们开始实践吧。

找到设备类型信息

媒体查询应该是每一个 web 开发者都知道的。有了这个,我们可以让 CSS 代码只在某些确定的屏幕条件下执行。所以我们可以为智能手机或平板电脑等,编写自己的查询条件。

我们所有 CSS 追踪器背后的魔法就是它们的属性,比如我们可以将一段 URL 作为属性值。有一个比较好的例子是 background-image 的属性,它允许我们为一个元素设置一张背景图片。这张图片从一段 URL 获取,并且在执行过程中,它是优先请求的,因此会向这个 URL 地址: background-image: url('/dog.png'); 发送一个 GET 请求。

但是最后,没人强制我们必须确保这段 URL 链接确实能访问到图片。服务器甚至不需要对请求进行应答,但我们仍然可以响应 GET 请求,向数据库输入数据。

   const express = require("express");
const app = express();

app.get("/", (req, res) => {
  res.sendFile(__dirname + "/index.html");
});

app.get("/mobile", (req, res) => {
  console.log("is mobile")
  res.end()
)}
        
app.listen(8080)
复制代码

至于后端,我使用 Express.js 作为服务器。它提供了一个简单的 HTML 网站;如果访问设备是智能手机,则会调用 mobile 路由。并且我们的后端是唯一使用 JavaScript 的地方。

   @media only screen and (max-width: 768px) {
  body {
    background-image: url("http://localhost:8080/mobile");
  }
}
复制代码

在我们的 index.html 文件中,我们有了上面的 CSS 代码。只有在用户设备与媒体查询匹配的时候,才请求背景图片。

如果现在一部智能手机访问这个页面,媒体查询会执行,并发送请求背景图片的请求,同时服务端会输出它是智能手机。这些操作是完全没有使用 JavaScript。

并且由于我们不会发送一张图片作为回应,这个网站内容将不会有任何改变。

找到操作系统信息

现在变得更加疯狂,我们能大致找到用户操作系统通过它支持的字体。在 CSS 中,我们可以使用多种后备方案,换句话说,可以指定多种字体。如果第一个在系统上不起作用,浏览器将会尝试第二个。

font-family: BlinkMacSystemFont, "Arial"; 当我在我们的网站嵌入这句代码时,我的 MacBook 使用第一种苹果标准字体,这字体只可以在 Mac OS 上使用。当在我的 Windows PC 上,Arial 正常使用。

当使用字体时,我们可以定义自定义字体以及从什么地方加载它。Google 字体的工作方式相同,如果我们要从某处使用自定义的字体,必须先从服务器加载它。并且我们可以多次使用字体。

    @font-face {
  font-family: Font2;
  src: url("http://localhost:8080/notmac");
 }

body {
  font-family: BlinkMacSystemFont, Font2, "Arial";
}
复制代码

这里我们为了全部的 body 部分设置了字体。从逻辑上讲,你只能使用一种字体。以至于在 MacBook 上,使用的是第一种字体,即系统自己的字体。在类似 Windows 的其他系统上,系统检查字体是否存在。当然,肯定不存在,因此尝试使用下一种我们自己定义的字体。它仍然不得不从服务端加载,因此我们的 CSS 代码会再次触发 GET 请求。

毕竟 Font2 不是一个真正的字体,因此我们继续尝试,最终将使用 Arial 字体。尽管如此,我们仍然可以在用户无感知的情况下,使用一个合理的字体。

追踪元素信息

到目前为止,我们所做的事情就是当用户抵达网站,立即对信息进行分析。当然,我们也可以利用 CSS 对单独的事件做出应对。

如下所示,我们可以使用下面的例子,来分析鼠标悬停或活动事件。

   <head>
  <style>
    #one:hover {
      background-image: url("http://localhost:8080/one-hovered/");
    }
  style>
head>
<body>
  <button id="one">Hover mebutton>
body>
复制代码

当鼠标每次悬停在按钮上,它会一次又一次的设置背景图片,一个 GET 请求也随之发出。

我们可以在按钮被点击时,做相同的事情。在 CSS 中,这就是活动事件。

   <head>
  <style>
    #one:active {
      background-image: url("http://localhost:8080/one-clicked/");
    }
  style>
head>
<body>
  <button id="one">Click mebutton>
body>
复制代码

还有一系列其他事件。例如,悬停事件几乎适用在每一个元素上。因此从理论上来讲,我们可以追踪用户的每一个行为。

犹豫计时器

使用更多的代码,我们可以组合这些事件并且了解更多信息,而不仅仅是发生了那些事件。

对于许多网站主来说,更感兴趣的是,用户在看到或悬停在元素上犹豫了多久才点击某个元素。通过下面的代码,我们可以测量用户悬停后点击所花费的时间。

   let counter;
app.get("/one-hovered", (req, res) => {
  counter = Date.now();
});

app.get("/one-active", (req, res) => {
  console.log("Clicked after", (Date.now() - counter) / 1000, "seconds");
});
复制代码

用户一旦悬停,计时器就会启动。最后,我们可以算出直到点击过了几秒。

你可能会认为由于它嵌入在 CSS 代码中,统计的可能并不准确,但事实并非如此。由于请求的体积十分小,并且立即作用在服务器上。我试了几次并测量了时间,最终测量的结果非常精确。

很惊人,不是吗?

让整个功能更美观

为了不被发现,使用不显眼的 URL 是十分有意义的。 最后,每个人都可以看到完整的前端代码。

你也可以使用自己想到的关键词,代替个别特别显眼的路由单词。最后,前端和后端的 URL 必须匹配。

对于上面的示例,我始终将我自己的路由用作 GET 请求。这样十分清晰明白。一种更优雅的方式是使用 URL 的查询,这在 CSS 当中也适用。

   @font-face {
  font-family: Font2;
  src: url("http://192.168.2.110:8080/os/mac");
  /* or: */ 
  src: url("http://192.168.2.110:8080/?os=mac");
}
复制代码

有关 Express.js 中 URL 查询与参数的相关的详细教程可以在这里查看:

在 Express.js 中 URL 的查询与参数

如果发现译文存在错误或其他需要改进的地方,欢迎到 掘金翻译计划 对译文进行修改并 PR,也可获得相应奖励积分。文章开头的 本文永久链接 即为本文在 GitHub 上的 MarkDown 链接。


掘金翻译计划 是一个翻译优质互联网技术文章的社区,文章来源为 掘金 上的英文分享文章。内容覆盖 AndroidiOS前端后端区块链产品设计人工智能等领域,想要查看更多优质译文请持续关注 掘金翻译计划官方微博知乎专栏

相关 [css 用户] 推荐:

[译]只使用 CSS 进行用户追踪

- - 掘金前端
在浏览器里进行用户追踪会引发关于隐私和数据保护一次又一次的讨论. 类似 Google 分析之类的工具几乎可以抓到所有需要的内容,包括来源,语言,设备,停留时间等等. 但是,想获取一些感兴趣的信息,你可能不需要任何外部追踪器,甚至不需要 JavaScript. 本文将向你展示,即便用户禁用了 JavaScript,依然可以跟踪用户的行为.

CSS图形

- GLORY - 酷壳 - CoolShell.cn
下面的示例展示了使用纯CSS制作的各种图形,你可以自由地修改文中的CSS代码. 经测试,IE9, Chrome, FF, Safari都可以正常显示. 五角星形 via Kit MacAllister. 心形 via Nicolas Gallagher. 无穷大 via Nicolas Gallagher.

用 Compass 寫 CSS

- Jay - Blog.XDite.net
最近在開發一個新產品,整體來說應該是接近寫完了,不過越接近完工,抓 IE 系列的 bug 就越是挫折. 朋友 @evenwu 就來洗我要不要換成 Compass,說這東西超神奇,超好用,還可以把 IE bug 殺光光. 其實之前就久仰 Compass 大名了,只是文件實在看起來太他媽的眼花繚亂,因為專案進度一直在跑,不太敢貿然換掉寫 CSS 的方式.

CSS 入门

- - 博客 - 伯乐在线
级联样式表非常简单,也就是 (X)HTML 网页之上的分层设计. 使样式表 “级联”,这样您就可以跨站点应用它 — 也就是说,将样式应用到网站,它就会自行应用到每个网页的每个元素. ●XHTML:可扩展 HTML. 对于网站,将数据与设计分离是一个重要的概念:数据使用 (X)HTML 发送到 浏览器,而设计使用 CSS 应用到该数据.

css 圆角

- - CSDN博客推荐文章
作者:kangquan2008 发表于2012-2-20 22:32:24 原文链接. 阅读:6 评论:0 查看评论.

CSS架构

- - 博客 - 伯乐在线
英文原文: CSS Architecture,编译: CSDN-张红月. Philip Walton 在AppFolio担任前端工程师,他在Santa Barbara on Rails的聚会上提出了CSS架构和一些最佳实践,并且在工作中一直沿用. 擅长CSS的Web开发人员不仅可以从视觉上复制实物原型,还可以用代码进行完美的呈现.

CSS总结

- - CSDN博客Web前端推荐文章
         接触过一段CSS,为简单理解,将CSS说成两步,一步是你做个“记号”,另一步是根据记号设置样式.      网页的内容和样式是分开的. “记号”便是能标识网页中某部分内容的关键字词(选择器),而根据记号设置样式呢,就是按图索骥根据记号设置标识的那部分内容的样式.     这段时间练习的每个CSS小例子,或是用id做记号,或是用name,或是用class,只有有了这些所谓的记号,CSS设定的样式才有用,.

CSS基础

- - CSDN博客Web前端推荐文章
1、引入CSS的四种方式. 行内样式、内嵌样式、链接样式、导入样式. 基本选择器:标签选择器,ID选择器,类选择器,通用选择器. 通用选择器:*{css代码}. 通用选择器作用:对整个网页中所有HTML标签进行样式定义. 常见用法:定义*{margin:0;padding:0}通用样式,并置于CSS文件最顶端,用于对HTML内所有的标签进行重置以保证页面能兼容多种浏览器.

CSS命名规范

- - BlogJava-首页技术区
网上整理的比较好的css命名规则,为css代码的规范化做参考,增加代码的可读性. 容器: container 页头:header 内容:content/container. 页面主体:main 页尾:footer 导航:nav . 侧栏:sidebar 栏目:column 左右中:leftright center .

css基础入门

- - CSDN博客推荐文章
css是Cascading Style Sheets的缩写,是一种用于为Html文档定义布局的样式表语言. Css是一种样式表语言,用于为html定义布局. Css弥补了Html对标记属性控制的不足. Css将网页内容与样式实现分离,使得网页设计更加明了、简洁. Css可以精确控制网页布局,如行间距、字间距、段落缩进和图片定位等.