如何检测和处理UIWebView中的HTTP错误代码?

我想告诉用户何时收到HTTP错误404等。 我如何检测? 我已经试图实现

- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error 

但是当我收到404错误时不会调用它。

你可以在这里捕获URLRequest:

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

并将请求交给委托,并返回no。 然后在从NSURLConnection接收到的响应呼叫取消连接,如果一切正常(检查响应)在web视图中再次加载urlrequest。 再次加载urlrequest时,请确保在上述调用中返回YES。

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

我的实现受到Radu 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 } } 

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

请注意,如果响应没有被caching,则cachedResponseForRequest返回nil ,在这种情况下, statusCode被赋值为0,并且响应被认为是无误的。

UIWebView不提供任何获取它加载的请求的HTTP状态代码的function。 一种解决方法是使用UIWebViewDelegate方法拦截UIWebView的请求加载过程,并使用NSURLConnection来检测服务器如何响应该请求(如上所述)。 那么你可以采取适当的行动适合的情况。 本文将详细介绍演示项目的解决方法。

在收到回复后,您不需要继续加载请求。 学习HTTP状态码后,你可以直接取消– (void)连接中的连接:(NSURLConnection *)连接didReceiveResponse:(NSURLResponse *)响应方法。 这样可以防止连接加载任何不必要的响应数据。 然后,您可以再次在UIWebView中加载请求,或根据HTTP状态代码等向用户显示相应的错误消息。

这里是文章

这里是github上的演示项目

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

如果Web视图未能加载内容,则发送。

从HTTP 404上的维基百科文章:

404或Not Found错误消息是HTTP标准响应代码,指示客户端能够与服务器进行通信,但服务器找不到请求的内容。 404错误不应与“未find服务器”或类似的错误相混淆,在这种错误中根本无法连接到目标服务器。

很有可能你必须parsing一个你可以用NSURLConnection / NSURLRequest组合而不是Web视图获得的404响应文本。

最好的祝福,

NSURLConnection是你正在寻找的类,我不认为这可以直接在UIWebView中完成。

您可以使用同步方法

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

或者是asynchronous的。 这些设置比较困难,因为您必须将所有的数据添加到1个NSData中,但最终的结果是一样的。

无论您使用“同步”还是“asynchronous”方法:

如果你得到一个NSError *对象,那么就会出现COMMS错误。 正如其他答复中所述,这不是一个HTTP状态码,而是一个通信问题。

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

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

  NSInteger httpStatusCode = (NSHTTPURLResponse*)_responseInfo.statusCode; 

responseInfo应该总是一个NSHTTPURLResponse的HTTP请求…但你可能是聪明的有一个断言,以防万一。

如果statusCode是成功的(即200),那么你的NSData对象应该包含响应的数据(不pipe是什么)。 如果状态码指示错误,那么NSData可能包含来自服务器的错误的文本描述。

NB。 我真的不build议tyringparsingNSData对象的错误消息。 这就是HTTP'statusCode'的用途!

在webViewDidFinishLoad中:

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

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

下面是@AxelGuilmin响应的快速3版本:

 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 } } } 

我使用下面的代码为我的解决scheme

 -(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”); 

}