“用一行 HTML 申请摄像头、麦克风和定位权限”,这个说法最近很容易让人兴奋。它抓住了一个真实痛点:传统权限请求不仅代码散,还经常在用户还没理解功能价值时弹窗,拒绝后更难恢复。
但如果你准备把下面这类代码带进项目,先停一下:
<permission type="camera microphone"></permission>
它代表的是较早的 Page-Embedded Permission Control(PEPC)通用试验方案,不是 Chrome 144 里可以按该写法直接采用的通用标准。Chrome 144 里稳定发布的,是更具体的 <geolocation> 元素;通用 <permission> 的历史实验,正在被拆解成按能力设计的元素。Chrome 144 发布说明 与现行 WICG 草案 都明确记录了这次转向。
这不是吹毛求疵。<permission> 的旧事件名、属性名和兼容性,正是最容易让“复制即用”变成线上空白按钮的地方。本文的结论很简单:定位场景可以开始验证 <geolocation>;摄像头和麦克风仍要以 getUserMedia() 为主,并把新元素当作渐进增强。
先对齐事实:参考写法里有三处过期信息
| 常见说法 | 2026 年 8 月应怎样理解 |
|---|---|
Chrome 144+ 支持通用 <permission> | Chrome 144 稳定引入的是 <geolocation>;它此前确实以通用 <permission> 形式试验过。 |
grant、deny 是可监听的标准事件 | 现行草案使用 promptaction、promptdismiss、validationstatuschange;不要把旧示例当稳定 API。 |
preciseLocation 可直接拿到高精度定位 | 旧试验里 preciselocation 只影响提示文案;当前 <geolocation> 草案以位置 API 的能力模型为基础,精度和系统授权仍由平台决定。 |
Chrome 团队在 2025 年的通用元素试验文档中,仍列出了 camera、microphone 和 geolocation 等 type,并且当时的 API 还在不断变化:从 Chrome 137 起才允许元素拥有 fallback 内容,HTMLPermissionElement.isTypeSupported() 也随试验演进而出现。官方更新 本身就说明了它的实验性质。
后续讨论改变了形态。WICG 的新草案说明,旧 <permission> 草案已被一组按能力划分的元素替代;<geolocation> 是其中首先稳定落地的一项。对应的 Blink 讨论也直接写明,camera/mic 的通用试验仍在延长和调整中。Blink 邮件组
一句话记忆:声明式权限的方向没有变,变的是最终 API 不再是一个万能标签。
它真正解决的,不是“少写几行 JS”
老写法的问题,通常不是调用 getCurrentPosition() 的三行代码,而是权限请求和用户意图脱节。
// 不推荐:页面一加载就抢占用户注意力
navigator.geolocation.getCurrentPosition(onSuccess, onError);
用户只看到浏览器在问“是否允许定位”,却不知道你是要填收货地址、查附近门店,还是展示一张地图。浏览器也很难判断:这一次点击到底是在表达“我要定位”,还是用户刚好点到一个被脚本绑定的区域。
<geolocation> 把“请求权限”和“用户点击页面里的位置控件”绑在一起。浏览器负责控件文字与授权 UI,页面负责把它放进正确的业务上下文。Chrome 的发布说明特别强调,这个强用户意图信号也给过去拒绝过权限的用户提供了恢复路径。Chrome 144 发布说明
这带来三个工程价值:
- 请求时机可读:把控件放在“使用当前位置填地址”旁边,用户知道为什么现在要授权。
- 恢复路径交给浏览器:页面不用为每个系统和浏览器版本手写“去设置里打开权限”的长教程。
- 状态与数据靠近:元素不只触发提示,也承载位置结果和错误结果;定位的样板回调会更少。
不过别把它理解成权限系统的替代品。HTTPS、安全上下文、用户系统级开关、Permissions-Policy、iframe 授权与业务的最小权限原则依然都在。
Chrome 144 的最小示例:一次点击,拿到位置
对“附近门店”这样的单次定位场景,结构可以非常直接:
<label for="store-locator">选择门店</label>
<geolocation id="store-locator" lang="zh-CN"></geolocation>
<p id="location-status" aria-live="polite"></p>
<script>
const locator = document.querySelector('#store-locator');
const status = document.querySelector('#location-status');
locator.addEventListener('location', () => {
if (locator.position) {
const { latitude, longitude, accuracy } = locator.position.coords;
status.textContent = `已获取位置:${latitude}, ${longitude}(约 ±${accuracy} 米)`;
// 在这里请求“附近门店”接口;不要把精确坐标写入日志或 URL。
return;
}
status.textContent = `无法获取位置:${locator.error?.message ?? '未知错误'}`;
});
locator.addEventListener('promptdismiss', () => {
status.textContent = '你关闭了定位授权,可以在需要时再次点击。';
});
</script>
这里有两个细节值得注意。
第一,location 才是 <geolocation> 获取到位置或发生获取错误时的事件;结果通过 position 与 error 属性读取。草案还提供 watch,让元素走持续监听;autolocate 只会在此前已经获得授权时于插入页面后自动定位。它们分别对应传统 API 的 watchPosition() 与 getCurrentPosition()。WICG 草案
第二,promptaction 表示用户已对这一次权限提示作出选择,但它不等于“现在已经有可用坐标”。真正请求门店接口,应该等 location 事件中确认 position 存在后再做。
生产代码仍需要兜底:把“能力检测”写进组件
现在就把页面全替换成 <geolocation>,会丢掉非 Chrome 144+ 用户。更稳的方式是:把新元素放在第一路径,同时保留语义正常的原生按钮和传统 API。
<geolocation id="geo-native" lang="zh-CN">
<!-- 不支持该元素时,浏览器会显示这里的回退内容 -->
<button type="button" id="geo-fallback">使用当前位置</button>
</geolocation>
<p id="geo-status" aria-live="polite"></p>
<script>
const nativeGeo = document.querySelector('#geo-native');
const fallback = document.querySelector('#geo-fallback');
const status = document.querySelector('#geo-status');
const showPosition = (position) => {
status.textContent = `定位成功:${position.coords.latitude}, ${position.coords.longitude}`;
};
if ('HTMLGeolocationElement' in window) {
nativeGeo.addEventListener('location', () => {
if (nativeGeo.position) showPosition(nativeGeo.position);
else status.textContent = nativeGeo.error?.message ?? '定位失败';
});
} else {
fallback.addEventListener('click', () => {
if (!navigator.geolocation) {
status.textContent = '当前浏览器不支持定位能力';
return;
}
navigator.geolocation.getCurrentPosition(showPosition, (error) => {
status.textContent = `定位失败:${error.message}`;
}, { enableHighAccuracy: false, timeout: 10_000 });
});
}
</script>
这个方案的价值不在于“检测一个类名”,而在于回退路径没有另起一套 UI:支持新元素时浏览器渲染可控件;不支持时用户仍有一个可点击、有名称、可键盘访问的按钮。实际发布前,至少用 Chrome 144、当前 Safari、Firefox 和移动端真机各走一遍授权、拒绝、再次尝试、系统层关闭权限四条路径。
摄像头和麦克风怎么办?别把未来 API 写进今天的业务
如果你的业务是视频会议、扫码、语音输入,今天依然应该把 navigator.mediaDevices.getUserMedia() 当成主路径:
async function startCamera(video) {
try {
const stream = await navigator.mediaDevices.getUserMedia({ video: true });
video.srcObject = stream;
} catch (error) {
// 按 error.name 区分 NotAllowedError、NotFoundError 等,再给用户可理解的下一步。
console.error('camera unavailable', error);
}
}
新的方向并没有否定它,而是希望把“让用户作出权限决定”和“业务实际消费媒体流”分开得更清楚。Chrome 144 的发布说明已把媒体能力描述为正在演进的 capability-specific elements,而 WICG 对 <geolocation> 的设计讨论也明确提到,需要类似的 <usermedia> 元素来承接 camera/microphone。Chrome 144 发布说明 WICG Issue #59
因此合理策略是:不要围绕旧 <permission> 封装一层关键业务抽象;先把现有 getUserMedia() 错误处理、设备选择、流停止、系统级拒绝提示做好。 等媒体专用元素的标准和跨浏览器状态更清晰后,再把它作为授权入口的增强层。
为什么兼容性不能乐观估计
这个提案并不是所有浏览器都已达成一致。Blink 的试验公告列出了当时 Gecko 为 negative、WebKit 为 oppose 的立场;Mozilla 的公开 issue 带有 complexity、integration 和 use cases 的 concern 标签,WebKit 则标注了 complexity、portability、usability 等多项顾虑。Mozilla 立场讨论 WebKit 立场讨论
这不等于 <geolocation> 没有价值,恰恰说明它适合用渐进增强验证真实收益,而不是把它当作跨浏览器权限 API 的唯一入口。Web 平台里,“Chrome 已实现”与“互操作标准已经稳定”之间,经常隔着一段很长的路。
上线前,问完这 8 个问题
| 检查项 | 需要确认什么 |
|---|---|
| 触发点 | 用户是否刚刚明确表达了“我要使用位置/相机”的意图? |
| 价值说明 | 按钮附近是否说明了用途,而不是只写“允许”? |
| 浏览器能力 | 是否做了元素级 feature detection 与传统 API 回退? |
| 失败分支 | 拒绝、关闭弹窗、无设备、超时、系统层禁用分别怎么提示? |
| 权限策略 | HTTPS、iframe allow 与 Permissions-Policy 是否允许该能力? |
| 数据最小化 | 是否只在需要时读取位置/媒体流,并避免记录精确坐标? |
| 可访问性 | 回退按钮是否可键盘操作,状态是否通过 aria-live 宣读? |
| 观测 | 是否只统计流程阶段和失败类型,而不采集不必要的敏感数据? |
结论:可以试 <geolocation>,但别再复制旧 <permission>
<permission> 最值得关注的,不是“HTML 能替掉几十行 JS”,而是它把权限请求重新放回用户理解得到的业务上下文。这个方向很对,也已经促成 Chrome 144 的 <geolocation> 落地。
但对前端工程来说,最重要的能力仍是辨别 API 的时间线:通用 <permission> 是被验证过的想法;<geolocation> 才是当下可以针对定位场景做验证的落地接口;摄像头和麦克风仍应以现有媒体 API 为主。
建议是明确的:
- 做门店查找、地址填写、地图定位:在 Chrome 144+ 做
<geolocation>灰度验证,同时保留传统回退。 - 做摄像头、麦克风:继续打磨
getUserMedia()体验,不押注旧<permission>示例。 - 做跨浏览器产品:把声明式元素视为增强,而不是把兼容策略交给一个尚未完成标准化的标签。
当权限弹窗不再是“页面加载时的突然打断”,而是用户点击“使用当前位置”后的自然下一步,前端体验确实会更好。只是这次升级的正确入口,已经不是那段广泛流传的 <permission type="camera microphone">。
参考资料
- Chrome 144 发布说明:
<geolocation>与媒体相关能力 - Chrome:通用
<permission>试验的后续更新 - WICG:HTML Permission Elements 草案
- Blink-dev:PEPC 试验延长与互操作性风险
- WICG:
<geolocation>元素提案讨论 - Mozilla standards positions:PEPC
- WebKit standards positions:PEPC
参考资料
- https://developer.chrome.com/release-notes/144
- https://developer.chrome.com/blog/enhancements-to-permission-element
- https://wicg.github.io/PEPC/permission-elements.html
- https://groups.google.com/a/chromium.org/g/blink-dev/c/393mrf_4aBk/m/gB2aO3mWAwAJ
- https://github.com/WICG/PEPC/issues/59
- https://github.com/mozilla/standards-positions/issues/908
- https://github.com/WebKit/standards-positions/issues/270