gpt4 book ai didi

ios - 找不到 webLink 时,UIWebView 不会转到 didFailLoadWithError?

转载 作者:技术小花猫 更新时间:2023-10-29 10:59:30 24 4
gpt4 key购买 nike

我使用 UIWebViewwebLink 加载网页,并使用 UIWebViewDelegate 来控制错误状态:

[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,而是转到 startLoaddidFinishLoad。找不到 webLink 的情况怎么办?请帮忙!

最佳答案

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

@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,则必须处理这些变幻莫测的问题。

因此,例如,我上面的代码正在搜索“http://www.applecom/pages”(其中我故意省略了“.com”的句点,应该 DNS 查找失败),但是对于我的 ISP Verizon 拦截了请求并通过 HTTP 连接重定向到他们自己的搜索页面,因此,我的应用程序正在报告:

2013-01-21 23:14:21.896 webtest[24198:c07] -[ViewController connection:didReceiveResponse:] you were redirected from http://www.applecom/pages to http://search.dnsassist.verizon.net/assist.php?url=www.applecom

您可能需要考虑哪些类型的重定向是可以接受的(例如,如果您转到“www.adobephotoshop.com”,它会将您重定向到“www.adobe.com”)以及哪些类型的重定向是 Not Acceptable (例如,如果我去“www.applecom”,它会将我重定向到“search.dnsassist.verizon.net”。我可能担心一个相当狭窄的问题(由于我的 ISP 而影响我),但这是值得考虑的事情。

关于ios - 找不到 webLink 时,UIWebView 不会转到 didFailLoadWithError?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14451012/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com