UIWebViewDelegate 不监控 XMLHttpRequest? [英] UIWebViewDelegate not monitoring XMLHttpRequest?

查看:25
本文介绍了UIWebViewDelegate 不监控 XMLHttpRequest?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

UIWebViewDelegate 是否真的不监控使用 XMLHttpRequest 发出的请求?如果是这样,是否有办法监控此类请求?

Is it true that the UIWebViewDelegate does not monitor requests made by using a XMLHttpRequest? If so, is there a way to monitor these kind of requests?

例如UIWebViewDelegate 没有在 -(BOOL) webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSMutableURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType;

e.g. UIWebViewDelegate does not catch this in -(BOOL) webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSMutableURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType;

var xhr = new XMLHttpRequest();
xhr.open("GET", "http://www.google.com", true);

xhr.onreadystatechange=function() 
{
    if (xhr.readyState==4) 
    {
        alert(xhr.responseText);
    }
}

xhr.send();

推荐答案

有趣的问题.

有两个部分来完成这项工作:JavaScript 处理程序和 UIWebView 委托方法.在 JavaScript 中,我们可以修改原型方法以在创建 AJAX 请求时触发事件.使用我们的 UIWebView 委托,我们可以捕获这些事件.

There are two parts to make this work: a JavaScript handler and UIWebView delegate methods. In JavaScript, we can modify prototype methods to trigger events when an AJAX request is created. With our UIWebView delegate, we can capture these events.

JavaScript 处理程序

我们需要在 AJAX 请求发出时得到通知.我在此处找到了解决方案.

We need to be notified when an AJAX request is made. I found the solution here.

在我们的例子中,为了使代码正常工作,我将以下 JavaScript 放在一个名为 ajax_handler.js 的资源中,该资源与我的应用程序捆绑在一起.

In our case, to make the code work, I put the following JavaScript in a resource called ajax_handler.js which is bundled with my app.

var s_ajaxListener = new Object();
s_ajaxListener.tempOpen = XMLHttpRequest.prototype.open;
s_ajaxListener.tempSend = XMLHttpRequest.prototype.send;
s_ajaxListener.callback = function () {
    window.location='mpAjaxHandler://' + this.url;
};

XMLHttpRequest.prototype.open = function(a,b) {
  if (!a) var a='';
  if (!b) var b='';
  s_ajaxListener.tempOpen.apply(this, arguments);
  s_ajaxListener.method = a;  
  s_ajaxListener.url = b;
  if (a.toLowerCase() == 'get') {
    s_ajaxListener.data = b.split('?');
    s_ajaxListener.data = s_ajaxListener.data[1];
  }
}

XMLHttpRequest.prototype.send = function(a,b) {
  if (!a) var a='';
  if (!b) var b='';
  s_ajaxListener.tempSend.apply(this, arguments);
  if(s_ajaxListener.method.toLowerCase() == 'post')s_ajaxListener.data = a;
  s_ajaxListener.callback();
}

这实际上是将浏览器的位置更改为一些已编造的 URL 方案(在本例中为 mpAjaxHandle),其中包含有关所发出请求的信息.不用担心,我们的代表抓住了这个,位置不会改变.

What this will actually do is change the location of the browser to some made up URL scheme (in this case, mpAjaxHandle) with info about the request made. Don't worry, our delegate with catch this and the location won't change.

UIWebView 委托

首先,我们需要阅读我们的 JavaScript 文件.我建议将其存储在静态变量中.我有使用 +initialize 的习惯.

First, we need to read our JavaScript file. I suggest doing storing it in a static variable. I'm in the habit of using +initialize.

static NSString *JSHandler;

+ (void)initialize {
    JSHandler = [[NSString stringWithContentsOfURL:[[NSBundle mainBundle] URLForResource:@"ajax_handler" withExtension:@"js"] encoding:NSUTF8StringEncoding error:nil] retain];
}

接下来,我们希望在页面加载完成之前注入此 JavaScript,以便我们可以接收所有事件.

Next, we want to inject this JavaScript before a page is done loading so we can receive all events.

- (void)webViewDidStartLoad:(UIWebView *)webView {
    [webView stringByEvaluatingJavaScriptFromString:JSHandler];
}

最后,我们要捕获事件.

Finally, we want to capture the event.

既然 URL Scheme 是编出来的,我们就不想真正去遵循它.我们返回NO,一切都很好.

Since the URL Scheme is made up, we don't want to actually follow it. We return NO and all is well.

#define CocoaJSHandler          @"mpAjaxHandler"

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
    if ([[[request URL] scheme] isEqual:CocoaJSHandler]) {
        NSString *requestedURLString = [[[request URL] absoluteString] substringFromIndex:[CocoaJSHandler length] + 3];

        NSLog(@"ajax request: %@", requestedURLString);
        return NO;
    }

    return YES;
}

我使用该解决方案创建了一个示例项目,但无处可托管.如果你可以主持它,你可以给我留言,我会相应地编辑这篇文章.

I created a sample project with the solution but have nowhere to host it. You can message me if you can host it and I'll edit this post accordingly.

这篇关于UIWebViewDelegate 不监控 XMLHttpRequest?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆