使用自定义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调用?

希望这有帮助,文森特