2010-02-10 136 views

回答

7

你可以捕捉这里的URLRequest:

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType 

及以上的委托手请求并返回无。然后在从NSURLConnection接收到的响应呼叫中取消连接,如果一切正常(检查响应)再次在webview中加载urlrequest。请确保在再次加载urlrequest时在上述呼叫中返回YES。

不是很优雅,但它可能工作。

+0

感谢您的答复。如何在html字符串中搜索一个字符串?我被困住了。 – EEE 2010-02-12 07:49:14

+0

如果您捕获请求,您可以启动自己的'NSUrlconnection'并收集接收到的连接数据,在'connectionDidFinishLoading'中,您可以访问html。 – FelixLam 2010-02-12 09:45:13

+0

其实我已经访问过html,问题是在objective-c的html中搜索字符串,但是我已经用c解决了。谢谢。 – EEE 2010-02-12 12:28:10

7

您错误地解释了-didFailLoadWithError的用途。技术上,请求成功。它能够击中服务器并发现你所请求的文件不存在(即404)。例如,如果服务器不存在,则会调用-didFailLoadWithError方法。您的服务器存在。该文件没有。网络视图不会解释内容中的错误。 -didFailLoadWithError从UIWebViewDelegate苹果文档的目的是:

如果发送Web视图加载失败 内容。

从维基百科文章上HTTP 404

404或Not Found错误消息是 指示客户端是能够 一个HTTP标准响应代码 与服务器进行通信,但 服务器找不到要求的 。 404错误不应该与 混淆“找不到服务器”或 类似的错误,其中到目标服务器的连接 根本不可能是 。

在你必须解析为404,你可以用一个NSURLConnection的/的NSURLRequest组合,而不是一个Web视图获取响应文本的所有可能性。

最好的问候,

+0

感谢您的回复。我只是误解了didFailLoadError方法。 – EEE 2010-02-11 20:12:27

+1

解析错误代码的响应文本是一个坏主意,响应文本可能是任何东西!查看我的答案,了解获取HTTP状态代码的真正方法。 – 2010-06-07 08:12:39

7

NSURLConnection的是你正在寻找的课,我不认为这可以直接在一个UIWebView来完成。

您可以使用同步方法

+ (NSData *)sendSynchronousRequest:(NSURLRequest *)request returningResponse:(NSURLResponse **)response error:(NSError **)error 

还是异步的。这些设置比较困难,因为您必须将所有数据位添加到1个NSData中,但最终结果是相同的。


不管,如果你使用的同步或异步方法:

如果你得到一个NSError *对象,然后出现了一个COMMS错误。正如其他回复中指出的那样,这不是HTTP状态代码,而是通信问题。

如果连接成功,你会得到一个NSURLResponse和NSData的。重要的是,HTTP请求的NSURLResponse实际上是NSHTTPURLResponse子类!

然后你必须检查响应看到错误代码是什么。试试这个(其中_responseInfo是你NSURLResponse对象):

NSInteger httpStatusCode = (NSHTTPURLResponse*)_responseInfo.statusCode; 

responseInfo应该永远是HTTP请求NSHTTPURLResponse ......但你可能是明智的,以防万一有一个断言那里。

IF所述的StatusCode是成功的(即200),那么你NSData对象应包含的响应(无论其可以是)的数据。如果状态码指示错误,那么NSData可能包含来自服务器的错误的文本描述。

注意:我真的不建议tyring解析错误消息的NSData对象。这就是HTTP'statusCode'的用途!

8

UIWebView中不提供用于获取HTTP状态代码为它加载请求的任何功能。一种解决方法是使用UIWebViewDelegate方法拦截UIWebView的请求加载过程,并使用NSURLConnection来检测服务器如何响应该请求(如上所述)。然后你可以采取适合这种情况的适当行动。 This article详细解释了演示项目的解决方法。

而且你也不需要继续收到响应后装载请求。您只需取消连接 - (无效)连接:(NSURLConnection的*)连接didReceiveResponse:(NSURLResponse *)响应学习HTTP状态代码后方法。这样可以防止连接加载任何不必要的响应数据。然后可以再次加载的UIWebView请求或显示一个适当的错误消息,这取决于HTTP状态代码的用户,等等

Here is the article

and here is the demo project on github

2

在webViewDidFinishLoad:

if ([[(NSHTTPURLResponse*)[[NSURLCache sharedURLCache] cachedResponseForRequest:webView.request] valueForHTTPHeaderField:@"Status"] intValue] == 404){ 
} 

您可能会考虑将此解决方案放在其他更复杂的解决方案上,即使某些响应可能无法缓存。请注意,错误的URL通常会被具有默认配置的系统缓存。

16

我实现由拉杜Simionescu的回应启发:

- (void)webViewDidFinishLoad:(UIWebView *)webView { 
    NSCachedURLResponse *urlResponse = [[NSURLCache sharedURLCache] cachedResponseForRequest:webView.request]; 
    NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*) urlResponse.response; 
    NSInteger statusCode = httpResponse.statusCode; 
    if (statusCode > 399) { 
     NSError *error = [NSError errorWithDomain:@"HTTP Error" code:httpResponse.statusCode userInfo:@{@"response":httpResponse}]; 
     // Forward the error to webView:didFailLoadWithError: or other 
    } 
    else { 
     // No HTTP error 
    } 
} 

它管理HTTP客户端错误(4XX)和HTTP服务器错误(5XX)。

请注意,cachedResponseForRequest返回nil如果没有缓存响应,在这种情况下statusCode被分配为0,并且该响应被认为是无误的。

+0

谢谢我认为你的答案是最正确的方法。 – GeneCode 2016-11-22 08:49:47

+0

我把我的头发拉出来,直到我在真实的设备上进行测试,模拟器总是为我返回一个404。直到我在iPad上试用它时,它才真正起作用! – Plasma 2017-04-28 11:31:10

+1

但很多次'cachedResponseForRequest'返回'Nil' – Mrug 2017-06-15 07:15:41

-1

我用下面的代码为我解决

-(void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error{ 
NSLog(@"error :%@",error); 

NSString *strError = [NSString stringWithFormat:@"%@",error]; 

if ([strError rangeOfString:@"Code=-1005"].location == NSNotFound) { 
    NSLog(@"string does not contain Code=-1005"); 
} else 
    NSLog(@"string contains Code=-1005”); 

}

1

继承人是我的SWIFT 3版@AxelGuilmin响应:

func webViewDidFinishLoad(_ webView: UIWebView) { 

     guard let request = webView.request else { return } 

     let cachedUrlResponse = URLCache.shared.cachedResponse(for: request) 
     let httpUrlResponse = cachedUrlResponse?.response as? HTTPURLResponse 
     if let statusCode = httpUrlResponse?.statusCode { 
      if statusCode == 404 { 
       // Handling 404 response 
      } 
     } 
    }