gpt4 book ai didi

iphone - 使用 NSURLConnection 正确处理重定向

转载 作者:行者123 更新时间:2023-12-03 16:01:20 27 4
gpt4 key购买 nike

出于此目的,我将假设原始网址是 http://host/form新的网址是 https://host/form 。 (请注意,在我发布此内容之前,两个 URL 都将是安全的。但是,非安全到安全似乎是一个方便的重定向来测试这一点。)

我正在使用 NSURLConnection 访问 Web API这重定向了我。基本上,我想把我刚刚提交给http://hostaform的所有内容都拿走。并重新提交至https://host/form 。我认为这将是默认行为,但看起来正文在重定向中丢失了。

所以我想我需要处理 connection:willSendRequest:redirectResponse:事件NSURLConnection的委托(delegate)并重新附加主体。问题是这条消息的记录似乎严重不足。我能找到的关于此方法的唯一信息是 NSURLConnection Class Reference,这不是很有帮助。除其他外,它包括:

redirectResponse: The URL response that caused the redirect. May be nil in cases where this method is not being sent as a result of involving the delegate in redirect processing.

我不确定这意味着什么。结合初始willSendRequest:调用,我想这就是手段willSendRequest:即使是我的初始请求,在重定向响应之前也会发送。这是正确的吗?

因此,我向我的委托(delegate)添加了代码以保留主体额外的时间,并添加了此 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;
}
}

这不起作用。但我什至不确定这是否是正确的方法。对我来说这似乎过于黑客化了。我应该做什么?这有记录在任何地方吗?到目前为止,我在 Apple 文档或使用 Google 时没有发现任何有用的信息。

(这是在 iPhone 上,尽管这些类似乎没有太大区别。)

最佳答案

section 10.3.2 of RFC 2616中有一条注释关于此行为:

Note: When automatically redirecting a POST request afterreceiving a 301 status code, some existing HTTP/1.0 user agentswill erroneously change it into a GET request.

所以这种行为似乎是不标准的,但却是历史性的。该 GET 请求不是 POST,并且它将丢失有效负载。

有趣的是,这也在同一部分:

If the 301 status code is received in response to a request otherthan GET or HEAD, the user agent MUST NOT automatically redirect therequest unless it can be confirmed by the user, since this mightchange the conditions under which the request was issued.

这非常清楚,似乎表明我们无法解决这个问题,但我认为为了我们自己的网络服务客户端为我们选择(或控制)的服务而忽略这一点可能是最不坏的选择。

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

我使用的是这个:而不是原始问题中的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;
}
}

这里的想法是,我不是克隆新请求并尝试将其塑造为与 Cocoa Touch 发送给我的请求相同的形式,而是创建原始请求的克隆并仅更改 URL 以匹配 Cocoa Touch 发送给我的请求。原始请求仍然是附加了有效负载的 POST

如果你控制了服务器,那么值得一读RFC 2616, section 10.3完整地查看是否有更好的代码可以使用(当然,同时检查 iOS 是否按应有的方式处理更好的代码)。

您还可以制作重定向请求的可变副本,并将其 HTTP 方法替换为原始请求的 HTTP 方法。相同的一般原则,尽管这有利于让事情不受新请求的影响,而不是旧的请求。在某些情况下,这可能会更好,但我还没有测试过。

关于iphone - 使用 NSURLConnection 正确处理重定向,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1446509/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com