当服务器在响应某个请求时,指明客户端应该向另一个URL发送新的请求,这时就会发送重定向。当发生重定向时NSURLSession
类会通知他的代理对象。为了能够处理重定向的问题,URL loading类必须要实现URLSession:task:willPerformHTTPRedirection:newRequest:completionHandler:代理方法,该代理会校验新的请求(request)和产生重定向的响应(response),还可以通过completionHandler返回一个新的请求对象。该代理可以做以下这些事儿:
- 允许重定向,并简单地返回提供的请求(request);
- 创建一个新的请求,指向不同的URL并返回该请求;
- 拒绝重定向,并通过返回nil从连接(比如一次TCP连接中的报文段数据)中接收任何现有的数据。
此外,该代理对象可以取消重定向和连接。而对于NSURLSession,它(代理)会发送cancle消息给任务对象。
如果处理请求的NSURLProtocol子类为了规范它的格式而更改了NSURLRequest
,NSURLSession
类的代理对象会接收URLSession:task:willPerformHTTPRedirection:newRequest:completionHandler:的消息。例如对“http://www.apple.com“URL最后加一个反斜杠,发生这种情况是因为相关的标准、规则、或者请求的版本被用于缓存管理。在这种特殊的情况下,响应(response)会给代理传递一个nil值,并且代理需要简单地把提供的请求(request)返回回去。
下面的例子展示了拒绝服务器的重定向:
/// Objective-C
- (void)URLSession:(NSURLSession *)session
task:(NSURLSessionTask *)task
willPerformHTTPRedirection:(NSHTTPURLResponse *)redirectResponse
newRequest:(NSURLRequest *)request
completionHandler:(void (^)(NSURLRequest *))completionHandler{
NSURLRequest *newRequest = request;
if (redirectResponse) {
newRequest = nil;
}
completionHandler(newRequest);
}
/// Swift
func urlSession(_ session: URLSession, task: URLSessionTask, willPerformHTTPRedirection response: HTTPURLResponse, newRequest request: URLRequest, completionHandler: @escaping (URLRequest?) -> Void) {
completionHandler(request)
}
提示
如果代理没有实现适当地重定向处理的代理方法,所有规范更改和服务器重定向都是允许的。