处理与NSURLConnection的正确重定向(Handling redirects correc

2019-07-18 13:13发布

对于这个目的,我要假装原始URL是http://host/form和新的URL是https://host/form 。 (请注意,我舰在此之前,这两个URL都将是安全的。但是,非安全到安全似乎是一个方便的重定向测试这个上。)

我访问使用Web API NSURLConnection重定向我。 基本上,我想利用我刚刚提交的一切http://hostaform ,并重新提交https://host/form 。 我想这是默认的行为,但它看起来就像人体在重定向丢失。

因此,我认为我需要处理的connection:willSendRequest:redirectResponse:该事件NSURLConnection的委托和重新附加体。 问题是这样的消息似乎远远未公开。 唯一的信息,我可以找到这个方法是NSURLConnection的类参考 ,这是不是非常有帮助。 除此之外,它包括这样的:

导致重定向的URL响应。 其中该方法不被作为涉及重定向处理委托的结果发送可以是在箱子为零。

我不知道这意味着什么。 结合初始willSendRequest:调用,我认为这是意味着willSendRequest:正在即使是我的初始请求发送重定向响应之前。 那是对的吗?

所以,我已经添加代码到我的委托,以保持身体的额外的时间,并增加这种willSendRequest:处理器:

- (NSURLRequest *)connection: (NSURLConnection *)inConnection
             willSendRequest: (NSURLRequest *)inRequest
            redirectResponse: (NSURLResponse *)inRedirectResponse;
{
    if (inRedirectResponse) {
        NSMutableURLRequest *r = [[inRequest mutableCopy] autorelease];
        [r setURL: [inRedirectResponse URL]];
        [r setHTTPBody: body];
        return r;
    } else {
        return inRequest;
    }
}

它不工作。 但我甚至不知道这是正确的做法。 这似乎过分的hackish给我。 我应该怎么做? 这是记录任何地方? 我什么也没有发现苹果的文档或使用谷歌迄今为止有用。

(这是在iPhone上,但似乎没有要在这些类太大的差别。)

Answer 1:

有在一份RFC 2616第10.3.2有关此行为:

注意:当接收到一个301状态代码后自动重定向POST请求,一些现有的HTTP / 1.0用户代理将错误地把它变成一个GET请求。

所以这个行为似乎是不规范的,但历史。 这GET请求不是POST ,它会缺少有效载荷。

有趣的是,这也是在同一节:

如果响应于比​​GET或HEAD其他的请求被接收到301个状态代码,用户代理不能自动重定向请求,除非它可以由用户来确认,因为这可能会改变已发出请求下的条件。

这是相当清晰,似乎表明我们不可能解决这个问题,但我认为这忽视了我们自己的Web服务客户端为我们挑选服务(或控制)的目的可能是最不坏的选择。

那么,我们如何解决这个问题?

取而代之的是的willSendResponse:在原来的问题,我使用的是这样的:

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

这里的想法是,与其克隆了新的要求,并试图为一个可可触摸送我去塑造它一样,我创建原始请求的克隆,只需更改URL匹配可可触摸寄给我的请求。 该原始请求仍然是一个POST附带的有效负载。

如果你控制的服务器,这是值得一读RFC 2616,第10.3节的全部,看看是否有更好的代码,你可以使用(同时检查,当然,是iOS的处理更好的代码,因为它应该)。

你也可以将重定向请求的可变副本,并与原请求的HTTP方法取代它的HTTP方法。 同样的基本原则,尽管这将有利于在新的要求,而不是老让事情。 在某些情况下可能会更好地工作,但我没有测试过这呢。



Answer 2:

您应该检查服务器发送HTTP响应状态代码,以确定是否要发送GET或重复自检。 为303(或302),发送的GET请求。 对于307,重复自检。



Answer 3:

我有同样的问题重定向。 感谢AJSoaks! 我想,他建议,问题得到解决。

所以,我试图通过发布POST方法的用户名和密码,我看到服务器重定向我的要求。 作为AJSoaks说,在情况下,如果有302错误,您使用GET方法,而不是以前的职位应重复请求,但这个时候。

...在某些时候你有下面几行:......可能里面,如果你的IBAction为(按下按钮)方法或任何你想要...

NSMutableString *postString = [[NSMutableString alloc] init];

[postString appendString:@"username=YourUsername&password=YourPassword"];

    //the original URL (https means that it supports SSL protocol)
    //it doesn't change anything, don't worry about it
NSURL *URL = [NSURL URLWithString:@"https://loginWebpageURL"];

NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:URL];

[request setHTTPMethod:@"POST"];    
[request setValue:[NSString stringWithFormat:@"%d", [postString length]] forHTTPHeaderField:@"Content-length"];
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-type"];
[request setHTTPBody:[postString dataUsingEncoding:NSUTF8StringEncoding]];

[NSURLConnection connectionWithRequest:request delegate:self];

[postString release];
[request release];

比你还应该实现重定向NSURLConnection的委托方法,具有以下特征:

- (NSURLRequest *)connection:(NSURLConnection *)connection
            willSendRequest:(NSURLRequest *)request
           redirectResponse:(NSURLResponse *)redirectResponse

这个方法里面,万一如果你有服务器的错误302或303,你应该执行类似的代码波纹管的东西,只需复制,你看到并使用新的URL(重定向)替换它的代码。 新的URL可以在浏览器中看到,或者如果你希望它是非常有用的,也是今后,使用Firebug(Firefox插件)或Safari网络督察检查它。 如果你使用Firebug的所有信息,你可以在“网络”选项找到:

if (redirectResponse) {

    NSLog(@"REDIRECT");
    NSMutableURLRequest *requestTmp = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:@"https://areaclienti.tre.it/selfcare/areaclienti133/4552_infoCosti_ITA_HTML.xsl"]];

    return [requestTmp autorelease];
}

//return original request in case thay there is no redirecting...
else return request;


Answer 4:

NSURLConnection的不加originalRequest头到重定向请求在“willSendRequest:(*的NSURLRequest)inRequest”。

您可以通过添加“originalRequest.headers”到重定向请求解决此问题。



文章来源: Handling redirects correctly with NSURLConnection