POST 请求未考虑 NSMutableURLRequest 超时间隔

Posted

技术标签:

【中文标题】POST 请求未考虑 NSMutableURLRequest 超时间隔【英文标题】:NSMutableURLRequest timeout interval not taken into consideration for POST requests 【发布时间】:2009-09-23 14:33:50 【问题描述】:

我有以下问题。在使用HTTP 方法POSTNSMutableURLRequest 上,为连接设置的超时间隔将被忽略。如果互联网连接有问题(错误的代理、错误的 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 超时间隔的主要内容,如果未能解决你的问题,请参考以下文章

POST 请求 ReactJS 后列表项未呈现

Axios Post 请求发送未定义

Restangular POST 请求未按预期工作

QNetworkAccessManager 未发送 POST 请求的数据部分

POST 请求响应未定义,但 REQUEST 有效

$http post 请求未添加指定的标头