【问题标题】:Cordova, iOS and iframe won't load content unless I allow-access href="*"除非我允许访问 href="*",否则 Cordova、iOS 和 iframe 不会加载内容
【发布时间】:2018-01-26 05:29:44
【问题描述】:

我有一个网络应用程序,它有一个嵌入的地图字段,它是使用 iframe 实现的 https://maps.google.com/...

我正在将我们的应用程序(目前作为主屏幕图标运行)移植到 iOS 上的 Cordova,因此添加了一个 Cordova 包装器。我们已经通过 Cordova 在 Android 上运行了该应用程序。

我有一个div,带有一个子元素

<iframe src="https://maps.google.com/?iwloc=&output=embed&q=something"></iframe>

最初,当 Cordova 项目只关注 Android 时,我曾在 config.xml

<access origin="*" />
<access origin="file://*" />
<access origin="http://*" />
<allow-navigation href="http://*" />

但是,这不起作用。带有地图 url 的 iframe 甚至没有尝试加载,也没有迹象表明原因。

所以我开始阅读并使用这些设置,基本上在 iOS 上,它们所做的只是映射到 Info.plist 中的 NSAppTransportSecurity 设置。

原来&lt;allow-navigation href="http://*" /&gt; 被完全忽略了,只支持指定域或只支持 * 的允许导航,所以我尝试了更具体的基于域的导航,例如

&lt;allow-navigation href="http://maps.google.com/*" /&gt;

这确实为maps.google.com 创建了一个域条目并将NSExceptionAllowsInsecureHTTPLoads 设置为true,但仍然无法加载iframe。

我能找到的唯一允许 iframe 加载地图 URL 的方法是添加

&lt;allow-navigation href="*"/&gt;

这实质上将NSAllowsArbitraryLoads 设置为true,这基本上会关闭 TLS,并会触发应用审核并需要理由。

旁注:&lt;access origin="*"/&gt; 也将 NSAllowsArbitraryLoads 设置为 true,但单独阻止初始 URL 加载到 webview 内(它从外部加载)。

我不知道需要什么 config.xml 或 NSAppTransportSecurity 设置的组合才能使其正常工作,而不能只允许所有内容以及无疑会触发的应用程序审核问题。

注意:这些请求不会触发 CSP 警告,我认为 webview 甚至没有走那么远,如果我将 allow-navigation 设置为 * 它可以工作,这表明 CSP 没问题。

当它失败时,我在网络调试器中获得的所有请求都是“尝试加载资源时发生错误”,而 XCode 控制台中没有任何内容。

【问题讨论】:

  • 嗨,奥斯汀。你找到解决这个问题的方法了吗?我发现自己处于几乎完全相同的位置;我想在我的 IOS 应用程序中包含一个带有 calendar.google.com 内容的 iframe。
  • 好像我做到了,但我不知道我是怎么做到的。回顾我的日志,我放弃了问题并转向其他事情。现在在 iPhone 10 上测试它,嵌入在 web 视图中的 iframe 中的地图正在工作。我在 config.xml 中使用
  • 我做的一件事就是从头开始重建我的项目。最初我使用 cordova 来创建项目并维护(和定制)它。后来我放弃了这种方法,并通过插件进行了所有定制,因此该项目完全是从头开始生成的。隐约可能有什么东西潜入了最初的项目,造成了混乱,但我无法想象。
  • 我注意到您的 iframe 中有一个“https”网址,但在允许导航中您只指定“http”...但是我认为您对允许导航仅支持“*”是正确的" 或完整的 URL;这也是我的经验。另外,您提到了 CSP,但您是否在 HTML 中包含了 CSP 元标头?

标签: ios cordova iframe


【解决方案1】:

在遇到同样的问题后,我找到了适合我的配置!

我希望我的应用在 iframe 中包含 Google 日历,这意味着我需要为 Cordova 指定 Google 日历的 URL 应在应用的 web 视图中处理。

拥有&lt;allow-navigation href="*" /&gt; 可以使其工作,但它的副作用是用户单击的所有链接也将在 Web 视图中处理(我的应用程序具有向用户提供新闻提要的功能,有时还有文本中的链接供用户单击)。在我的应用程序的全屏 Web 视图中包含任意网页,使用户无法导航回我的应用程序。在 Android 上总是有一个“返回按钮”,但在 iOS 上没有,迫使用户退出应用程序。

我的解决方案有两个:在允许导航中指定 URL 并设置允许内容和脚本的 CSP:

config.xml:

<access origin="*"/>
<allow-navigation href="https://calendar.google.com/*" />
<allow-navigation href="https://apis.google.com/*" />
<allow-navigation href="https://clients6.google.com/*" />

在 iOS 上,只有 calendar.google.com 是不够的;我必须找到 iframe 访问的所有域,因此需要上面的三个 URL。我使用 Chrome 的检查工具中的网络日志来查找这些域。 对于 Android,这不是必需的。

我本可以设置&lt;allow-navigation href="https://*.google.com/* /&gt;,但这对于我的需要来说过于宽泛(例如,指向“www.google.com”的链接将在 webview 而不是外部浏览器中处理)。

index.html:

<head>
...
    <meta http-equiv="Content-Security-Policy"
          content="default-src * 'self' data: gap: 'unsafe-inline' 'unsafe-eval';
          style-src * 'self' 'unsafe-inline' 'unsafe-eval' gap:;
          script-src * 'self' 'unsafe-inline' 'unsafe-eval' gap:;">
...

注意 - 上面的 CSP 可能允许的太多了。但这是一个起点,然后您可以根据应用的需要缩小访问范围。

现在,该应用可以在 iOS 和 Android 上正确地使用 Google Calender URL 呈现 iframe,并允许其他链接调用设备的浏览器,即在应用之外。

【讨论】:

  • CSP + 白名单配置对我有用,在带有 Cordova 的 IOS 中使用 IFrame 窗口。非常感谢
  • 这对我有用,而且我必须像这样在元标记的末尾添加 frame-src *。非常感谢!!
猜你喜欢
  • 2018-08-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-20
  • 1970-01-01
  • 2012-07-30
  • 2014-09-27
  • 1970-01-01
相关资源
最近更新 更多