HTML 嵌入式站点的地理定位被拒绝 - 锚标记功能策略

Geolocation denied for HTML embedded site - anchor tag feature policy

带有 allow="geolocation" 的 iframe 效果很好。 但是,如果我想加载一个从 html 锚标记调用 getCurrentPosition() 的 link 怎么办?

示例: 在 iframe 中,我将使用

<iframe src="https://siteWhichCallsGetGeolocation.com" allow='geolocation'></iframe>

我有一个用例,其中 html 嵌入了 link,例如

<a href="https://siteWhichCallsGetGeolocation.com">Click here to get geolocation</a>

嵌入父网站。 父站点在它自己的 iframe

中加载子 link

请注意,父站点的 iframe 具有 allow="geolocation" 属性。

在这种情况下,请求被静默拒绝并出现错误

errorCode :1

errorMessage: "Geolocation has been disabled in this document by permissions policy."

feature policy 文档指向 iframe 但锚标记嵌入呢?

我知道我可以使用 iframe 代替锚标记嵌入,但父站点只允许锚标记。

PS - 这是我的第一个问题。请协助。

注:

  1. 我还尝试通过为锚标记添加 allow="geolocation" 来随机拍摄,但它不起作用。
  2. 这似乎适用于 Safari(我假设这是因为 Safari 尚未实施跨源站点请求的功能策略)

编辑 1 :

我在 jsfiddle 中尝试了我的用例并注意到我提供的所有脚本(iframe 或锚标记)都加载到 jsfiddle 的 iframe 中

<iframe name="result" allow="midi; geolocation; microphone; camera; display-capture; encrypted-media;" sandbox="allow-modals allow-forms allow-scripts allow-same-origin allow-popups allow-top-navigation-by-user-activation allow-downloads" allowfullscreen="" allowpaymentrequest="" frameborder="0" src=""> </iframe>

如果我将 iframe 加载到其中,它会完美运行!(完美平衡,一切都应该如此...)

但是如果我在其中加载我的锚标记,我会收到错误消息。根据

带有 allow='geolocation' 的 jsfiddle 的 iframe 应该设置 jsfiddle 站点的功能策略,即在该 iframe 中加载的所有脚本都可以访问地理定位吗?为什么我的 iframe 在 jsfiddle 的 iframe 中工作但锚标记不工作?

注意 - 我无法控制顶级网站。我只为 https://siteWhichCallsGetGeolocation.com

编写脚本

解决方案(如果您可以控制顶级文档的功能策略或控制任何具有地理定位权限的中间 <iframe>(来自格兰蒂的回答)

我尝试了建议的解决方案,方法是通过检查元素将 jsfiddle 的 iframe 属性更改为

<iframe name="result" allow="midi; geolocation https://siteWhichCallsGetGeolocation.com ; microphone; camera; display-capture; encrypted-media;" sandbox="allow-modals allow-forms allow-scripts allow-same-origin allow-popups allow-top-navigation-by-user-activation allow-downloads" allowfullscreen="" allowpaymentrequest="" frameborder="0"></iframe>

为了突出显示,我在白名单中的地理位置旁边添加了我的网站,例如

allow="midi; geolocation https://siteWhichCallsGetGeolocation.com ;

然后加载我的锚标签。 当从 https://siteWhichCallsGetGeolocation.com 加载的脚本触发 getCurrentPosition() 时,浏览器提示 Allow/Deny 位置共享。我允许并得到了坐标!

哇!如果它可以像通过检查元素编辑顶级文档的 feature/permissions 策略一样简单。

但是,唉,我无法控制顶级文档的功能策略。至少我明白引擎盖下发生了什么。

简述,你要发表

Feature-Policy: geolocation https://siteWhichCallsGetGeolocation.com;

HTTP 响应 header,当服务器将页面发送到浏览器时。

TL; DR幕后发生了什么
allow="geolocation" 属性用于在 iframe 中设置功能策略(现在已重命名为权限策略)。
您使用带有空白来源列表的 geolocation 指令,因此应用了 default policy geolocation 'src'。这意味着对于从与 iframe 相同的位置加载的脚本,允许在 iframe 内部进行地理定位 API - https://siteWhichCallsGetGeolocation.com.

请注意,allow="geolocation" 的默认策略是 'src'(来自 iframe 的 src=)。但是如果你使用指令 Feature-Policy: geolocation;,空列表的默认策略是 'self'.

在主页(顶级文档)中设置功能策略是为了 Feature-Policy header。如果未设置,则应用默认策略 geolocation 'self'。这禁止对从 https://siteWhichCallsGetGeolocation.com 来源加载的脚本使用地理定位 API。

因此使用

Feature-Policy: geolocation https://siteWhichCallsGetGeolocation.com;

Feature-Policy: geolocation 'self' https://siteWhichCallsGetGeolocation.com;

如果您自己的页面也使用地理定位。

参考编辑 1
Jsfiddle的<iframe allow="geolocation;"表示<iframe allow="geolocation 'src';"。这意味着只有从与 jsfiddle iframe 相同的源 (Url) 加载的脚本才能访问 Geolocation API。因此它不允许来自 https://siteWhichCallsGetGeolocation.com 来源的锚标记。

但是 passing permissions of parent page into nested iframe 执行一个棘手的方法。如果某些浏览上下文有一些权限,它可以将它授予任何独立于其来源的 嵌套 上下文(如果它自己创建此上下文)。

因此 jsfiddle 的 iframe 具有 geolocation 的权限。在 jsfiddle 的 iframe 中放置了具有 allow='geolocation 'src'.
的嵌套 iframe Jsfiddle 的 iframe 将其地理定位权限委托给您的 iframe,当然,当权限传递给另一个 iframe 时,允许的来源会发生变化。

是的,从 third-party Urls 加载的脚本也可以创建 iframe,但它们不能授予地理定位权限,因为它们没有它 - 因为它们是从地理定位的来源加载的不允许。

the jsfiddle's iframe with allow='geolocation' should set jsfiddle site's feature policy that all scripts loaded inside that iframe can access geolocation right?

不是“在该 iframe 中加载”,而是从与该 iframe 相同的 Url 加载。
否则,如果任何未列出的脚本都可以访问您的相机,指定允许来源列表(如 allow="camera 'self' https://www.youtube.com" 的意义何在?

使用隐藏的默认值是一种不好的做法,因此你被误导了。而不是:

<iframe allow="midi; geolocation; microphone; camera; display-capture; encrypted-media;"

应该是:

<iframe allow="midi 'src'; geolocation 'src'; microphone 'src'; camera 'src';
  display-capture 'src'; encrypted-media 'src';"