我对NSURLRequest(和伴奏)实现进行了久经考验,这对于GET和给定URL的POST非常有用。
但是,我现在想要移动URL的目标而不更改应用程序使用的URL,所以我打算通过我的DNS提供程序使用webhop重定向。
这适用于GET请求,但POST只是挂起......没有收到连接响应。
处理重定向的相关iOS方法是
-(NSURLRequest *)connection:(NSURLConnection *)connection
willSendRequest:(NSURLRequest *)request
redirectResponse:(NSURLResponse *)redirectResponse
根据Apple的(handling redirects)文档,
如果委托没有实现连接:willSendRequest:redirectResponse:,则允许所有规范更改和服务器重定向。
嗯,这不是我的经验,因为退出这种方法对我不起作用。请求只是挂起而没有响应。
Apple也建议实施willSendRequest(参见上面链接的Apple文档),这再次对我不起作用。我看到了调用,但结果请求只是挂起。我目前对willSendRequest的实现如下(见下文)。这是在重定向之后,但处理请求就好像它是一个GET而不是POST。
我认为问题在于重定向正在失去HTTP请求是POST的事实(可能会出现更多问题,例如承载请求Body也是如此?)。
我不确定我应该在这做什么。因此,任何有关如何正确处理接收重定向的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;
}
}
其他信息1
willSendRequest收到的HTTP代码是301 - '永久移动。
使用allHTTPHeaderFields提取标题字段,我看到他请求我最初提交的标题
HTTP header {
"Content-Length" = 244;
"Content-Type" = "application/json";
}
...并且复制/重定向的请求具有标题
Redirect HTTP header {
Accept = "*/*";
"Accept-Encoding" = "gzip, deflate";
"Accept-Language" = "en-us";
"Content-Type" = "application/json";
}
...看起来不像原始请求的副本,甚至是超集。
答案 0 :(得分:13)
保留原始请求,然后提供您自己的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应用程序进行POST时,此行为将更好地为您提供服务。
另见:
答案 1 :(得分:1)
用于处理3xx类状态代码的HTTP规范对GET和HEAD以外的协议非常不友好。它期望在重定向的中间步骤进行某种类型的用户交互,这导致了大量不兼容的客户端和服务器实现,以及Web服务开发人员的严重问题。
从iOS NSURL的角度来看,您可能要验证的一件事是原始POST正文包含在新的重定向请求中。
根据您对原始答案的评论以及对您问题的修改,您尝试访问的网址似乎已永久更新(301状态代码)。在这种情况下,您实际上可以通过使用新URL完全避免重定向。