使用自定义NSURLProtocol在UIWebView中通过AJAX调用加载文本文件失败 [英] Loading text file by AJAX call in UIWebView using custom NSURLProtocol fails

查看:103
本文介绍了使用自定义NSURLProtocol在UIWebView中通过AJAX调用加载文本文件失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用 UiWebView 在iOS应用上显示网站。该站点的某些组件(即使用AJAX调用加载的Web服务结果)应替换为本地数据。

I want to display a website on an iOS app using a UiWebView. Some components of the site (namely the webservice results loaded using AJAX calls) should be replaced by local data.

请考虑以下示例:

text.txt:

foo

page1.html:

<html><head>
    <title>test</title>
    <script type="text/javascript" src="jquery.js"></script>
</head>
<body>
<div id="target"></div>
<script type="text/javascript">
    function init(){
        $.get("text.txt",function(text){    
            $("#target").text(text);
        });
    }
    $(init);
</script>
</body></html>

查看控制器:

@interface ViewController : UIViewController <UIWebViewDelegate>
    @property (nonatomic,assign) IBOutlet UIWebView *webview;
@end


@implementation ViewController
    @synthesize webview;
    //some stuff here
    - (void)viewDidLoad
    {
        [super viewDidLoad];
        [NSURLProtocol registerClass:[MyProtocol class]];
        NSString *url = @"http://remote-url/page1.html";
        NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]];
        [request setCachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData];
        [webview loadRequest:request];
    }
@end

MyProtocol:

@interface MyProtocol : NSURLProtocol

@end

@implementation MyProtocol

+ (BOOL) canInitWithRequest:(NSURLRequest *)req{
    NSLog(@"%@",[[req URL] lastPathComponent]);
    return [[[req URL] lastPathComponent] caseInsensitiveCompare:@"text.txt"] == NSOrderedSame;
}

+ (NSURLRequest*) canonicalRequestForRequest:(NSURLRequest *)req{
    return req;
}

- (void) startLoading{

    NSLog(@"Request for: %@",self.request.URL);
    NSString *response_ns = @"bar";
    NSData *data = [response_ns dataUsingEncoding:NSASCIIStringEncoding];
    NSURLResponse *response = [[NSURLResponse alloc] initWithURL:[self.request URL] MIMEType:@"text/plain" expectedContentLength:[data length] textEncodingName:nil];

    [[self client] URLProtocol: self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageNotAllowed];
    [[self client] URLProtocol:self didLoadData:data];
    [[self client] URLProtocolDidFinishLoading:self];
    [response release];
}

- (void) stopLoading{
    NSLog(@"stopLoading");
}

@end

如果我不注册我的自定义URLProtocol页面正确显示。如果我调用了 startLoading(),则会加载内容,之后会触发 stopLoading()。但是在UIWebView上根本没有任何事情发生。我试图做一些错误处理,但既没有抛出JS AJAX错误,也没有调用 UIWebViewDelegate didFailLoadWithError

If I don't register my custom URLProtocol the page is displayed properly. If I do startLoading() is called, the content is loaded and stopLoading() is triggered afterwards. But on the UIWebView nothing happends at all. I tried to do some error-handling, but neither is a JS AJAX error thrown nor is didFailLoadWithError of the UIWebViewDelegate called.

我尝试了另一个场景并创建了一个只加载图片的HTML页面:

I tried another scenario and created a HTML page that just loads an image:

<img src="image.png" />

并修改了我的URLProtocol以处理图像的加载 - 这可以正常工作。也许这与AJAX调用有关?

and modified my URLProtocol to just handle the loading of the image - this works properly. Maybe this has anything to do with AJAX calls?

您是否知道问题可能是什么?

Do you have any idea what the problem might be?

提前致谢!

推荐答案

我遇到了同样的问题,经过几天的拔毛后终于解决了这个问题:

I had the same problem and finally solved it after days of hair pulling :

您的问题来自您创建响应的方式,您必须创建状态200响应并强制WebView在必要时允许跨域请求:

Your problem comes from the way you create the response, you have to create a status 200 response and force the WebView to allow cross-domain request if necessary :

NSDictionary *headers = @{@"Access-Control-Allow-Origin" : @"*", @"Access-Control-Allow-Headers" : @"Content-Type"};
NSHTTPURLResponse *response = [[NSHTTPURLResponse alloc] initWithURL:request.URL statusCode:200 HTTPVersion:@"1.1" headerFields:headers];

您可以在我的答案中看到我的完整工作实现:

You can see my full working implementation in my answer here :

如何使用NSURLProtocol模拟AJAX调用?

希望这会有所帮助,
Vincent

Hope this helps, Vincent

这篇关于使用自定义NSURLProtocol在UIWebView中通过AJAX调用加载文本文件失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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