【问题标题】:Cross-domain ajax request not executing in iOS Simulator using Phonegap跨域 ajax 请求未在 iOS 模拟器中使用 Phonegap 执行
【发布时间】:2014-07-04 14:30:09
【问题描述】:

我刚刚开始使用 Phonegap 和一般的移动开发,并且在从 iOS 模拟器运行时尝试调用 $.ajax(...) 以做任何事情或 iOS 设备 - 但我的小应用在从浏览器或 Ripple 模拟器 (http://ripple.incubator.apache.org/) 运行时都能正常运行。

另外,我已经熟悉了 CORS,并且我的测试似乎表明我的请求/响应标头已正确设置用于跨域客户端-服务器通信。使用 Safari WebInspector 的 JS 调试器来逐步执行(并监视我的服务器的 Apache 日志),我已经能够确定对 xhr.send() 的调用从未真正执行过。

一旦我意识到这一点,我就从等式中删除了 jQuery,以防我不正确地设置了 $.ajax() 请求,并使用下面的代码创建了 CORS 请求(从这里获得:http://www.html5rocks.com/en/tutorials/cors/

在这两种情况下(使用和不使用 jQuery),我在调试器中注意到在调用 xhr.open(...) 之后 xhr.status 和 xhr.statusText 的值都设置为“[Exception : DOMException]",我假设这是阻止 xhr.send() 执行的原因。

另外,我的 config.xml 包含以下行:

<access origin="*" />

这是创建和执行请求的代码:

// Create the XHR object.
function createCORSRequest(method, url) {
  var xhr = new XMLHttpRequest();
  if ("withCredentials" in xhr) {
    // XHR for Chrome/Firefox/Opera/Safari.
    xhr.open(method, url, true);
  } else if (typeof XDomainRequest != "undefined") {
    // XDomainRequest for IE.
    xhr = new XDomainRequest();
    xhr.open(method, url);
  } else {
    // CORS not supported.
    xhr = null;
  }
  return xhr;
}

// Helper method to parse the title tag from the response.
function getTitle(text) {
  return text.match('<title>(.*)?</title>')[1];
}

// Make the actual CORS request.
function makeCorsRequest() {
  // All HTML5 Rocks properties support CORS.
  var url = 'http://server.mylocalhost/api/action?arg1=foo';

  var xhr = createCORSRequest('GET', url);
  if (!xhr) {
    alert('CORS not supported');
    return;
  }

  // Response handlers.
  xhr.onload = function() {
    var text = xhr.responseText;
    var title = getTitle(text);
    alert('Response from CORS request to ' + url + ': ' + title);
  };

  xhr.onerror = function() {
    alert('Whoops, there was an error making the request.');
  };

  xhr.send();
}

注意:上面在 makeCorsRequest() 中指定的 url 反映了我在应用程序中定位的 url 的实际结构。

我的设置:

  • 完全控制 ajax 请求的两端
  • 在本地开发,为客户端和服务器使用单独的 apache 虚拟主机(例如,http://server.mylocalhosthttp://mobile.mylocalhost
  • 所有内容的最新版本(Phonegap/Cordova、Xcode、Ripple、Chrome、Safari、Jquery、OSX/Mavericks 等)

我觉得我一定遗漏了一些非常基本的东西......有什么想法吗?

另外,我不想使用 JSONP。

【问题讨论】:

    标签: jquery ajax cordova cross-domain


    【解决方案1】:

    这原来是网络 (DNS) 层的问题。事实证明,Xcode iOS 模拟器忽略了宿主机的 /etc/hosts 文件,并且似乎没有等效的方法来控制模拟器环境中的 DNS。所以,据我所知,使用基于名称的虚拟主机在本地开发机器上进行开发是不可能的……这似乎是一个非常荒谬的限制。

    由于 iOS 模拟器显然确实知道如何找到“localhost”,我通过将以下行添加到作为我的目标 API 端点的虚拟主机的 VirtualHost 容器来解决我的问题(在适当的 Apache conf 文件):

    ServerAlias localhost
    

    然后我将 makeCorsRequest() 中的 url 更改为以下形式:

    var url = 'http://localhost/api/action?arg1=foo';
    

    在我的代码的基于 jQuery 的版本中进行类似的更改也有效。

    可能有其他/更好的方法来解决这个可悲的限制,但现在这个修复让我能够重新真正专注于我的应用程序。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-02-14
      • 2012-12-04
      • 1970-01-01
      • 2016-06-19
      • 2012-09-30
      • 1970-01-01
      • 2014-09-10
      • 2013-03-06
      相关资源
      最近更新 更多