认识 HTML 新提案元素 <permission>:让权限请求更讲道理

更新日期: 2026-05-06 阅读: 18 标签: 元素

它是什么

<permission> 是一个正在讨论中的 HTML 新元素。它想把“向用户申请权限”这件事,从 JavaScript 函数调用变成一个页面上真实可见的控件。目前这个提案还处于 WICG 草案阶段,经历过 Chrome 的 Origin Trial 测试,距离成为正式标准还有一段路,现在还不能在生产环境里直接使用。


它能解决什么问题

以前要申请定位、摄像头、通知这些权限,基本套路是:页面上放一个按钮,用户点一下,背后执行 navigator.permissions 或者直接调用对应的权限接口,浏览器的弹窗就跳出来了。用户常常还没看清弹窗内容,手一抖就点了拒绝。拒绝之后,权限状态变成“已阻止”,网站再想引导用户去设置里改回来,过程非常折腾。

<permission> 的设计思路是:让权限入口变成页面上的一个标签,跟在按钮、输入框一样,用户点它,就是明确想要授权。浏览器能更清楚地知道,这次权限请求确实是用户真实意图触发的。WICG 草案和 Chrome 团队的说明都提到一个关键目标:减少骚扰式弹窗,把权限动作放回到使用场景里。


基础写法

最简的用法看起来就像个普通按钮:

<permission type="camera">打开摄像头</permission>
<permission type="microphone">打开麦克风</permission>

type 属性告诉浏览器要申请哪种权限,浏览器会根据这个值生成对应的授权流程。用户点击这个元素,本质上和以前点按钮触发权限接口类似,区别在于浏览器的处理方式可能更统一、更可预测。


实际项目中的稳妥写法

因为兼容性还没铺开,现在写业务代码,更好的做法是走“渐进增强”路线:支持 <permission> 的浏览器走新方案,不支持的继续用老办法兜底。下面是一个处理定位权限的示例:

<div class="permission-block">
  <!-- 新方案:permission 元素 -->
  <permission id="geoPermission" type="geolocation">
    允许获取当前位置
  </permission>

  <!-- 旧方案兜底按钮,默认隐藏 -->
  <button id="geoFallback" hidden>允许获取当前位置</button>

  <pre id="result"></pre>
</div>
const result = document.querySelector('#result');
const fallbackBtn = document.querySelector('#geoFallback');
const permissionEl = document.querySelector('#geoPermission');

function print(msg) {
  result.textContent = `[${new Date().toLocaleTimeString()}] ${msg}`;
}

function readLocation() {
  navigator.geolocation.getCurrentPosition(
    function (pos) {
      const lat = pos.coords.latitude.toFixed(6);
      const lng = pos.coords.longitude.toFixed(6);
      print('定位成功:' + lat + ', ' + lng);
    },
    function (err) {
      print('定位失败:' + err.code + ' ' + err.message);
    },
    { enableHighAccuracy: true, timeout: 8000 }
  );
}

async function init() {
  try {
    // 先查当前权限状态,不要一上来就申请
    const status = await navigator.permissions.query({ name: 'geolocation' });
    print('当前权限状态:' + status.state);

    // 如果已经授权,直接定位
    if (status.state === 'granted') {
      readLocation();
      return;
    }

    // 检测浏览器是否不支持 permission 元素
    // 如果 permissionEl 不是真实的自定义元素实例,说明当前浏览器不认识它
    if (
      typeof customElements !== 'undefined' &&
      !customElements.get('permission') &&
      permissionEl instanceof HTMLElement
    ) {
      // 隐藏 permission 元素,换旧按钮出场
      permissionEl.hidden = true;
      fallbackBtn.hidden = false;
    }

    // 监听权限状态变化
    status.onchange = function () {
      print('权限状态变更:' + status.state);
      if (status.state === 'granted') {
        readLocation();
      }
    };
  } catch (e) {
    // 如果连 permissions.query 都不支持,直接切旧方案
    print('初始化失败:' + e.message);
    permissionEl.hidden = true;
    fallbackBtn.hidden = false;
  }
}

// 旧方案按钮的点击处理
fallbackBtn.addEventListener('click', function () {
  readLocation();
});

init();

上面这段代码做了几件事:

  1. 页面加载时先用 navigator.permissions.query() 查一下权限状态,而不是直接弹出请求。

  2. 如果权限已经是“已授权”,直接执行定位逻辑。

  3. 检测浏览器是否认识 <permission> 元素,不认识就把新元素藏起来,让兜底的旧按钮显示。

  4. 监听 status.onchange,当用户在别处改了权限后,页面能及时响应。


和 Permissions API 的关系

有一点容易混淆:<permission> 不是一个用来替代 Permissions API 的东西。它们分工不同。

Permissions API 负责让代码查询权限状态、监听变化。<permission> 负责给用户一个看得见、点得到的权限入口。两者是配合关系,不是替代关系。代码里该查状态还是要查,不该一加载页面就傻等着用户授权。


怎么用才真的有用

这个标签最大的价值不在于省掉几行 JS,而在于两件事:

第一,把权限入口嵌进真实的操作流程里。比如“开始导航”旁边放定位授权按钮,“加入会议”旁边放麦克风授权按钮。用户看到的就是“我要用这个功能,所以需要这个权限”,逻辑是通的。

第二,给“被拒绝后的恢复”留了一条更自然的路。以前用户拒绝过一次,权限状态变成“已阻止”,页面再想引导就非常费劲,用户得去浏览器设置里翻半天。Chrome 对这个提案反复提到的一点就是:用户之前拒绝过,页面里也应该有更清晰的方式让用户重新同意或管理权限,不用跑到设置页。


现在要不要用

如果问我现在的态度,我不会建议大家立刻大规模上。更好的做法是挑几个权限敏感、转化容易出问题的页面做小范围试验。把 <permission> 当成一个增强能力,而不是唯一入口。新标签再新,最后也得回到一个旧问题:用户到底知不知道你为什么需要这个权限。这个问题没讲清楚,换什么标签都帮不上忙。


小结

<permission> 是一个值得关注的提案,它代表了一种趋势:浏览器厂商试图把权限请求的控制权更多还给用户,减少出其不意的弹窗。但它目前还是草案,语法细节和兼容性都可能变。如果你对这个方向感兴趣,可以关注 WICG 的官方仓库或 Chrome 平台的更新日志。真正要落到业务里,记得保持渐进增强,用老方案兜底,别把全部希望押在一个还在演进中的东西上。

本文内容仅供个人学习、研究或参考使用,不构成任何形式的决策建议、专业指导或法律依据。未经授权,禁止任何单位或个人以商业售卖、虚假宣传、侵权传播等非学习研究目的使用本文内容。如需分享或转载,请保留原文来源信息,不得篡改、删减内容或侵犯相关权益。感谢您的理解与支持!

链接: https://fly63.com/article/detial/13750

相关推荐

原生JS如何获取当前元素属于父元素第几个子元素

我们经常通过document.getElementById 方法来获取到一个元素,这个时候我们经常需要有一个需求,那就是如何判断这个元素在父元素中的位置。原生JS有一个常见的小技巧那就是通过元素的previousSibling 属性,额外需要注意的是该属性会遍历text节点,即回车键。

使用原生js来控制、修改CSS伪元素的方法总汇, 例如:before和:after

在网页中,如果需要使用辅助性/装饰性的内容的时候,这就需要使用伪元素了。在使用伪元素的时候,会发现js并不真能直接控制它,这篇文章主要就介绍下如果间接的控制、修改css中伪元素的方法

js动态生成html元素并为元素追加属性

动态生成HTML元素的方法有三种:document.createElement()创建元素,再用appendChild( )添加、使用innerHTML直接将元素添加到指定节点、jQuery创建节点...

原生js删除元素

通过id删除;通过class获取元素;清空一个元素,即删除一个元素的所有子元素 ;原理很简单,就是不断的判断要清空的div还有没有子节点,有的话就删除一个子节点(这里是它的首个子节点),直到删除完毕为止。

使用document.querySelector获取元素

使用 document.querySelector() 和 document.querySelectorAll(), 将 CSS选择器 作为参数传入即可;注意: querySelecotor()返回某个元素节点, querySelectorAll()返回一个NodeList实例对象;

CSS隐藏元素的五种方法

用css隐藏页面元素有许多种方法。1、opacity:0;2、visibility:hidden;3、diaplay:none;4、position:absolute;5、clip-path。大家可以根据具体情况选择适合的方法来隐藏元素

css父元素透明度(opacity)对子元素的影响

设置父元素opacity:0.5,子元素不设置opacity,子元素会受到父元素opacity的影响,也会有0.5的透明度。设置父元素opacity:0.5,即使设置子元素opacity:1,子元素的opacity

angular怎么删除(remove)元素?

angular删除(remove)元素可以使用angular.element中的remove()方法,此方法可以将匹配元素集合从DOM中删除(同时移除元素上的事件及jQuery数据)。

JS 的 Element元素对象

在 HTML DOM 中, 元素对象代表着一个 HTML 元素。元素对象 的 子节点可以是, 可以是元素节点,文本节点,注释节点。NodeList 对象 代表了节点列表,类似于 HTML元素的子节点集合。

CSS隐藏页面元素常用方法_不同场景下使用CSS隐藏元素

使用 CSS 让元素不可见的方法很多,剪裁、定位到屏幕外、明度变化等都是可以的。虽然它们都是肉眼不可见,但背后却在多个维度上都有差别

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!