NSURLConnection返回错误而不是401的响应

时间:2015-04-01 13:17:30

标签: objective-c nsurlconnection nsurlrequest

我有一个Web API,对于特定请求,如果一切正常,则返回状态代码200;如果用户未基于授权令牌登录,则返回401。如果响应状态为200,则一切正常,但如果响应状态为401则无法正常工作,返回代码为-1012的连接错误,而响应为零。

所以,以下代码:

[NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
    NSLog(@"%@", response);
    NSLog(@"%@", connectionError);

    NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response;
    int statusCode = (int)[httpResponse statusCode];
    NSLog(@"response status code: %d", statusCode);

将显示

2015-04-01 15:58:18.511 MyProject[3618:694604] <NSHTTPURLResponse: 0x155facc0> { URL: *SOME_URL* } { status code: 200, headers {
    "Access-Control-Allow-Headers" = "Content-Type, Accept, X-Requested-With";
    "Access-Control-Allow-Methods" = "POST, GET, PUT, UPDATE, OPTIONS";
    "Access-Control-Allow-Origin" = "*";
    Connection = "keep-alive";
    "Content-Type" = "application/json";
    Date = "Wed, 01 Apr 2015 12:58:14 GMT";
    Server = "Wildfly 8";
    "Transfer-Encoding" = Identity;
    "X-Powered-By" = "Undertow 1";
} }
2015-04-01 15:58:18.513 MyProject[3618:694604] (null)
2015-04-01 15:58:18.513 MyProject[3618:694604] response status code: 200

如果响应状态是200,而如果状态代码是401,我将得到:

2015-04-01 16:05:55.988 MyProject[3633:695836] (null)
2015-04-01 16:05:55.992 MyProject[3633:695836] Error Domain=NSURLErrorDomain Code=-1012 "The operation couldn’t be completed. (NSURLErrorDomain error -1012.)" UserInfo=0x146137c0 {NSErrorFailingURLKey=*SOME_URL*, NSErrorFailingURLStringKey=*SOME_URL*, NSUnderlyingError=0x1459e6d0 "The operation couldn’t be completed. (kCFErrorDomainCFNetwork error -1012.)"}
2015-04-01 16:05:55.992 MyProject[3633:695836] response status code: 0

如果我使用Postman或Android设备执行相同的请求,我将获得带有以下标题的状态代码401(从Postman复制):

Connection → keep-alive
Content-Length → 30
Content-Type → application/json
Date → Wed, 01 Apr 2015 13:07:34 GMT
Server → Wildfly 8
X-Powered-By → Undertow 1

是否有任何修复或图书馆可以给我一些准确的回复状态?我对-1012错误进行了一些搜索,但找不到多少,我真的不想基于此。

编辑:经过一些研究后,我在Appl的文档中找到了以下声明:“如果需要进行身份验证以下载请求,则必须将所需的凭据指定为URL的一部分。如果身份验证失败,或凭据丢失,连接将尝试在没有凭据的情况下继续。

但是,我怎么知道这个错误是否会在401状态之后?可以在其他类型的请求后出现吗?

4 个答案:

答案 0 :(得分:2)

检查401错误,你可以这样做:

if (error != nil && error.code == NSURLErrorUserCancelledAuthentication) {
    // do something for 401 error
}

希望这个帮助

答案 1 :(得分:1)

为了获得401状态代码,我认为您需要实施协议 NSURLConnectionDelegate ,然后 connection:didReceiveAuthenticationChallenge:

因此,您还需要传递代理,可能使用 [NSURLConnection connectionWithRequest:request delegate:self]

而且,如果您没有尝试实施身份验证质询,我宁愿总是返回200状态代码,但使用不同的json内容。

希望它可以提供帮助。

答案 2 :(得分:0)

  

我有一个Web API,针对特定请求返回状态代码200   如果一切正常,如果用户没有登录,则为401   授权令牌。如果响应状态,一切正常   是200,但如果响应状态是,似乎无法正常工作   401,返回与代码-1012的连接错误,同时响应   是零。

我完全遇到了同样的问题,REST API调用在Android和Postman中返回401,但iOS中的状态代码为0,连接错误代码为-1012。

您可以在this SO post。

中找到有关此问题的更多信息

似乎是在异步和同步请求中发生的iOS错误(或至少非常奇怪的方法)。

我发布此信息是为了防止其他人遇到同样的问题。我在代码中所做的就是在请求之后立即管理401状态,即调用检查每个托管的http状态代码的方法。

该方法收到(NSError **)错误 [(NSHTTPURLResponse *)响应statusCode]

这是401部分 - 使用 userInfo 结构中存储的错误详细信息。

casper.start('http://www.test.com', function(){

    this.echo('Browser Cookie: ' + this.evaluate(function() {
            return document.cookie;
    }));

    phantom.deleteCookie('PHPSESSID');

    //Get new cookie 
});

另一种方法是直接检查此错误代码(-1012),如上面@ThuanDINH所建议的那样。 (编辑了目标c的答案。)

我的代码可以更改为:

// Auth failed or token problems
if (statusCode == 0 && [error userInfo] != nil) {

    // Get error detailed informations
    NSDictionary *userInfo = [error userInfo];
    NSString *errorString = [[userInfo objectForKey:NSUnderlyingErrorKey] localizedDescription];

    // If error message is of type authFailed or returns iOS code -1012 meaning auth failed
    if ([errorString containsString:@"kCFErrorDomainCFNetwork"] || [errorString containsString:@"-1012"]) {
        NSLog(@"%@ - ConnectionError - Code 401 - Cause: authentication failed, token is invalid or expired", type);
    } else {
        NSLog(@"%@ - ConnectionError - Cause: generic auth error", type);
    }

    // Alert user that auth failed
    ...
}

但是这样你就不会处理所有其他错误了(你需要打开每个NSURLError代码)。

Here您可以在所有NSURLError代码列表中找到SO问题。

答案 3 :(得分:0)

基于Apple文档https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/URLLoadingSystem/NSURLSessionConcepts/NSURLSessionConcepts.html

Note: NSURLSession does not report server errors through the error parameter. The only errors your delegate receives through the error parameter are client-side errors, such as being unable to resolve the hostname or connect to the host. The error codes are described in URL Loading System Error Codes.
Server-side errors are reported through the HTTP status code in the NSHTTPURLResponse object. For more information, read the documentation for the NSHTTPURLResponse and NSURLResponse classes.

我们需要确保不会在代码中取消会话。例如,我在didReceiveChallenge委托方法中调用NSURLSessionAuthChallengeCancelAuthenticationChallenge,当previousFailureCount&gt; 1.这抑制了401响应并且还调用了didReceiveResponse。

当我将上述值更改为NSURLSessionAuthChallengePerformDefaultHandling时,我在didReceiveResponse委托方法中收到401 Unauthorized响应,并按预期工作。