【问题标题】:shouldStartLoadWithRequest is not called when using AJAX/XMLHttpRequest使用 AJAX/XMLHttpRequest 时不调用 shouldStartLoadWithRequest
【发布时间】:2010-04-25 11:03:39
【问题描述】:

我正在尝试将方法调用从 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();

【问题讨论】:

    标签: iphone-sdk-3.0 iphone


    【解决方案1】:

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

    1. 一旦你有 JS 数据你想发送回 Objective-C 然后在 JS 中将它存储在一些全局可访问的变量中,例如var myTempData = ...
    2. 使用document.location = 'myapp://fire-some-event'的上述技术
    3. 在您的 Objective-C 代码中执行 [myWebView stringByEvaluatingJavaScriptFromString:@"myTempData"]
    4. 我想你已经完成了,注意 threading/object-to-string-via-json-encoding。

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

        【解决方案3】:

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

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

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

        以及objective-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);
          };
        
            返回是;
        }

        【讨论】:

          猜你喜欢
          • 2012-01-21
          • 2021-02-03
          • 1970-01-01
          • 2018-04-03
          • 2013-08-29
          • 1970-01-01
          • 2011-02-25
          • 2013-08-04
          • 2015-09-29
          相关资源
          最近更新 更多