我使用 NSURLConnection 和委托向 URL 发送 HTTP GET 请求。请求使用 HTTP 302 重定向,执行新请求并检索数据。
问题是我不需要重定向的 HTTP 请求的正文,而是原始重定向响应的内容。
我已经实现了
- (NSURLRequest *)connection:(NSURLConnection *)connection willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)response
,它是通过redirectRepsonse调用的,但是connection:didReceiveData
在新的重定向请求返回之前不会被调用。
除了使用基于 CFNetwork 的方法之外,到目前为止我还没有找到任何解决方案。
更新: 我创建了一个包含问题的示例项目供您使用:https://github.com/snod/302RedirectTest
有什么想法吗?
来自-connection:willSendRequest:redirectResponse:
的
docs:
要接收重定向响应本身的正文,请返回 nil 以取消重定向。连接继续处理,最终根据需要向您的委托发送一个connectionDidFinishLoading 或connection:didFailLoadingWithError: 消息。
从您创建的测试项目来看,它看起来应该运行良好 ViewController.m 具有所需的所有方法,让我用清晰的示例进一步详细说明,这些示例已经在您的测试项目中部分实现。
//This method can be used to intercept the redirect
- (NSURLRequest *)connection:(NSURLConnection *)connection
willSendRequest:(NSURLRequest *)request
redirectResponse:(NSURLResponse *)redirectResponse {
if(redirectResponse != nil && redirectResponse) {
//Cast NSURLResponse to NSHTTPURLResponse
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) redirectResponse;
//Verify if statusCode == MOVED_TEMPORARILY (302)
if((long)[httpResponse statusCode] == 302){
NSDictionary* headers = [(NSHTTPURLResponse *)httpResponse allHeaderFields];
NSString *redirectLocation;
//Find redirect URL
for (NSString *header in headers) {
if([header isEqualToString:@"Location"]){
redirectLocation = headers[header];
break;
}
}
//return nil without following the redirect URL automatically
return nil;
} else {
//return without modifiying request
return request;
}
} else {
//return without modifiying request
return request;
}
//returnd without modifiying request
return request;
}
- (void)connection:(NSURLConnection *)aConnection
didReceiveResponse:(NSHTTPURLResponse *)aResponse
{
if ([aResponse statusCode] == 302) {
//do whatever you need to do with the response, the redirectURL is in the header "Location"
//for example show an UIAlertController to the user with a button which can then redirect to the URL
}
}