工作流工具观察发布于 2026/08/06作者 前端界已人工审核7 分钟

别急着用 <permission>:Chrome 144 真正落地的是 <geolocation>

通用 <permission> 曾让前端看到声明式权限的可能,但 Chrome 144 稳定发布的是能力专用的 <geolocation>。本文厘清版本、给出可运行的渐进增强方案,也说明摄像头和麦克风该如何继续兼容。

“用一行 HTML 申请摄像头、麦克风和定位权限”,这个说法最近很容易让人兴奋。它抓住了一个真实痛点:传统权限请求不仅代码散,还经常在用户还没理解功能价值时弹窗,拒绝后更难恢复。

但如果你准备把下面这类代码带进项目,先停一下:

<permission type="camera microphone"></permission>

它代表的是较早的 Page-Embedded Permission Control(PEPC)通用试验方案,不是 Chrome 144 里可以按该写法直接采用的通用标准。Chrome 144 里稳定发布的,是更具体的 <geolocation> 元素;通用 <permission> 的历史实验,正在被拆解成按能力设计的元素。Chrome 144 发布说明 与现行 WICG 草案 都明确记录了这次转向。

这不是吹毛求疵。<permission> 的旧事件名、属性名和兼容性,正是最容易让“复制即用”变成线上空白按钮的地方。本文的结论很简单:定位场景可以开始验证 <geolocation>;摄像头和麦克风仍要以 getUserMedia() 为主,并把新元素当作渐进增强。

从通用 permission 试验到 geolocation 元素的演进

先对齐事实:参考写法里有三处过期信息

常见说法2026 年 8 月应怎样理解
Chrome 144+ 支持通用 <permission>Chrome 144 稳定引入的是 <geolocation>;它此前确实以通用 <permission> 形式试验过。
grantdeny 是可监听的标准事件现行草案使用 promptactionpromptdismissvalidationstatuschange;不要把旧示例当稳定 API。
preciseLocation 可直接拿到高精度定位旧试验里 preciselocation 只影响提示文案;当前 <geolocation> 草案以位置 API 的能力模型为基础,精度和系统授权仍由平台决定。

Chrome 团队在 2025 年的通用元素试验文档中,仍列出了 cameramicrophonegeolocationtype,并且当时的 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> 获取到位置或发生获取错误时的事件;结果通过 positionerror 属性读取。草案还提供 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 allowPermissions-Policy 是否允许该能力?
数据最小化是否只在需要时读取位置/媒体流,并避免记录精确坐标?
可访问性回退按钮是否可键盘操作,状态是否通过 aria-live 宣读?
观测是否只统计流程阶段和失败类型,而不采集不必要的敏感数据?

结论:可以试 <geolocation>,但别再复制旧 <permission>

<permission> 最值得关注的,不是“HTML 能替掉几十行 JS”,而是它把权限请求重新放回用户理解得到的业务上下文。这个方向很对,也已经促成 Chrome 144 的 <geolocation> 落地。

但对前端工程来说,最重要的能力仍是辨别 API 的时间线:通用 <permission> 是被验证过的想法;<geolocation> 才是当下可以针对定位场景做验证的落地接口;摄像头和麦克风仍应以现有媒体 API 为主。

建议是明确的:

当权限弹窗不再是“页面加载时的突然打断”,而是用户点击“使用当前位置”后的自然下一步,前端体验确实会更好。只是这次升级的正确入口,已经不是那段广泛流传的 <permission type="camera microphone">

参考资料

参考资料

  1. https://developer.chrome.com/release-notes/144
  2. https://developer.chrome.com/blog/enhancements-to-permission-element
  3. https://wicg.github.io/PEPC/permission-elements.html
  4. https://groups.google.com/a/chromium.org/g/blink-dev/c/393mrf_4aBk/m/gB2aO3mWAwAJ
  5. https://github.com/WICG/PEPC/issues/59
  6. https://github.com/mozilla/standards-positions/issues/908
  7. https://github.com/WebKit/standards-positions/issues/270

Continue Reading

相关推荐

继续阅读同一工具与主题下的实战内容。