Ios NSURLRequest:如何处理重定向的帖子?

Ios NSURLRequest:如何处理重定向的帖子?,ios,redirect,nsurlrequest,Ios,Redirect,Nsurlrequest,我已经尝试并测试了NSURLRequest(和伴奏)实现的使用,它非常适合给定URL的GET和POST 但是,我现在想在不更改应用程序使用的URL的情况下移动URL的目标,因此我打算通过我的DNS提供商使用webhop重定向 这对GET请求很有效,但帖子只是挂起。。。没有收到连接响应 处理重定向的相关iOS方法是 -(NSURLRequest *)connection:(NSURLConnection *)connection willSendRequest:(NSURLRequest

我已经尝试并测试了NSURLRequest(和伴奏)实现的使用,它非常适合给定URL的GET和POST

但是,我现在想在不更改应用程序使用的URL的情况下移动URL的目标,因此我打算通过我的DNS提供商使用webhop重定向

这对GET请求很有效,但帖子只是挂起。。。没有收到连接响应

处理重定向的相关iOS方法是

-(NSURLRequest *)connection:(NSURLConnection *)connection
    willSendRequest:(NSURLRequest *)request
    redirectResponse:(NSURLResponse *)redirectResponse
根据苹果公司()的文档

如果委托未实现connection:willSendRequest:redirectResponse:,则允许所有规范更改和服务器重定向

嗯,这不是我的经验,因为忽略这个方法对我不起作用。请求只是挂起,没有响应

苹果还建议实施willSendRequest(见上面链接的苹果文档),这同样对我不起作用。我看到了调用,但生成的请求只是挂起

我目前对willSendRequest的实现如下(见下文)。这会遵循重定向,但会将请求当作GET而不是POST来处理

我认为问题在于重定向正在失去HTTP请求是POST的事实(可能还有更多的问题,比如将请求主体向前推进?)

我不确定我应该在这里做什么。因此,任何关于如何正确处理收到重定向的帖子的建议都将不胜感激。谢谢

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

    NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) redirectResponse;

    int statusCode = [httpResponse statusCode];


    NSLog (@"HTTP status %d", statusCode);

    // http statuscodes between 300 & 400 is a redirect ...
    if (httpResponse && statusCode >= 300 && statusCode < 400)
    {
        NSLog(@"willSendRequest (from %@ to %@)", redirectResponse.URL, request.URL);
    }

    if (redirectResponse)
    {
        NSMutableURLRequest *newRequest = [request mutableCopy]; // original request

       [newRequest setURL: [request URL]];

       NSLog (@"redirected");

       return newRequest;
    }
    else
    {
        NSLog (@"original");

       return request;
    }
}
…并且复制/重定向的请求具有标头

Redirect HTTP header {
  Accept = "*/*";
  "Accept-Encoding" = "gzip, deflate";
  "Accept-Language" = "en-us";
  "Content-Type" = "application/json";
}

…看起来不像原始请求的副本,甚至不像超集。

处理3xx类状态码的HTTP规范对GET和HEAD以外的协议非常不友好。它期望在重定向的中间步骤进行某种用户交互,这会导致大量不兼容的客户机和服务器实现,同时也会给web服务开发人员带来严重的麻烦

从iOS NSURL的角度来看,您可能需要验证的一件事是,新的重定向请求中包含了原始的POST正文


根据您对我原始答案的评论以及对您问题的编辑,您试图访问的URL似乎已被永久更新(301状态代码)。在这种情况下,您可以使用新的URL完全避免重定向。

保留您的原始请求,然后提供您自己的
willSendRequest:redirectResponse:
以自定义该请求,而不是使用Apple提供给您的请求

- (NSURLRequest *)connection: (NSURLConnection *)connection
             willSendRequest: (NSURLRequest *)request
            redirectResponse: (NSURLResponse *)redirectResponse;
{
    if (redirectResponse) {
        // The request you initialized the connection with should be kept as
        // _originalRequest.
        // Instead of trying to merge the pieces of _originalRequest into Cocoa
        // touch's proposed redirect request, we make a mutable copy of the
        // original request, change the URL to match that of the proposed
        // request, and return it as the request to use.
        //
        NSMutableURLRequest *r = [_originalRequest mutableCopy];
        [r setURL: [request URL]];
        return r;
    } else {
        return request;
    }
}
这样做,您就显式地忽略了HTTP规范的某些方面:重定向通常应该变成GET请求(取决于HTTP状态代码)。但在实践中,当从iOS应用程序发布时,这种行为将更好地为您服务

另见:


谢谢您的回复,但恐怕不是这样。实际上,“request”保存重定向的URL(正如我之前的NSLog所确认的)。我也觉得这是违反直觉的,但事实就是这样。那就奇怪了。如果是这样的话,您不应该克隆并(重新)发送请求。你坚持使用NSURL类吗?我想我坚持使用NSURL,有更好的选择吗?你可以试试MKNetworkingKit。同时,你能运行你的代码并添加到问题中,你得到的确切HTTP状态代码吗?谢谢你回到这里并尝试提供帮助。我在原来的问题下面添加了一些额外的信息。嗯,我想你可能是对的。我有很多重叠的请求,所以这需要一些排序(和测试),但我认为这是一条路要走。谢谢Steven。是的,快速测试表明此解决方案有效。谢谢大家!您可能可以从
连接
获取原始请求,我不记得了。不过值得一看。但在iOS 4.3之后,此方法被指定为已弃用。那么可以实施吗?(我确实尝试过这个解决方案,它很有效!)
originalRequest
应该重命名为
request
,以便通过复制和粘贴来使用此示例。苹果也提供了一个很好的解释
- (NSURLRequest *)connection: (NSURLConnection *)connection
             willSendRequest: (NSURLRequest *)request
            redirectResponse: (NSURLResponse *)redirectResponse;
{
    if (redirectResponse) {
        // The request you initialized the connection with should be kept as
        // _originalRequest.
        // Instead of trying to merge the pieces of _originalRequest into Cocoa
        // touch's proposed redirect request, we make a mutable copy of the
        // original request, change the URL to match that of the proposed
        // request, and return it as the request to use.
        //
        NSMutableURLRequest *r = [_originalRequest mutableCopy];
        [r setURL: [request URL]];
        return r;
    } else {
        return request;
    }
}