平台 · 方法论Platform · Methodology · 2026-08-10

隐私如何保护:一套把数据留在你设备上的架构How Your Privacy Is Protected: An Architecture That Keeps Data on Your Device

大多数测评网站的做法是:你答题 → 数据上传服务器 → 服务器算结果 → 存进数据库。我们的做法完全相反——这篇技术短文解释为什么,以及「不收集数据」在工程上意味着什么。

三层隐私架构

1. 计算全部在本地

六个测评的计分逻辑全部是浏览器端 JavaScript:你的每一道答案只存在于内存与 localStorage 中。关掉页面、清除浏览器数据,一切随之消失。服务器上没有你的任何作答记录。

2. 分享数据走 URL 片段

想把结果发给朋友?我们把答案编码成几个字符,放进网址的 # 片段里。HTTP 协议规定:片段永远不会发送到服务器,也不会出现在 Referer 头和访问日志里。你的答案在设备之间「旅行」,但从不「经过」我们。

3. 匿名计数,且可拒绝

为了改进产品,我们记录匿名的功能使用计数:事件名 + 测评名 + 时间戳。不含身份、不含作答内容、不含 IP 关联档案。并且遵循浏览器「请勿追踪」设置——开启 DNT 后统计完全关闭。

为什么选择这条更难的路

因为测评数据天然敏感:它包含你的行为倾向、关系模式、精神状态的自评。这些数据一旦泄露,伤害远大于购物偏好。与其承诺「我们会保管好」,不如从架构上做到「我们拿不到」——最好的数据保护,是数据根本不在你手里。

代价与取舍

这条路线放弃了:跨设备同步、找回结果、精准推送。我们认为值得。技术方案会持续公开在我们的 GitHub 仓库,欢迎审查。

隐私不是功能,是架构。

一张「数据去向」清单

「不收集数据」这四个字太抽象,把它拆成一张清单会更清楚——你在这站产生的每一类数据,去向分别是:

作答选项与结果。每一道题的点击、计分中间值、最终类型,只存在于两个地方:页面内存和浏览器的 localStorage。我们的本地存储键名统一以 xyx: 开头——你可以随时按 F12 打开开发者工具,在 Application → Local Storage 里亲眼看到它们。清空浏览器数据,或者换一个浏览器,一切归零。

语言偏好。你切换中/英文的偏好同样存在 localStorage(xyx:lang),作用只有一个:下次打开时界面记得用哪种语言。

匿名事件计数。唯一会离开设备的数据:事件名、测评名、时间戳,攒够一小批后发到 /api/v1/events。没有身份信息、没有作答内容、没有可以拼出「你是谁」的字段。开启浏览器的 Do Not Track 后,连这些都不发。

服务器侧。整站托管在 Cloudflare Pages 上,本质是静态文件分发:服务器的工作是把 HTML、CSS、JS 发给你,然后忘了你来过。没有账号系统、没有数据库、没有 cookie——所以也没有「数据泄露」可发生的那一头。

URL 片段分享是怎么工作的

这套机制值得单独拆开讲,因为它是整套架构里最巧的一环。

以「AI 人格」为例:16 道题、每题 4 个选项,每道题用 2 个比特表示,16 题压缩成 4 个字节,再编码成 8 个字符的短码(形如 P1xxxxxxxx)。你点「邀请好友 PK」时,这个码被拼进网址的 # 后面,比如 #invite=P1xxxxxxxx。

关键在于 HTTP 协议本身的规定:# 之后的内容属于浏览器本地,从不随请求发送。朋友点开链接,服务器只收到「把页面给我」,至于 # 后面带了什么,服务器从头到尾不知道——解码和还原全部发生在对方的浏览器里。你的答案在设备之间「旅行」,但从不「经过」我们。

这个设计同时意味着边界:链接拿在手里的人就能看到编码内容(虽然要懂点编码才能读回原答案),所以分享链接请只发给信任的人;而且受链接长度限制,片段里只能塞下答案本身,塞不下你的备注和留言。

这套架构做不到什么

诚实是这套方案的一部分,所以它的短板也该摆在台面上。

没有跨设备同步。手机上测出的结果不会自动出现在电脑上——因为没有账号把两台设备认作「同一个人」。想搬运结果,唯一的通道是分享链接。

没有找回功能。清掉浏览器数据、换浏览器、全程用无痕模式,结果都会消失。没有账号就意味着没有「忘记密码」也没有「找回记录」——你的数据只在你自己的设备上活着。

我们无法主动联系你。没有邮箱、没有推送、没有短信。上了新测评,只能等你下次自己来发现。我们把这看作特性而不是缺陷:一个不能打扰你的产品,也不会出卖你。

安全边界依赖你的设备。localStorage 不联网、不共享,但它就躺在这台设备的浏览器里——能物理拿到你设备并打开浏览器的人,理论上可以看到你测过什么。在公共或共享设备上用完,记得清理浏览器数据。

常见疑问

「没有账号,怎么知道哪些功能被用得多?」靠那套匿名计数:「某测评被完成了一次」会记为一条「事件名 + 测评名 + 时间戳」。我们能看出哪个测评受欢迎、哪一步流失多,但拼不出任何个人画像——这是产品迭代所需的最小数据集。

「分享链接安全吗?会不会被中间人看到?」链接本身经过 HTTPS 加密传输;# 片段不进服务器日志、不进 Referer。真正的暴露面只有一个:你把链接发给了谁、贴在了哪里。所以原则不变——只发给你信任的人。

「我测完又清了一遍浏览器,你们那边还有存档吗?」没有。我们这边从来就没有过你的答案——不是删了,是根本没收到过。这是「数据不离开设备」最直接、也最诚实的推论。

体验一下这套架构:回到首页选一个测评。

What most assessment sites do is this: you answer questions → the data is uploaded to a server → the server computes the result → it is stored in a database. We do the exact opposite. This short technical note explains why, and what "we don't collect data" actually means in engineering terms.

A three-layer privacy architecture

1. All computation happens locally

The scoring logic for all six assessments is browser-side JavaScript: every answer you give exists only in memory and in localStorage. Close the page or clear your browser data and everything disappears with it. There is no record of your answers on our servers.

2. Sharing goes through the URL fragment

Want to send your result to a friend? We encode the answers into a handful of characters and place them in the # fragment of the URL. The HTTP specification is explicit about this: the fragment is never sent to the server, and it appears in neither the Referer header nor the access logs. Your answers "travel" between devices, but they never "pass through" us.

3. Anonymous counts, and you can opt out

To improve the product, we record anonymous feature-usage counts: event name + assessment name + timestamp. No identity, no answer content, no IP-linked profile. We also honor the browser's Do Not Track setting — once DNT is enabled, analytics shut off completely.

Why take the harder road

Because assessment data is inherently sensitive: it contains your behavioral tendencies, your relationship patterns, and your self-rated mental state. If such data leaks, the harm goes well beyond leaked shopping preferences. Rather than promising "we'll keep it safe," we made it architecturally true that "we cannot get it" — the best data protection is data that never sits in our hands at all.

The costs and the trade-offs

This route gives up cross-device sync, result recovery, and targeted messaging. We think it is worth it. Our technical approach stays public in our GitHub repository, and review is welcome.

Privacy is not a feature. It is an architecture.

A "where does the data go" inventory

"We don't collect data" is too abstract as a slogan. As an inventory it's clearer — here's where every class of data you generate on this site ends up:

Your answers and results. Every option you tap, every intermediate score, the final type — these exist in exactly two places: page memory and the browser's localStorage. Our storage keys all start with xyx: — press F12 any time and see them for yourself under Application → Local Storage. Clear your browser data or switch browsers and it all goes to zero.

Language preference. Your Chinese/English toggle lives in localStorage too (xyx:lang), and does exactly one thing: remember which language the interface should open in next time.

Anonymous event counts. The only data that ever leaves the device: event name, assessment name, timestamp — batched and posted to /api/v1/events. No identity, no answer content, no fields that could be assembled into "who you are." Enable your browser's Do Not Track and even these stop.

The server side. The whole site is hosted on Cloudflare Pages — essentially static file distribution. The server's job is to hand you HTML, CSS and JS, then forget you visited. No account system, no database, no cookies — which means there is no end at which a "data breach" could happen.

How URL-fragment sharing actually works

This mechanism deserves its own section, because it's the cleverest piece of the architecture.

Take the AI Persona test: 16 questions, 4 options each. Each answer fits in 2 bits, so all 16 compress into 4 bytes, encoded as an 8-character code (it looks like P1xxxxxxxx). When you tap "invite a friend," the code is appended after the # in the URL — for instance #invite=P1xxxxxxxx.

The crucial part is a rule of HTTP itself: everything after the # belongs to the local browser and is never sent with the request. When your friend opens the link, our server only receives "give me the page" — whatever the fragment carried, the server never learns. Decoding and reconstruction happen entirely inside the friend's browser. Your answers "travel" between devices, but they never "pass through" us.

The design has boundaries worth stating: whoever holds the link holds the encoded answers (reading them back takes some decoding skill, but the link itself is the payload) — so share links only with people you trust. And because URL length is finite, the fragment can carry the answers and nothing else — no notes, no messages.

What this architecture cannot do

Honesty is part of the design, so its shortcomings belong on the table too.

No cross-device sync. A result produced on your phone will not appear on your computer — with no account, there is nothing to recognize two devices as "the same person." The only bridge is a share link.

No recovery. Clear your browser data, switch browsers, or live in private mode, and results are gone. No account means no "forgot password" and no "restore my records" — your data lives only on the device in front of you.

We can't reach out to you. No email, no push notifications, no SMS. When a new assessment ships, you discover it the next time you visit. We count that as a feature: a product that cannot interrupt you also cannot sell you out.

The security boundary is your device. localStorage never goes online and is never shared — but it physically sits inside this device's browser. Anyone with hands-on access to your device who opens the browser could, in principle, see what you tested. On shared or public machines, clear your browser data when you're done.

Common questions

"With no accounts, how do you know which features get used?" Through the anonymous counts: "assessment X was completed once" gets logged as event name + assessment name + timestamp. It's enough to see which tests are popular and where people drop off — but nothing in it can be assembled into a personal profile. It's the minimal dataset a product needs to improve.

"Are share links safe? Could someone intercept them?" The link itself travels over HTTPS; the # fragment never reaches server logs or the Referer header. The only real exposure is who you sent it to and where you pasted it. So the rule stands — share only with people you trust.

"I finished a test and wiped my browser. Do you still have a copy?" No. There was never a copy on our side — not deleted, simply never received. That is the most direct, and most honest, consequence of "data never leaves the device."

Try this architecture out: head back to the home page and pick an assessment.

← 为什么我们的测试结果可复现:确定…← Why our results are reproducible: three … 塔罗作为投射测验:一张心理学视角… →Tarot as a projective test: a psycholog… →