【问题标题】:Cordova(Phonegap) ajax calls hanging on iphone deviceCordova(Phonegap) ajax 调用挂在 iPhone 设备上
【发布时间】:2015-10-19 22:10:01
【问题描述】:

我进行的 ajax 调用在浏览器和 android 上运行良好,但是在 iphone 上运行时它会永远挂起,或者如果添加了超时选项则会超时。

ajax 看起来像:

$.ajax({
  url: "http://pbcc.ca/xxx/index.php",
  data: {api: 'test'},
  type: "GET",
  dataType: "jsonp",
  jsonp: 'callback',
  beforeSend: function() {
    alert("beforeSend");
  },
  success: function(data) {
    alert("success");
  },
  error: function(e,x) {
    alert("error");
  }
});

我在文档准备好和设备准备好之后尝试了它,只是在这两种情况下都在发送响应之前。网上有几篇类似问题的帖子,我尝试了一些方法,但都没有解决我的问题。任何人都可以帮忙吗?谢谢。

更新:在服务端测试,服务端没有响应来自ios的ajax调用。实际上我认为没有数据传输到服务器。

更新2

我收到此错误:

Refused to load the script 'http://www.pbcc.ca/xxx/index.php?callback=...' because it violates the following Content Security Policy directive: "default-src 'self' data: gap: https://ssl.gstatic.com 'unsafe-eval'". Note that 'script-src' was not explicitly set, so 'default-src' is used as a fallback.

元:

<meta http-equiv="Content-Security-Policy" content="default-src 'self' data: gap: https://ssl.gstatic.com 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *; connect-src http://pbcc.ca">

Info.plist(我一开始没把它们放在一起):

<key>NSAppTransportSecurity</key>
<dict>
  <key>NSAllowsArbitraryLoads</key>
  <true/>
  <key>NSExceptionDomains</key>
  <dict>
    <key>pbcc.ca</key>
    <dict>
      <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
      <true/>
    </dict>
  </dict>
</dict>

config.xml(默认由cordova创建):

<?xml version='1.0' encoding='utf-8'?>
<widget id="com.polarbear.lunch" version="0.0.1" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
    <name>xxx</name>
    <description>
        A sample Apache Cordova application that responds to the deviceready event.
    </description>
    <author email="dev@cordova.apache.org" href="http://cordova.io">
        Apache Cordova Team
    </author>
    <content src="index.html" />
    <plugin name="cordova-plugin-whitelist" version="1" />
    <access origin="*" />
    <allow-intent href="http://*/*" />
    <allow-intent href="https://*/*" />
    <allow-intent href="tel:*" />
    <allow-intent href="sms:*" />
    <allow-intent href="mailto:*" />
    <allow-intent href="geo:*" />
    <platform name="android">
        <allow-intent href="market:*" />
    </platform>
    <platform name="ios">
        <allow-intent href="itms:*" />
        <allow-intent href="itms-apps:*" />
    </platform>
</widget>

【问题讨论】:

  • 您使用的是哪个版本的 Cordova 和 iOS?
  • cordova 5.3.3 和 ios 9.0.2(iphone 6 plus)
  • ?您还尝试过哪些方法,如果您使用的是带有 Cordova 5 的 iOS 9,您可能需要在 index.html 的元标记中正确设置 Content-Security-Policy 以及为 pbcc.ca 设置 Apple 的 App Transport Security 异常您应用的 Info plist 文件。
  • @SimonPrickett Content-Security-Policy 设置是由 cordova 默认创建的。你能举一个传输安全异常设置的例子吗?我是 ios 新手,所以不知道。
  • 我在网上搜索过。有人说应该设置NSAppTransportSecurity,但是我在xcode中没有找到这个key。

标签: ios ajax cordova


【解决方案1】:

Xcode 7 将使用 iOS 9,默认情况下不允许 HTTP 后端调用,除非使用 NSAllowsArbitraryLoads 覆盖并禁用 App Transport Security 或配置异常。

以下是更改应用信息 .plist 的工作示例:

<key>NSAppTransportSecurity</key>
<dict>
  <key>NSAllowsArbitraryLoads</key>
  <true/>
</dict>

下面是一个脚本,您可以将其用作 iOS 的预构建挂钩来自动执行此操作:

#!/bin/bash
echo "Adjusting plist for App Transport Security exception." val=$(/usr/libexec/plistbuddy -c "add NSAppTransportSecurity:NSAllowsArbitraryLoads bool true" platforms/ios/PROJECTNAME/PROJECTNAME-Info.plist 2>/dev/null) echo "Done"

只需将 PROJECTNAME 替换为您的项目名称即可。

您也可以只为您的服务器设置一个例外,而不是启用与所有后端的 http 连接...要做到这一点,请使用以下内容:

<key>NSAppTransportSecurity</key>
<dict>
    <key>NSExceptionDomains</key>
    <dict>
        <key>pbcc.ca</key>
        <dict>
            <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
            <true/>
        </dict>
    </dict>
</dict>

此外,您需要在 index.html 中的 Cordova 内容安全策略元标记中设置 connect-src。使用这样的东西:

<meta http-equiv="Content-Security-Policy" content="default-src 'self' data: gap: https://ssl.gstatic.com 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *; connect-src http://pbcc.ca">

或使用:

connect-src *

如果您想开放连接到任何地方以进行 Ajax 调用。有关内容安全策略的更多信息,请联系found hereconfiguration tool here

您需要同时进行这两项更改(内容安全策略和应用程序传输安全例外)才能使其与 iOS 9 / Cordova 5 / XCode 7 一起使用。

除了您发布的错误“拒绝加载脚本'http://www.pbcc.ca/xxx/index.php?callback=...',因为它违反了以下内容安全策略指令:“default-src 'self' data: gap:https://ssl.gstatic.com'unsafe- eval'"。请注意,'script-src' 没有明确设置,因此 'default-src' 用作后备。"

我们可以看到,您无法加载远程文档,因为它违反了您的内容安全政策。要解决此问题,请将 default-src 设置为 * 或添加 script-src www.pbcc.ca。示例:

<meta http-equiv="Content-Security-Policy" content="default-src 'self' data: gap: https://ssl.gstatic.com 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *; connect-src http://pbcc.ca; script-src http://www.pbcc.ca">

请注意,您正在混合和匹配 www.pbcc.ca 和 pbcc.ca,因此您可能需要确保指定正确的,或者使用 * 将其打开以确保其正常工作,然后将其锁定为特定的主机。

【讨论】:

  • 嗯……还是不行。我添加了 connect-src 和 NSAppTransportSecurity。我做了以下步骤来测试: 1.cordova build ios --device 2.在xcode中打开项目并在真正的设备上运行它,这是带有IOS9的iphone 6+。 xcode的调试显示0网络数据。
  • 将很难调试,除非您可以完整发布 Content-Security-Policy 标签和 plist 的相关部分。可能也是您的 config.xml。您是否在 Xcode 控制台中看到任何错误,或者通过附加 Safari 远程调试器并查看那里的 JS 控制台然后执行命令 + R 重新加载页面并查看是否出现任何错误?
  • 更新顶帖,请看'Update2'
  • 更新了我的答案见 script-src 部分。
  • 是的,我刚刚想通了。再次感谢你。 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多