0

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

示例:在 iframe 中,我将使用

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

我有一个用例,其中 html 嵌入链接如

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

嵌入在父站点中。父站点在它自己的 iframe 中加载子链接

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

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

错误代码:1

errorMessage:“地理定位已被权限策略在此文档中禁用。”

功能策略文档指向 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,它会完美运行!(完美平衡,因为所有东西都应该......)

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

带有allow='geolocation' 的jsfiddle 的iframe 应该设置jsfiddle 站点的功能策略,即在该if​​rame 中加载的所有脚本都可以访问地理位置,对吗?为什么我在 jsfiddle 的 iframe 中的 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;地理位置https://siteWhichCallsGetGeolocation.com

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

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

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

4

1 回答 1

2

简而言之,你必须发布

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

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

TL; DRWhat's going on under the hood
allow="geolocation"属性用于在 iframe 中设置功能策略(现在它已重命名为权限策略)。
您将geolocation指令与一个空的来源列表一起使用,因此应用了默认策略 geolocation 'src'。这意味着在 iframe 内部允许从与 iframe 相同的位置加载的脚本的 Geolocation API - https://siteWhichCallsGetGeolocation.com

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

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

因此使用

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

或者

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

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

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

但是将父页面的权限传递到嵌套 iframe执行一种棘手的方式。如果某些浏览上下文具有某些权限,则它可以将其授予任何嵌套上下文,而与其来源无关(如果它自己创建此上下文)。

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

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

带有allow ='geolocation'的jsfiddle的iframe应该设置jsfiddle站点的功能策略,该iframe中加载的所有脚本都可以访问地理位置对吗?

不是“在那个 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';"
于 2021-06-03T14:33:08.030 回答