POST 请求未考虑 NSMutableURLRequest 超时间隔
Posted
技术标签:
【中文标题】POST 请求未考虑 NSMutableURLRequest 超时间隔【英文标题】:NSMutableURLRequest timeout interval not taken into consideration for POST requests 【发布时间】:2009-09-23 14:33:50 【问题描述】:我有以下问题。在使用HTTP
方法POST
的NSMutableURLRequest
上,为连接设置的超时间隔将被忽略。如果互联网连接有问题(错误的代理、错误的 dns),则 url 请求会在大约 2-4 分钟后失败,但NSLocalizedDescription = "timed out";
NSUnderlyingError = Error Domain=kCFErrorDomainCFNetwork Code=-1001 UserInfo=0x139580 "The request timed out.
如果使用的http
方法是GET
,它可以正常工作。
连接是async
超过https
。
NSURL *url = [NSURL URLWithString:urlString];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setTimeoutInterval:10];
//Set the request method to post
[request setHTTPMethod:@"POST"];
if (body != nil)
[request setHTTPBody:body];
// Add general parameters to the request
if (authorization)
[request addValue: authorization forHTTPHeaderField:@"Authorization"];
[request addValue: WS_HOST forHTTPHeaderField:@"Host"];
[request addValue:@"text/xml" forHTTPHeaderField:@"Content-Type"];
[[NSURLCache sharedURLCache] setDiskCapacity:0];
[self addToQueueRequest:request withDelegate:delegate];
'
【问题讨论】:
尝试使用 requestWithURL:cachePolicy:timeoutInterval: 类方法创建 NSMutableURLRequest 对象? 【参考方案1】:根据 Apple 开发者论坛上的帖子,POST 的最小超时间隔为 240 秒。任何比这更短的超时间隔都会被忽略。
如果您需要更短的超时间隔,请使用异步请求和计时器,并根据需要在 NSURLConnection 上调用取消。
主题链接:here
【讨论】:
在使用 ASIHTTPRequest 框架进行 POST 时,是否有人可以验证 timeout 属性也是如此? 它很有帮助。默认超时我在调用服务时收到错误(以防网络非常糟糕),我将超时设置为大于 240 并且它有效。谢谢。【参考方案2】:ios 6 已修复此问题。
NSMutableURLRequest *request = [NSMutableURLRequest
requestWithURL:[NSURL URLWithString:url]
cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:20];
[request setHTTPMethod:method];
[request setHTTPBody:requestBody];
NSLog(@"%f", [request timeoutInterval]);
//20.0 in iOS 6
//240.0 in iOS 4.3, 5.0, 5.1
【讨论】:
【参考方案3】:修复了 Clay Chambers 的建议:使用自定义计时器
在NSURLConnection
的子类中添加了一个计时器
if (needsSeparateTimeout)
SEL sel = @selector(customCancel);
NSMethodSignature* sig = [self methodSignatureForSelector:sel];
NSInvocation* invocation = [NSInvocation invocationWithMethodSignature:sig];
[invocation setTarget:self];
[invocation setSelector:sel];
NSTimer *timer = [NSTimer timerWithTimeInterval:WS_REQUEST_TIMEOUT_INTERVAL invocation:invocation repeats:NO];
[[NSRunLoop mainRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
在自定义取消方法中,连接被取消
[super cancel];
【讨论】:
【参考方案4】:看起来这里描述的问题仍然面临 iOS 7.1(或再次出现)。幸运的是,在NSURLSession
的配置上设置timeoutIntervalForResource 属性似乎可以解决此问题。
编辑
根据@XiOS 观察,这适用于短于(大约)2 分钟的超时。
【讨论】:
知道这在 ios8 中是否有任何类型的修复,还是在 ios8 中仍然存在? 我的帖子中描述了修复 :) 嗨 Julian Król,看起来不错,虽然我还没有解决。我的实际问题是,当我为我的 NSMutableURLRequest 设置 180 秒的超时间隔时,didFailWithError: 委托会在 75 到 220 秒的间隔内触发,并且比这个间隔大一些,但不完全是 180 秒的间隔。我正在使用 POST 方法进行异步 Web 服务调用。那么你的意思是指定的超时间隔将完全适用于 NSURLSession? 我认为你应该试试这个,根据我对 NSMutableURLRequest 的经验,它根本不起作用,而 NSURLSession 工作正常。 我试过了,但我提到的上述行为与 NSURLSESSION 相同:(【参考方案5】:如果你的意思是如何处理超时错误,我想还没有人回答这个问题
让我写一些我的代码来解释这一点
// replace "arg" with your argument you want send to your site
NSString * param = [NSString stringWithFormat:@"arg"];
NSData *Postdata = [param dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:@"%lu",(unsigned long)[Postdata length]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc]init];
// replace "yoursite" with url of site you want post to
[request setURL:[NSURL URLWithString:[NSString stringWithFormat:@"http//yoursite"]]];
// set what ever time you want in seconds 120 mean 2 min , 240 mean 4 min
[request setTimeoutInterval:120];
[request setHTTPMethod:@"POST"];
[request setValue:postLength forHTTPHeaderField:@"Content-Length"];
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Current-Type"];
[request setHTTPBody:Postdata];
NSURLConnection * connection = [[NSURLConnection alloc]initWithRequest:request delegate:self];
// if request time out without response from server error will occurred
-(void) connection:(NSURLConnection * ) connection didFailWithError:(NSError *)error
if (error.code == NSURLErrorTimedOut)
// handle error as you want
NSLog(@"Request time out , Please try again later");
我希望这对任何询问如何处理超时错误的人有所帮助
【讨论】:
以上是关于POST 请求未考虑 NSMutableURLRequest 超时间隔的主要内容,如果未能解决你的问题,请参考以下文章