找不到webLink时,UIWebView没有转到didFailLoadWithError? [英] UIWebView not go to didFailLoadWithError when webLink not found?

查看:129
本文介绍了找不到webLink时,UIWebView没有转到didFailLoadWithError?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用 UIWebView webLink UIWebViewDelegate 控制错误状态:

I use UIWebView to load web from a webLink and UIWebViewDelegate to control error state:

[webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:webLink]]];


- (void)webViewDidStartLoad:(UIWebView *)webView{
    NSLog(@"START LOAD");

}

- (void)webViewDidFinishLoad:(UIWebView *)webView{
    NSLog(@"FINISH LOAD");
}

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

但是当 webLink 没找到,它不会去 didFailLoadWithError ,它会转到 startLoad didFinishLoad 。如何找到 webLink 未找到的情况?
请帮助!

But when webLink not found, it NOT go to didFailLoadWithError, it go to startLoad and didFinishLoad. How to go the situation when webLink not found? Please help!

推荐答案

不幸的是,404(或类似代码)不被<$ c $视为错误c> UIWebView ,因为收到了HTML响应。更糟糕的是, UIWebView 不会捕获我们的响应代码,因此您必须通过 NSURLConnection 手动执行此操作。这是处理它的一种方法:

Unfortunately, 404 (or similar codes) aren't considered errors by UIWebView, because a HTML response was received. Worse, the UIWebView doesn't capture response codes for us, so you have to do that manually, via NSURLConnection. Here's one way to deal with it:

@interface ViewController () <UIWebViewDelegate, NSURLConnectionDataDelegate>

@property (nonatomic) BOOL validatedRequest;
@property (nonatomic, strong) NSURL *originalUrl;

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    // since `shouldStartLoadWithRequest` only validates when a user clicks on a link, we'll bypass that
    // here and go right to the `NSURLConnection`, which will validate the request, and if good, it will
    // load the web view for us.

    self.originalUrl = [NSURL URLWithString:@"http://www.stackoverflow.com"];
    NSURLRequest *request = [NSURLRequest requestWithURL:self.originalUrl];
    [NSURLConnection connectionWithRequest:request delegate:self];
}

#pragma mark - UIWebViewDelegate

// you will see this called for 404 errors

- (void)webViewDidFinishLoad:(UIWebView *)webView
{
    self.validatedRequest = NO; // reset this for the next link the user clicks on
}

// you will not see this called for 404 errors

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

// this is where you could, intercept HTML requests and route them through
// NSURLConnection, to see if the server responds successfully.

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
    // we're only validating links we click on; if we validated that successfully, though, let's just go open it
    // nb: we're only validating links we click on because some sites initiate additional html requests of
    // their own, and don't want to get involved in mediating each and every server request; we're only
    // going to concern ourselves with those links the user clicks on.

    if (self.validatedRequest || navigationType != UIWebViewNavigationTypeLinkClicked)
        return YES;

    // if user clicked on a link and we haven't validated it yet, let's do so

    self.originalUrl = request.URL;

    [NSURLConnection connectionWithRequest:request delegate:self];

    // and if we're validating, don't bother to have the web view load it yet ...
    // the `didReceiveResponse` will do that for us once the connection has been validated

    return NO;
}

#pragma mark - NSURLConnectionDataDelegate method

// This code inspired by http://www.ardalahmet.com/2011/08/18/how-to-detect-and-handle-http-status-codes-in-uiwebviews/
// Given that some ISPs do redirects that one might otherwise prefer to see handled as errors, I'm also checking
// to see if the original URL's host matches the response's URL. This logic may be too restrictive (some valid redirects
// will be rejected, such as www.adobephotoshop.com which redirects you to www.adobe.com), but does capture the ISP
// redirect problem I am concerned about.

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{     
    NSString *originalUrlHostName = self.originalUrl.host;
    NSString *responseUrlHostName = response.URL.host;

    NSRange originalInResponse = [responseUrlHostName rangeOfString:originalUrlHostName]; // handle where we went to "apple.com" and got redirected to "www.apple.com"
    NSRange responseInOriginal = [originalUrlHostName rangeOfString:responseUrlHostName]; // handle where we went to "www.stackoverflow.com" and got redirected to "stackoverflow.com"

    if (originalInResponse.location == NSNotFound && responseInOriginal.location == NSNotFound) {
        NSLog(@"%s you were redirected from %@ to %@", __FUNCTION__, self.originalUrl.absoluteString, response.URL.absoluteString);
    }

    if ([response isKindOfClass:[NSHTTPURLResponse class]]) {
        NSInteger statusCode = [(NSHTTPURLResponse *)response statusCode];

        if (statusCode < 200 || statusCode >= 300) {
            NSLog(@"%s request to %@ failed with statusCode=%d", __FUNCTION__, response.URL.absoluteString, statusCode);
        } else {
            self.validatedRequest = YES;

            [self.webView loadRequest:connection.originalRequest];
        }
    }

    [connection cancel];
}

@end

注意,在我的实施中,我不仅要检查状态代码,还要检查重定向(您可能想要也可能不想做)。我之所以这样做,是因为某些ISP拦截了HTTP请求,如果找不到目标站点,请将您重定向到他们自己的搜索网页(我认为我的ISP正在查看我搜索的每个网站,这有点令人毛骨悚然)。如果你正在处理通过wifi连接的iPhone,你必须处理这些变幻莫测的问题。

Note, in my implementation, I'm not only checking for status codes, but I'm also checking for redirects (which you may or may not want to do). I do this because some ISP's intercept HTTP requests, and if the destination site is not found, redirect you to their own search web page (which I think is a bit creepy knowing that my ISP is checking out every web site I search for). And if you're dealing with iPhones that are connecting via wifi, you have to deal with these vagaries.

因此,例如,我上面的代码正在搜索 http ://www.applecom/pages (其中我故意省略了.com的时期,其中应该无法进行DNS查找),但我的ISP,Verizon,截获请求并通过HTTP连接重定向到他们自己的搜索页面,因此,我的应用报告:

So, for example, my code above is searching for "http://www.applecom/pages" (in which I deliberately omitted the period of ".com", which should fail a DNS lookup), but for which my ISP, Verizon, intercepted the request and redirected by HTTP connection to their own search page and as such, my app is reporting:


2013-01-21 23 :14:21.896 webtest [24198:c07] - [ViewController连接:didReceiveResponse:]您是从 http:// www。重定向的。 applecom / pages http://search.dnsassist。 verizon.net/assist.php?url=www.applecom

您可能想要考虑哪种重定向是可以接受的(例如,如果你去www.adobephotoshop.com并将它重定向到w ww.adobe.com)以及不是什么类型(例如,如果我去www.applecom并将其重定向到search.dnsassist.verizon.net。我可能会担心一个相当狭窄的问题(因为我的ISP而影响了我),但这是需要考虑的事情。

You might want to think about what sort of redirects are acceptable (e.g., if you go to "www.adobephotoshop.com" and it redirects you to "www.adobe.com") and what sorts aren't (e.g., if I go to "www.applecom" and it redirects me to "search.dnsassist.verizon.net". I may be worrying about a fairly narrow problem (which affects me because of my ISP), but it's something to contemplate.

这篇关于找不到webLink时,UIWebView没有转到didFailLoadWithError?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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