服务器要求在所有请求当中添加Header进行验证,
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType方法拦截不到相关的css,js文件请求。这里要用NSURLProtocol,这是一个挺牛逼的类,它是一个抽象类,不能去实例化它,只能子类化NSURLProtocol
,每次在对一个 URL 进行请求的时候 URL Loading System
都会向 已经注册的 Protocol
询问是否可以处理该请求。这里就看出他的作用来了. 比如: 拦截UIWebView的请求,忽略请求,重定向... ...
直接贴代码:
- #import <Foundation/Foundation.h>
- @interface NSURLProtocolCustom : NSURLProtocol
- @end
- #import "NSURLProtocolCustom.h"
- static NSString* const FilteredKey = @"FilteredKey";
- @interface NSURLProtocolCustom ()<NSURLSessionDataDelegate>
- @property (atomic, strong, readwrite) NSURLSessionDataTask *task;
- @property (nonatomic, strong ) NSURLSession *session;
- @end
- @implementation NSURLProtocolCustom
- + (BOOL)canInitWithRequest:(NSURLRequest *)request
- {
- //只处理http和https请求
- NSString *scheme = [[request URL] scheme];
- if ( ([scheme caseInsensitiveCompare:@"http"] == NSOrderedSame ||
- [scheme caseInsensitiveCompare:@"https"] == NSOrderedSame))
- {
- //看看是否已经处理过了,防止无限循环
- if ([NSURLProtocol propertyForKey:FilteredKey inRequest:request]) {
- return NO;
- }
- return YES;
- }
- return NO;
- }
- + (NSURLRequest *) canonicalRequestForRequest:(NSURLRequest *)request {
- /** 可以在此处添加头等信息 */
- NSMutableURLRequest *mutableReqeust = [request mutableCopy];
- [mutableReqeust setValue:@"abc" forHTTPHeaderField:@"Authorization"];
- return mutableReqeust;
- }
- - (void)startLoading
- {
- NSMutableURLRequest *mutableReqeust = [[self request] mutableCopy];
- //打标签,防止无限循环
- [NSURLProtocol setProperty:@YES forKey:FilteredKey inRequest:mutableReqeust];
- NSURLSessionConfiguration *configure = [NSURLSessionConfiguration defaultSessionConfiguration];
- NSOperationQueue *queue = [[NSOperationQueue alloc] init];
- self.session = [NSURLSession sessionWithConfiguration:configure delegate:self delegateQueue:queue];
- self.task = [self.session dataTaskWithRequest:mutableReqeust];
- [self.task resume];
- }
- - (void)stopLoading
- {
- [self.session invalidateAndCancel];
- self.session = nil;
- }
- - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
- {
- if (error != nil) {
- [self.client URLProtocol:self didFailWithError:error];
- }else
- {
- [self.client URLProtocolDidFinishLoading:self];
- }
- }
- - (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask
- didReceiveResponse:(NSURLResponse *)response
- completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler
- {
- [self.client URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageNotAllowed];
- completionHandler(NSURLSessionResponseAllow);
- }
- - (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data
- {
- [self.client URLProtocol:self didLoadData:data];
- }
- - (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask willCacheResponse:(NSCachedURLResponse *)proposedResponse completionHandler:(void (^)(NSCachedURLResponse * _Nullable))completionHandler
- {
- completionHandler(proposedResponse);
- }
- //TODO: 重定向
- - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task willPerformHTTPRedirection:(NSHTTPURLResponse *)response newRequest:(NSURLRequest *)newRequest completionHandler:(void (^)(NSURLRequest *))completionHandler
- {
- NSMutableURLRequest * redirectRequest;
- redirectRequest = [newRequest mutableCopy];
- [[self class] removePropertyForKey:FilteredKey inRequest:redirectRequest];
- [[self client] URLProtocol:self wasRedirectedToRequest:redirectRequest redirectResponse:response];
- [self.task cancel];
- [[self client] URLProtocol:self didFailWithError:[NSError errorWithDomain:NSCocoaErrorDomain code:NSUserCancelledError userInfo:nil]];
- }
- - (instancetype)initWithRequest:(NSURLRequest *)request cachedResponse:(NSCachedURLResponse *)cachedResponse client:(id<NSURLProtocolClient>)client
- {
- self = [super initWithRequest:request cachedResponse:cachedResponse client:client];
- if (self) {
- // Some stuff
- }
- return self;
- }
- @end
最后在用到的webview类里进行注册和注销即可
- - (void)viewDidLoad {
- [super viewDidLoad];
- [NSURLProtocol registerClass:[NSURLProtocolCustom class]];
- }
- -(void)viewWillDisappear:(BOOL)animated{
- [super viewWillDisappear:animated];
- [NSURLProtocol unregisterClass:[NSURLProtocolCustom class]];
- }
联系客服