Ios NSURLRequest:如何处理重定向的帖子?
我已经尝试并测试了NSURLRequest(和伴奏)实现的使用,它非常适合给定URL的GET和POST 但是,我现在想在不更改应用程序使用的URL的情况下移动URL的目标,因此我打算通过我的DNS提供商使用webhop重定向 这对GET请求很有效,但帖子只是挂起。。。没有收到连接响应 处理重定向的相关iOS方法是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 *)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应用程序发布时,这种行为将更好地为您服务
另见:
连接
获取原始请求,我不记得了。不过值得一看。但在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;
}
}