等待 AJAX 和 iOS

Wait for AJAX with iOS

我有一个基本的 HTML 页面,它只不过是外部脚本的起点(它只包含一个 htmlheadscript标签)。在这个外部脚本中,我向 Google API 发出 AJAX 请求,然后对返回的数据进行一些解析。当我完成解析时,我将修改后的 JSON 放回 DOM 并且脚本终止。

最后一切正常。 AJAX 对 Google API 的请求进行得很顺利,不到 3 秒我就有了一个 HTML 页面,其中一些 JSON 被放入 pre 标签。

当我尝试从 iOS 应用程序向该页面发出请求时,问题开始出现。问题是无论我做什么,来自请求的数据总是只返回基本的 HTML 页面。 请求完成之前可以将JSON放入DOM,因为AJAX请求需要时间。

我已经在应用程序中尝试了以下所有方法,但均无济于事。

  1. 直线上升+[NSData dataWithContentsOfURL:options:error:]
  2. NSHTTPRequest
  3. [NSURLConnection sendSynchronousRequest:returningResponse:error:]
  4. NSURLRequest

我用过各种不同的方式从 iOS 应用发出请求,但它们都有同样的问题。每次向我的页面发出请求时,只返回基本的 HTML 页面。这是所有 4 种方法的示例输出。

<html>
    <head>
        <!-- Link to our custom script. Makes an AJAX request then puts JSON into the pre -->
        <script src="mpservice.js"></script>
    </head>

    <pre id="output"></pre>

</html> 

注意 pre 标签是空的,因为在请求终止时,AJAX 调用和解析尚未完成,我还没有将 JSON进入 DOM.

我的问题如下,如何从 iOS 应用程序中发出请求,等待任何 AJAX 调用完成后再返回?

感谢您抽出时间,如果我不够具体,请随时发表评论。如果您想查看我正在谈论的页面(为了证明 JSON 最终被放入 pre 标记,请转到 silicode.us/freeform

这里是一个简单的错误。据我了解,您假设正在发生的事情是当您调用 [NSData dataWithContentsOfURL:options:error:] 等时页面将加载(并呈现)-事实并非如此。您列出的这些请求仅在单个请求中检索HTML,它们不会加载额外的资产(如图像或CSS)并且它们不JavaScript处理。他们只是对文件(网页)发出 HTTP 请求,该文件未经修改且未呈现。

如果您有使用 Javascript 在页面上显示的数据,您的 选项是 运行 即 Javascript。您可以 运行 JavaScript 的唯一方法(这是良好做法)是在 UIWebView 中呈现该页面。

您可以像这样在 iOS 中创建 UIWebView:

UIWebView *browser = [[UIWebView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
NSURL *websiteUrl = [NSURL URLWithString:@"http://silicode.us/freeform/"];
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:websiteUrl];
[browser loadRequest:urlRequest];

在这个阶段,网页会在浏览器中呈现,并最终在pre-tag中呈现JSON。您可能会循环等待以检查它是否出现:

- (void)checkPreTag {
    NSString *preContent = [browser stringByEvaluatingJavaScriptFromString:@"function f() { var op = document.getElementById(\"output\"); return op.innerHTML.trim(); } f();"];
    if ([preContent length] > 0) {
        // do something with the data
    } else {
        // wait again
        [self performSelector:@selector(checkPreTag) withObject:nil afterDelay:0.25];
    }
}

我没有测试过这段代码,但我确信只需要稍作修改(如果有的话)就可以使其适合您的用例。

请注意,此方法远非理想,您应该寻找更直接的途径到达 JSON 内容,而不是等待它被异步准备。

您还应该只在 页面加载后才开始检查 checkPreTag 函数 ,使用委托方法:- (void)webViewDidFinishLoad:(UIWebView *)webView