域名被拦截(重定向)
移动网络服务运营商或其他网络服务机构,由于某些不知明原因,会禁掉一些域名访问,如果你的域名正好在其中,那恭喜,你的域名访问被其封锁了。你的所有请求就只能呵呵了,此时四十五度角仰望星空。心里有一百万个为什么…但是天无绝人之路,我们可以通过域名重定向去解决。是不是瞬间开心起来了。以下是我的解决方法:
一. 自定义协议类(AFURLProtocol)继承NSURLProtocol
(1)、 实现+ (BOOL)canInitWithRequest:(NSURLRequest *)request方法。此方法可以处理给定的请求,YES是需要处理,NO不需要处理。
+ (BOOL)canInitWithRequest:(NSURLRequest *)request {
//防止无限循环
if ([NSURLProtocol propertyForKey:URLProtocolHandledKey inRequest:request]) {
return NO;
}
if (![UCDomainManager hasNeedDomainRedirect]) {
return NO;
}
NSString *scheme = [[request URL] scheme];
if ([scheme caseInsensitiveCompare:@"http"] == NSOrderedSame || [scheme caseInsensitiveCompare:@"https"] == NSOrderedSame) {
if ([request.URL.host isEqualToString:[UCDomainManager currentDomain]]) {
return YES;
}
}
return NO;
}
(2)、实现+ (BOOL)requestIsCacheEquivalent:(NSURLRequest *)a toRequest:(NSURLRequest *)b方法。出于缓存目的,请求被认为是等效的当且仅当它们将由相同协议处理且协议在执行后声明它们等效, 实施特定的检查。
+ (BOOL)requestIsCacheEquivalent:(NSURLRequest *)a toRequest:(NSURLRequest *)b {
return [super requestIsCacheEquivalent:a toRequest:b];
}
(3)、实现- (instancetype)initWithRequest:(NSURLRequest *)request cachedResponse:(nullable NSCachedURLResponse *)cachedResponse client:(nullable id )client方法。初始化给定的NSURLProtocol请求, 缓存的响应和客户端。
- (instancetype)initWithRequest:(NSURLRequest *)request cachedResponse:(NSCachedURLResponse *)cachedResponse client:(id<NSURLProtocolClient>)client {
return [super initWithRequest:request cachedResponse:cachedResponse client:client];
}
(4)、实现+ (NSURLRequest *)canonicalRequestForRequest:(NSURLRequest *)request方法。拦截request请求进行处理(修改host、添加cookie)
+ (NSURLRequest *)canonicalRequestForRequest:(NSURLRequest *)request {
NSMutableURLRequest *mutableRequest = [request mutableCopy];
mutableRequest = [self redirectHostInRequest:mutableRequest];
return [mutableRequest copy];
}
+ (NSMutableURLRequest *)redirectHostInRequest:(NSMutableURLRequest *)request {
if (request.URL.host.length == 0) {
return request;
}
NSString *originUrlString = [request.URL absoluteString];
NSString *originHostString = [request.URL host];
NSRange hostRange = [originUrlString rangeOfString:originHostString];
if (hostRange.location == NSNotFound) {
return request;
}
NSString *httpDnsIP = [UCDomainManager getRedirectIP];
//替换请求头中url host
NSString *urlString = [originUrlString stringByReplacingCharactersInRange:hostRange withString:httpDnsIP];
NSURL *url = [NSURL URLWithString:urlString];
request.URL = url;
//注意:若包头的host(key-value中的host)本身就是一个IP,则需要将这个IP替换成域名(该域名需要从referer中获取)