iOS实现HTTP拦截器
需求背景
目前项目中有一个模块使用Cordova实现Hybrid方案,由于该模块访问后端的时候是需要验证用户信息的,但是用户的登录的又是在原生端,为了使该模块和原生共享一个token,由此产生了这样一个需求:实现一个HTTP拦截器,为该模块的接口请求动态注入token。
NSURLProtocol
官方说明:NSURLProtocol对象用于处理特定URL协议的数据加载,NSURLProtocol类本身是一个抽象类,你需要为自己的应用创建它的子类。你不用直接实例化NSURLProtocol类的子类,你只需要在应用启动的时候调用 NSURLProtocol的
registerClass:
类方法就可以了。
示例代码
static NSString * const CLURLProtocolHandleKey = @"CLURLProtocolHandleKey";
@interface CLURLProtocol ()
@property (nonatomic, strong) NSMutableData *responseData;
@property (nonatomic, strong) NSURLConnection *connection;
@end
@implementation CLURLProtocol
+ (BOOL)canInitWithRequest:(NSURLRequest *)request {
//这里需要填写自己的判断逻辑,因为现实情况是满足某些条件的请求才去处理。
BOOL condition = .....;
if (condition && ![NSURLProtocol propertyForKey: CLURLProtocolHandleKey inRequest:request]) {
return YES;
}
return NO;
}
+ (NSURLRequest *)canonicalRequestForRequest:(NSURLRequest *)request {
NSMutableURLRequest *mutableRequest = [request mutableCopy];
//这里实现了URL的重定向,看具体的需求,
NSURL *host = [NSURL URLWithString:@"your domain"];
if (host) {
mutableRequest.URL = [NSURL URLWithString:[NSString stringWithFormat:@"%@%@", host.absoluteString, [request.URL.absoluteString stringByReplacingOccurrencesOfString:@"file://" withString:@""]]];
[mutableRequest setValue:yourToken forHTTPHeaderField:@"token"];
return mutableRequest;
} else {
return request;
}
}
- (void)startLoading {
NSMutableURLRequest *mutableReqeust = [[self request] mutableCopy];
//标示改request已经处理过了,防止无限循环
[NSURLProtocol setProperty:@YES forKey:CLURLProtocolHandleKey inRequest:mutableReqeust];
self.connection = [NSURLConnection connectionWithRequest:mutableReqeust delegate:self];
}
- (void)stopLoading {
[self.connection cancel];
}
#pragma mark- NSURLConnectionDelegate
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
[self.client URLProtocol:self didFailWithError:error];
}
#pragma mark - NSURLConnectionDataDelegate
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
self.responseData = [[NSMutableData alloc] init];
[self.client URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageNotAllowed];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[self.responseData appendData:data];
[self.client URLProtocol:self didLoadData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
[self.client URLProtocolDidFinishLoading:self];
}
Comments