古怪的API能告诉我们关于网络的什么?

Lobsters Hottest 新闻

摘要

本文探讨了像canPlayType和History.pushState这类古怪的浏览器API,讨论了它们不寻常的设计决策和历史原因。

<p><a href="https://lobste.rs/s/fb5nuv/what_can_wonky_apis_tell_us_about_web">评论</a></p>
查看原文
查看缓存全文

缓存时间: 2026/06/22 01:29

# 不规范的API能告诉我们关于Web的什么? 来源:https://alexwlchan.net/2026/wonky-web-apis/ 几天前,Misty发了一条吸引我注意的帖子: > 我在想,有没有比`canPlayType`更不规范的官方浏览器API?2026年6月18日17:52 (https://digipres.club/@misty/116772382932474870) `HTMLMediaElement.canPlayType` API (https://developer.mozilla.org/zh-CN/docs/Web/API/HTMLMediaElement/canPlayType) 会告诉你浏览器播放给定MIME类型的媒体的可能性有多大,但它的返回值很不寻常。这里的关键词是“可能性”,因为它不是简单的“是/否”回答。可能的返回值有: - `""` – 否,浏览器无法播放该媒体 - `"probably"` – 浏览器很可能可以播放该媒体 - `"maybe"` – 没有足够信息判断该媒体是否可播放 一个基于概率的三元返回值本身就已经有点奇怪了;而返回值本身又加剧了这种怪异感。更清晰的返回值应该是`"no"`、`"probably"`和`"unknown"`。 但当我想到不规范的Web API时,我的脑海中浮现了另一个东西:`History.pushState()` (https://developer.mozilla.org/zh-CN/docs/Web/API/History/pushState) 和 `replaceState()` (https://developer.mozilla.org/zh-CN/docs/Web/API/History/replaceState)。这些API用于操作浏览器历史记录,并且有一个`unused`参数,你必须传入它,但它完全不起任何作用。 以下是MDN对`pushState`的描述(强调是我加的): > `pushState()` 是 `History` (https://developer.mozilla.org/zh-CN/docs/Web/API/History) 接口的一个方法,用于向浏览器的会话历史栈中添加一条记录。语法:`pushState(state, unused)` 或 `pushState(state, unused, url)`。参数:- `state` – `state`对象是一个JavaScript对象,与由`pushState()`创建的新历史记录条目相关联。\[...\] - `unused` – **该参数因历史原因存在,且不可省略;传递空字符串可安全应对该方法未来的变更。** - `url` – 新历史记录条目的URL。 这不禁让人想问:到底是什么历史原因?为什么一个所有主流浏览器都支持的API会有一个没人用的参数? History API (https://developer.mozilla.org/zh-CN/docs/Web/API/History_API/Working_with_the_History_API) 是为单页应用 (https://developer.mozilla.org/zh-CN/docs/Glossary/SPA) 设计的——这类网站只加载一个页面,然后使用JavaScript更新页面内容,而不是每次内容变化时都加载新页面。使用SPA可以让网站更快,因为它们只需加载页面变化的部分,但同时也破坏了浏览器“后退”和“前进”按钮的正常行为。 从用户的角度来看,他们点击链接,页面发生变化,所以如果他们点击“后退”按钮,期望能回到之前的状态。 但浏览器只记录一个历史事件,即用户首次加载SPA时——所有通过JavaScript进行的页面内更新都不会被注册为新页面。当用户点击“后退”按钮时,浏览器会将他们带回打开SPA之前浏览的那个页面。 使用`pushState()`和`replaceState()`可以让应用创建虚拟的历史记录条目,这样“后退”和“前进”按钮就能让用户在SPA中浏览过的页面之间切换。 `pushState()` API首次出现在2008年1月的HTML5规范草案中(https://www.w3.org/TR/2008/WD-html5-20080122/#pushstate),包含三个参数: - `state`对象会附加到历史事件上,如果用户点击“后退”或“前进”按钮,你的应用会收到一个`popstate`事件(https://developer.mozilla.org/zh-CN/docs/Web/API/Window/popstate_event),其中包含与所选历史事件关联的state值。 - `title`参数允许应用为保存在浏览器会话历史中的条目设置标题,这个标题可以与浏览器窗口中显示的标题不同。 - `url`参数允许应用为历史条目设置URL,这个URL可以与浏览器窗口中显示的URL不同。如果省略,浏览器会使用当前URL。 `title`参数始终只是“建议性的”,实际上大多数浏览器完全忽略了这个参数,以避免浏览器UI和会话历史中标题不匹配带来的混淆。 很快人们就发现`title`参数毫无意义,但改变已经为时已晚。大量网站已建成单页应用,并正在使用新的`pushState`和`replaceState`API,破坏这些网站是不可接受的。 该参数既不能被删除,也不能被设为可选。如果删除它,就会破坏那些使用三个参数`pushState(state, title, url)`的网站。如果设为可选,由于它位于函数签名的中间位置,浏览器将无法区分`pushState(state, url)`和`pushState(state, title)`。 于是,规范被更新,将该参数重命名为`unused`,并明确说明它没有任何效果。 这个不规范的API反映了为Web设计的挑战:在看不到API在真实网站上的使用情况之前,很难设计好API;但看到之后,再根据反馈进行修改又为时已晚。Web致力于保持向后兼容性,这可以说是“任何被描述为原型的东西最终都会在生产环境中上线”的终极体现。 原生Web技术的持久性正是我持续使用静态网站 (https://alexwlchan.net/2024/static-websites/) 来管理我的媒体档案的原因——在我技术职业生涯中,没有什么比Web技术更持久了。

相似文章

视频游戏主机上的网页浏览器

Lobsters Hottest

关于视频游戏主机上官方网页浏览器的详细历史回顾,涵盖了早期尝试如CD-i的CD-Online和世嘉土星的Net Link,突出了它们作为廉价互联网网关的作用。