使用自定义NSURLProtocol在UIWebView中通过AJAX调用加载文本文件失败
我想使用UiWebView
在iOS应用上显示一个网站。 站点的某些组件(即使用AJAX调用加载的Web服务结果)应替换为本地数据。
请考虑以下示例:
的text.txt:
foo
page1.html:
test function init(){ $.get("text.txt",function(text){ $("#target").text(text); }); } $(init);
查看控制器:
@interface ViewController : UIViewController @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上根本没有任何事情发生。 我试图做一些error handling,但是既没有抛出JS AJAX错误,也没有调用UIWebViewDelegate
didFailLoadWithError
。
我尝试了另一个场景并创建了一个只加载图像的HTML页面:
并修改我的URLProtocol只是处理图像的加载 – 这是正常的。 也许这与AJAX调用有关?
你知道问题可能是什么吗?
提前致谢!
我有同样的问题,经过几天的拔毛后终于解决了:
您的问题来自您创建响应的方式,您必须创建状态200响应并强制WebView在必要时允许跨域请求:
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];
您可以在我的答案中看到我的完整工作实现:
如何使用NSURLProtocol模拟AJAX调用?
希望这有帮助,文森特