使用AJAX / XMLHttpRequest时不调用shouldStartLoadWithRequest

时间:2010-04-25 11:03:39

标签: iphone-sdk-3.0 iphone

我正在尝试将方法调用从JavaScript发送到Objective-C,反之亦然。一切都适用于window.location触发的url,这是由shouldStartLoadWithRequest捕获的。现在,如果我尝试使用AJAX调用,则不会调用shouldStartLoadWithRequest。 有没有办法做到这一点?主要是我不希望限制在可以从JavaScript传递给Objective-C的数据的最大URL大小。

我的UIWebViewDelegate实现:

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
 NSString *url = [[request URL] absoluteString];
 NSRange urlrange = [url rangeOfString:@"myScheme://"];
 if(urlrange.length > 0){
  NSLog(@"this is an objective-c call, do not load link: %@", [url substringWithRange:NSMakeRange(urlrange.location, [url length])] );
  return NO;
 } else {
  NSLog(@"not an objective-c call, load link: ", url );
  return YES;
 }
}

我的JavaScript调用:

// works
window.location.href = "myScheme://readyHref";  

// fails
var xmlHttpReq = false;
if (window.XMLHttpRequest) {
 xmlHttpReq = new XMLHttpRequest();
} else if (window.ActiveXObject) {
 xmlHttpReq = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlHttpReq.open('GET', "myScheme://readyAJAX", false);
xmlHttpReq.send();

3 个答案:

答案 0 :(得分:10)

如果您希望有一种更简洁的方法将数据从JavaScript传输到Objective-C,您可以按照以下步骤操作:

  1. 一旦你有了想要发送回Objective-C的JS数据,那么在JS中将它存储在一些全局可访问的变量中,例如: var myTempData = ...
  2. 使用上述document.location = 'myapp://fire-some-event'
  3. 的技巧
  4. 进入Objective-C代码后执行[myWebView stringByEvaluatingJavaScriptFromString:@"myTempData"]
  5. 我认为你已经完成了,请注意线程/对象到字符串通过json编码。

答案 1 :(得分:2)

虽然我找不到为什么AJAX请求没有被shouldStartLoadWithRequest拦截的答案,但我找到了两个解决方法。我假设JavaScript请求没有被拦截,只有HTML关联/原始请求。如果任何人可以验证或纠正这一点,我会很高兴。

这两个变通方法很简单。一方面,似乎URL中256个字符的限制不会影响MobileSafari或至少是该状态下的url。我读到Safari allows 80'000 charcters。但是我对此并不满意。因此,解决方法#2是使用一个使用POST方法的html表单并将操作设置为您的方案。数据可以以表格形式存储为输入字段的值等。在使用JavaScript提交表单后,触发了StartStoLoadWithRequest,并且可以从HTTPBody中检索数据。

答案 2 :(得分:2)

我不确定这是否适合您,但如果您尝试使用shouldStartLoadWithRequest以便从javascript访问本机电话功能,则可以使用PhoneGap。它是一个方便的开源Objective-c框架,能够桥接javascript和objective-c。

我需要一种异步方式使手机从javascript振动的方法,我查看了PhoneGap源,看看他们是如何做到这一点的。经过一些测试后,我发现$ .ajax不会被shouldStartLoadWithRequest拦截,并且它在拦截http请求时非常特别。你可以通过调用document.location而不是$ .ajax并使用另一个协议(如gap://而不是http://)来使一切正常运行。

所以javascript代码看起来像:
document.location = "gap://vibrate";

目标-c代码:

- (BOOL)webView:(UIWebView*)webView shouldStartLoadWithRequest:(NSURLRequest*)request navigationType:(UIWebViewNavigationType)navigationType {
    NSURL *url = request.URL;
    NSString *urlString = url.relativeString;

  if ([urlString isEqualToString:@"gap://vibrate"])
  {
    AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
  };

    return YES;
}