I Will Not Add Query Strings to Your URLs

I Will Not Add Query Strings to Your URLs

我不会在你的 URL 中添加查询字符串

By Susam Pal on 09 May 2026 作者:Susam Pal,2026 年 5 月 9 日

Last evening, a short blog post appeared in my feed reader that felt as if it spoke directly to me. It is Chris Morgan’s excellent post I’ve banned query strings. 昨晚,我的订阅阅读器中出现了一篇简短的博文,读起来仿佛是在直接与我对话。这就是 Chris Morgan 那篇出色的文章——《我已经禁用了查询字符串》(I’ve banned query strings)。

Wisdom on the Web

网络智慧

Chris is someone whose Internet comments I have been reading for about half a decade now. I first stumbled upon his comments on Hacker News, where he left very detailed feedback on a small collection of boilerplate CSS rules I had shared there. Chris 是我关注了大约五年的人,我一直在阅读他在互联网上的评论。我最初是在 Hacker News 上偶然发现他的评论的,当时我分享了一组简单的 CSS 样板规则,他对此给出了非常详细的反馈。

I am by no means a web developer. I have spent most of my professional life doing systems programming in C and C++. However, developing websites and writing small HTML tools has been a long-time hobby for me. 我绝非一名专业的 Web 开发人员。我的职业生涯大部分时间都在从事 C 和 C++ 的系统编程。然而,开发网站和编写小型 HTML 工具一直是我长期的爱好。

I have learnt most of my web development skills as a hobbyist by studying what other people do: first by viewing the source of websites I liked in the early 2000s, and later by occasionally getting possessed by the urge to implement a new game or tool and searching MDN Web Docs to learn whatever I needed to make it work. 我大部分的 Web 开发技能都是作为业余爱好者通过研究他人的作品学来的:起初是在 21 世纪初查看我喜欢的网站源代码,后来则是偶尔心血来潮想实现一个新游戏或工具时,通过搜索 MDN Web Docs 来学习实现它所需的一切。

One problem with learning a skill this way is that you sometimes pick up habits and practices that are fashionable but not necessarily optimal or correct. So it was really valuable to me when Chris commented on my collection of boilerplate CSS rules. It helped me improve my CSS a lot. 以这种方式学习技能的一个问题是,你有时会养成一些流行的习惯和做法,但它们未必是最佳或正确的。因此,当 Chris 对我的 CSS 样板规则集发表评论时,对我来说非常有价值。它极大地帮助我改进了 CSS。

In fact, a few of the lessons from his comment have really stuck with me; I keep them in mind whenever I make a hobby HTML project: always retain underlines in links and retain purple for visited links. 事实上,他评论中的几条建议让我受益匪浅;每当我制作业余 HTML 项目时,我都会牢记这些建议:始终保留链接的下划线,并保留已访问链接的紫色。

I have been following Chris’s posts and comments on web-related topics since then. He often posts great feedback on web-related projects. Whenever I come across one, I make sure to read them carefully, even when the project isn’t mine. I always end up learning something nice and useful from his comments. Here is one such recent example from the Lobsters story Adding author context to RSS. 从那时起,我一直关注着 Chris 在 Web 相关话题上的文章和评论。他经常对 Web 项目发表很棒的反馈。每当我看到这些反馈时,我都会仔细阅读,即使该项目不是我的。我总能从他的评论中学到一些既好用又有价值的东西。最近的一个例子来自 Lobsters 上的故事《为 RSS 添加作者上下文》(Adding author context to RSS)。

Wander on the Web

网络漫游

A couple of months ago, I created a new project called Wander Console. It is a small, decentralised, self-hosted web console that lets visitors to your website explore interesting websites and pages recommended by a community of independent personal website owners. 几个月前,我创建了一个名为“Wander Console”的新项目。这是一个小型、去中心化、自托管的 Web 控制台,可以让访问你网站的用户探索由独立个人网站所有者社区推荐的有趣网站和页面。

For example, my console is here: susam.net/wander/. If you click the ‘Wander’ button there, the tool loads a random personal web page recommended by the Wander community. 例如,我的控制台在这里:susam.net/wander/。如果你点击那里的“Wander”按钮,该工具会加载一个由 Wander 社区推荐的随机个人网页。

The tool consists of one HTML file that implements the console and one JavaScript file where the website owner defines a list of neighbouring consoles along with a list of web pages they recommend. If you copy these two files to your web server, you instantly have a Wander console live on the Web. 该工具由一个实现控制台的 HTML 文件和一个 JavaScript 文件组成,网站所有者可以在 JavaScript 文件中定义邻近控制台的列表以及他们推荐的网页列表。如果你将这两个文件复制到你的 Web 服务器上,你就能立即在网上拥有一个 Wander 控制台。

You don’t need any server-side logic or server-side software beyond a basic web server to run Wander Console. You can even host it in constrained environments like Codeberg Pages or GitHub Pages. 运行 Wander Console 不需要任何服务器端逻辑或除基础 Web 服务器之外的服务器端软件。你甚至可以将它托管在 Codeberg Pages 或 GitHub Pages 等受限环境中。

When you click the ‘Wander’ button, the console connects to other remote consoles, fetches web page recommendations, picks one randomly and loads it in your web browser. It is a bit like the now defunct StumbleUpon but it is completely decentralised. It is also a bit like web rings except that the community network is not restricted to being a cycle; it is a graph that can take any shape. 当你点击“Wander”按钮时,控制台会连接到其他远程控制台,获取网页推荐,随机挑选一个并在你的浏览器中加载。它有点像现已倒闭的 StumbleUpon,但它是完全去中心化的。它也有点像 Web 环(web rings),不同之处在于社区网络不局限于环状结构;它是一个可以呈现任何形状的图。

There are currently over 50 websites hosting this tool. Together, they recommend over 1500 web pages. You can find a recent snapshot of the list of known consoles and the pages they recommend at susam.codeberg.page/wcn/. To learn more about this tool or to set it up on your website, please see codeberg.org/susam/wander. 目前有超过 50 个网站托管了这个工具。它们总共推荐了超过 1500 个网页。你可以在 susam.codeberg.page/wcn/ 找到已知控制台列表及其推荐页面的最新快照。要了解有关此工具的更多信息或在你的网站上进行设置,请访问 codeberg.org/susam/wander。

Misfeature

错误的功能

In case you were wondering why I suddenly plugged my project into this post in the previous section, it is because I recently added a dubious feature to that project that I myself was not entirely convinced about. That misfeature is relevant to this post. 如果你想知道为什么我在上一节中突然在文章里植入我的项目,那是因为我最近为该项目添加了一个我自己都不太确定的可疑功能。那个“错误的功能”与本文有关。

In version 0.4.0 of Wander Console, I added support for a via= query parameter while loading web pages. For example, if you encountered midnight.pub while using the console at susam.net/wander/, the console loaded the page using the following URL: https://midnight.pub/?via=https://susam.net/wander/ 在 Wander Console 0.4.0 版本中,我添加了对加载网页时使用 via= 查询参数的支持。例如,如果你在使用 susam.net/wander/ 控制台时遇到了 midnight.pub,控制台会使用以下 URL 加载该页面:https://midnight.pub/?via=https://susam.net/wander/

This allowed the owner of the recommended website to see, via their access logs, that the visit originated from a Wander Console. Chris’s recent blog post is critical of features like this. He writes: 这使得被推荐网站的所有者可以通过他们的访问日志看到,该访问源自 Wander Console。Chris 最近的博文对这类功能提出了批评。他写道:

I don’t like people adding tracking stuff to URLs. Still less do I like people adding tracking stuff to my URLs. https://chrismorgan.info/no-query-strings?ref=example.com? Did I ask? If I wanted to know I’d look at the Referer header; and if it isn’t there, it’s probably for a good reason. You abuse your users by adding that to the link. 我不喜欢人们在 URL 中添加追踪信息。我更不喜欢人们在我的 URL 中添加追踪信息。https://chrismorgan.info/no-query-strings?ref=example.com?我要求了吗?如果我想知道,我会查看 Referer 标头;如果那里没有,那很可能是有正当理由的。你在链接中添加这些内容是在滥用你的用户。

I mentioned earlier that I was not entirely convinced that adding a referral query string was a good thing to do. Why did I add it anyway? I succumbed to popular demand. 我之前提到过,我并不完全确信添加推荐查询字符串是一件好事。那我为什么还要添加它呢?我屈服于大众的需求。

Let me briefly describe my frame of mind when I considered and implemented that feature. When I first saw the feature request on Codeberg, my initial reaction was reluctance. I wasn’t convinced it was a good feature. But I was too busy with some ongoing algebraic graph theory research, another recent hobby, with a looming deadline, so I didn’t have a lot of time to think about it clearly. 让我简要描述一下我在考虑和实现该功能时的心态。当我第一次在 Codeberg 上看到这个功能请求时,我的第一反应是抵触。我不认为这是一个好的功能。但我当时正忙于进行代数图论研究(这是我最近的另一个爱好),而且截止日期临近,所以我没有太多时间去深入思考。

In fact, everything about Wander Console has been made in very little time during the short breaks I used to take from my research. I made the first version of the console in about one and a half hours one early morning when my brain was too tired to read more algebraic graph theory literature and I really needed a break. During another such break, I revisited that feature request and, despite my reservations, decided to implement it anyway. During yet another such break, I am writing this post. 事实上,关于 Wander Console 的一切都是我在研究间隙的短暂休息时间里匆忙完成的。我在一个清晨花了大约一个半小时制作了控制台的第一个版本,当时我的大脑太累了,无法阅读更多的代数图论文献,我真的需要休息一下。在另一次这样的休息中,我重新审视了那个功能请求,尽管心存疑虑,我还是决定实现它。而在又一次这样的休息中,我正在写这篇文章。

Normally, I don’t like adding too many new features to my little projects. I want them to have a limited scope. I also want them to become stable over time. 通常,我不喜欢给我的小项目添加太多新功能。我希望它们的范围有限。我也希望它们能随着时间的推移变得稳定。