iOS HTTP Post重定向处理程序无法正常工作

时间:2014-07-30 18:08:35

标签: ios http redirect nsurlconnection

我是iOS开发的新手。我只是试图向服务器发送一个post请求,但遇到了带有服务器重定向的here提到的问题。我使用了答案中提到的事件处理程序,但事情仍然无法正常工作。

这是我的.m代码:

@interface ViewController ()

@end

@implementation ViewController


#pragma mark NSURLConnection Delegate Methods


//CALL BACK METHODS

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
    NSLog(@"    didReceiveResponse");
    // A response has been received, this is where we initialize the instance var you created
    // so that we can append data to it in the didReceiveData method
    // Furthermore, this method is called each time there is a redirect so reinitializing it
    // also serves to clear it


    //initialize response
    _responseData = [[NSMutableData alloc] init];

}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
    NSLog(@"   didReceiveData");
    // Append the new data to the instance variable you declared
    [_responseData appendData:data];



}

- (NSCachedURLResponse *)connection:(NSURLConnection *)connection
                  willCacheResponse:(NSCachedURLResponse*)cachedResponse {
    // Return nil to indicate not necessary to store a cached response for this connection
    return nil;
}




- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
    NSLog(@"   connectionDidFinishLoading ");

    // The request is complete and data has been received
    // You can parse the stuff in your instance variable now

    NSString *dataReceived= [[NSString alloc] initWithData:_responseData encoding:NSUTF8StringEncoding];
    NSLog(@"    async response data: %@", dataReceived);



}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
    NSLog(@"   didFailWithError");

    // The request has failed for some reason!
    // Check the error var
}



- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.


    NSString *post = [NSString stringWithFormat:@"&j_username=%@&j_password=%@",@"usrname",@"pw"];
    NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];

    NSString *postLength = [NSString stringWithFormat:@"%d", [postData length]];

    request = [[NSMutableURLRequest alloc] init];
    request.HTTPMethod= @"POST";
    //parameters
    [request setURL:[NSURL URLWithString:@"url"]];
    [request setValue:postLength forHTTPHeaderField:@"Content-Length"];
    [request setValue:@"application/x-www-form-urlencoded;charset=UTF-8" forHTTPHeaderField:@"Content-Type"];
    [request setValue:@"XMLHttpRequest" forHTTPHeaderField:@"X-Requested-With"];
    [request setHTTPBody:postData];




    // Send a synchronous request
    if (0) {
        NSURLResponse * response = nil;
        NSError * error = nil;
        NSData * data = [NSURLConnection sendSynchronousRequest:request
                                              returningResponse:&response
                                                          error:&error];
        NSLog(@"  Synchronous request done");
        if (error == nil)
        {
            // Parse data here
            NSLog(@"     Synchronous response has no error");
            NSLog(@"    Synchronous Reply: %@", response);
        }
    }
    else {
        // Send Asynchronous request
        //NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self];
        [NSURLConnection connectionWithRequest:request delegate:self];
        NSLog(@"  Asynchronous request sent");
    }



}

- (NSURLRequest *)connection: (NSURLConnection *)connection
             willSendRequest: (NSURLRequest *)inRequest
            redirectResponse: (NSURLResponse *)redirectResponse;
{
    if (redirectResponse) {
        // we don't use the new request built for us, except for the URL
        NSURL *newURL = [request URL];
        NSString *redirectURL= [newURL absoluteString];
        NSLog(@"Redirect URL: ");
        NSLog(redirectURL);
        // Previously, store the original request in _originalRequest.
        // We rely on that here!
        NSMutableURLRequest *newRequest = [request mutableCopy];
        [newRequest setURL: newURL];
        NSLog(@"redirect occur");
        return newRequest;
    } else {
        NSLog(@"no redirect");
        return inRequest;
    }
}

@end

没有处理程序,请求会很好(只是没有附加主体);但是使用处理程序,再次检测重定向b / c重定向的URL与原始URL相同。最终请求因重定向过多而死亡。我认为这可能是一个服务器端问题,但我在编码中做了什么错误导致了这个问题?

1 个答案:

答案 0 :(得分:1)

基本上问题是redirectResponse的url不是你被重定向到的地方;它仍然是你在原始post方法中设置的那个。这就是为什么你被一次又一次地重定向到同一个网址。

所以你要做的就是拦截你被重定向到响应头中的实际url。在执行初始发布请求后,您应该获得如下响应标头:

HTTP/1.1 302 Found
Location: http://www.iana.org/domains/example/

其中“位置”表示您被重定向到的位置。所以得到这样的网址:

NSDictionary* headers = [(NSHTTPURLResponse *)redirectResponse allHeaderFields];
NSString newUrl=headers[@"Location"];

在newRequest中使用newUrl,那么你应该好好去。