Permissions-Policy 是声明式硬闸门,需通过 iframe 的 allow 属性或服务端注入的 HTTP 响应头启用;allow 必须用分号分隔、括号标注来源,空格或旧语法将导致失效,且仅作用于该 iframe 及其子上下文。

Feature-Policy 已正式更名为 Permissions-Policy,HTML 中无法“创建”它,只能通过 iframe 的 allow 属性或 HTTP 响应头启用——且后者必须由服务端注入,前端 JS 完全无法动态设置。
iframe 的 allow 属性怎么写才真正生效
这是唯一能在 HTML 标签层面直接控制嵌入内容权限的方式,优先级高于响应头,但只作用于该 iframe 及其子上下文。
- 必须用分号
;分隔多个权限,空格或逗号会彻底失效:allow="geolocation 'self'; microphone=()"✅|allow="geolocation 'self' microphone=()"❌ - 每个权限后必须跟来源列表,用括号
()包裹:microphone=()明确禁止|microphone='self'允许同源|microphone=*允许任意来源(高风险) -
'self'指iframe自身的源,不是父页面源;跨域iframe无法读取父页面 DOM,但能用自己的源申请权限 - 省略某个权限(如不写
fullscreen)等同于默认拒绝,但显式写成fullscreen=()更可靠、可审计
为什么写了 allow 却没效果
绝大多数“策略失效”是语法或环境问题,不是浏览器不支持。
- 在本地用
file://协议打开 HTML 文件 → 所有权限策略自动禁用,Chrome/Firefox/Safari 均不执行 - 用了旧语法:
allow="microphone 'none'"或allow="geolocation 'self' https://a.com"(缺等号、括号、分号)→ Chrome 100+ 直接忽略整条allow值 - 误以为
allow能控制父页面行为 → 它只约束iframe内部脚本,父页面调用navigator.mediaDevices.getUserMedia不受其影响 - 在
iframe加载完成后动态修改allow属性 → 浏览器只在加载时解析一次,后续修改无效
如何验证 allow 是否起作用
不能只看 HTML 源码,得靠运行时反馈和开发者工具交叉确认。
立即学习“前端免费学习笔记(深入)”;
- 打开 Chrome DevTools → Application → Permissions → 查看当前上下文的
Microphone或Geolocation状态 - 在 Console 执行:
navigator.permissions.query({ name: 'microphone' }).then(r => console.log(r.state)),若返回"denied"或调用getUserMedia({ audio: true })抛NotAllowedError,说明策略已拦截 - 注意:
state: "prompt"不代表能调用——仍需用户手势(如 click)触发,且该iframe必须已在allow中获准对应权限 - 如果第三方组件在
iframe内报错NotAllowedError,基本可判定策略生效;若静默失败或仍能采集,则大概率语法错误或协议环境不合法
最易被忽略的一点:Permissions-Policy 是声明式硬闸门,不是运行时钩子。它不依赖 JS 检查、不修改 DOM、不拦截已有调用——而是让浏览器在加载资源前就决定 API 是否可用。写错一个括号或分号,策略就形同虚设。


















