等待 AJAX 和 iOS
Wait for AJAX with iOS
我有一个基本的 HTML 页面,它只不过是外部脚本的起点(它只包含一个 html
、head
、script
标签)。在这个外部脚本中,我向 Google API 发出 AJAX 请求,然后对返回的数据进行一些解析。当我完成解析时,我将修改后的 JSON 放回 DOM 并且脚本终止。
最后一切正常。 AJAX 对 Google API 的请求进行得很顺利,不到 3 秒我就有了一个 HTML 页面,其中一些 JSON 被放入 pre
标签。
当我尝试从 iOS 应用程序向该页面发出请求时,问题开始出现。问题是无论我做什么,来自请求的数据总是只返回基本的 HTML 页面。 请求完成之前可以将JSON放入DOM,因为AJAX请求需要时间。
我已经在应用程序中尝试了以下所有方法,但均无济于事。
- 直线上升
+[NSData dataWithContentsOfURL:options:error:]
NSHTTPRequest
[NSURLConnection sendSynchronousRequest:returningResponse:error:]
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
我有一个基本的 HTML 页面,它只不过是外部脚本的起点(它只包含一个 html
、head
、script
标签)。在这个外部脚本中,我向 Google API 发出 AJAX 请求,然后对返回的数据进行一些解析。当我完成解析时,我将修改后的 JSON 放回 DOM 并且脚本终止。
最后一切正常。 AJAX 对 Google API 的请求进行得很顺利,不到 3 秒我就有了一个 HTML 页面,其中一些 JSON 被放入 pre
标签。
当我尝试从 iOS 应用程序向该页面发出请求时,问题开始出现。问题是无论我做什么,来自请求的数据总是只返回基本的 HTML 页面。 请求完成之前可以将JSON放入DOM,因为AJAX请求需要时间。
我已经在应用程序中尝试了以下所有方法,但均无济于事。
- 直线上升
+[NSData dataWithContentsOfURL:options:error:]
NSHTTPRequest
[NSURLConnection sendSynchronousRequest:returningResponse:error:]
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