【发布时间】:2016-11-18 06:24:06
【问题描述】:
我正在使用 Cordova 的 CLI 构建一个由 HTML、CSS 和 JavaScript 组成的移动应用程序。该应用程序使用 jQuery 2.1.4、jQuery Mobile 1.4.5,并与 Cordova 6.4.0 一起打包。该应用程序面向 Android 6.0.0 和 iOS 10.1。
我有一个问题,我的所有 ajax 调用都只挂在 iPhone 7 设备上。下面是我正在尝试进行的一种 ajax 调用的示例。
$.ajax({
type: 'POST',
url: 'https://my.domain.com/myendpoint.php?parm=value',
beforeSend: function (request) {
request.setRequestHeader('Content-Type', 'application/json');
request.setRequestHeader('Accept', 'application/json');
request.setRequestHeader('Authorization', 'Basic ' + authstring);
}
})
我无法向我的任何端点发出 GET 或 POST 请求,所有端点都无限期地挂起。当我向请求添加 60 秒的超时时,超时将在 60 秒后触发我的失败功能。我尝试在启用应用传输安全的情况下访问 HTTPS 端点,以及在禁用应用传输安全的情况下访问 HTTP 端点。无论我尝试什么,ajax 都会挂起并且永远不会失败或完成,除非我包含超时。
我已经在 iPhone 5、iPhone 5C、iPhone 6 和 iPhone 6S 上测试了该应用程序,所有这些都在 iOS 10.1.1 上。这些不会挂起,并且 ajax 请求按预期完成。更奇怪的是,ajax 请求也适用于 XCode 的 iPhone 7 模拟器。但是,我所有的 iPhone 7 用户以及我的 iPhone 7 测试设备都遇到了 ajax 无限期挂起的问题。
关于如何解决此问题的任何建议?
编辑:
我能够通过添加元标记使其工作:
<meta http-equiv="Content-Security-Policy" content="default-src * 'self' data: gap: https://ssl.gstatic.com 'unsafe-eval'; style-src * 'self' 'unsafe-inline'; script-src * 'self' 'unsafe-inline'; connect-src * https: http:">
我通过向所有值添加通配符来修改了cordova 创建的元默认元标记。我还在标签中添加了 script-src 和 connect-src。我最初在没有通配符的情况下尝试了它们,但这也没有解决我的问题,所以我只是在这两个键中都包含了通配符,并且 ajax 请求开始工作。
编辑 2:
作为可能遇到类似问题的其他人的旁注,如果将带有无效凭据的基本身份验证标头发送到 IIS 服务器,iOS 设备也会导致 ajax 请求无限期挂起。发送无效凭据时,IIS 服务器默认配置为发送回带有 HTTP 标头“WWW-Authenticate”的 401。如果设备收到此标头,它不会将响应传递回应用层,这意味着您的失败函数将永远不会触发。这似乎是 iOS 和 Cordova 应用程序的一个已知问题。在客户端规避该问题的一种快速而肮脏(尽管不是理想)的方法是将 ajax 请求设置为与 ajax 选项“async:false”同步。这将强制将响应返回给应用程序层,以便应用程序可以继续前进,这意味着您的错误功能将触发。如果您的所有 ajax 请求都需要基本授权,这不会对您的应用程序有任何好处,但它至少可以帮助您诊断问题。
【问题讨论】: