AFNetworking在请求时出现999错误代码

14

我对objective-c很新,并且在使用AFNetworking时遇到了困难。

我的问题是,我想向一个服务器发出一个简单的POST请求,该服务器将向我发送一个salt。 为了测试我的请求,我制作了一个简单的应用程序,但我不明白为什么会得到错误代码999。

这是我的代码示例:

+ (void)simpleRequest; {
    NSURL *mailserver = [NSURL URLWithString:@"https://localhost:4443/"];

    AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc]initWithBaseURL:mailserver];
    manager.securityPolicy.allowInvalidCertificates = TRUE;
    manager.responseSerializer = [AFJSONResponseSerializer serializer];
    manager.requestSerializer = [AFJSONRequestSerializer serializer];
    NSDictionary *parameters = @{@"username": @"testtest"};

    [manager POST:@"api/v0/login/salt" parameters:parameters success:^(NSURLSessionDataTask *operation, id responseObject) {
        NSLog(@"JSON: %@", responseObject);
    } failure:^(NSURLSessionDataTask *operation, NSError *error) {
        NSLog(@"Error: %@", error);
    }];
}

我已经将这段代码链接到一个简单的按钮上,该按钮调用此函数。

我有另一个Ruby Motion应用程序,该函数正常工作,我可以获得响应而不会出现任何错误。但是,在这个简单的应用程序中,我无法进行任何请求,它们都返回错误代码999。

错误:Error Domain=NSURLErrorDomain Code=-999 "cancelled" UserInfo={NSErrorFailingURLKey=https://localhost:4443/api/v0/login/salt, NSLocalizedDescription=cancelled, NSErrorFailingURLStringKey=https://localhost:4443/api/v0/login/salt}

所以我真的想知道我做错了什么,有人能帮助我吗? 谢谢

编辑:

将管理器保存在属性中是否为正确方法,还是我做错了什么? 如果这是正确的方法,似乎这行代码不起作用。 感谢您的帮助

.h文件

@property (nonatomic, retain) AFHTTPSessionManager *session;

.m文件

@synthesize session;
- (IBAction)log:(id)sender {
NSURL *mailserver = [NSURL URLWithString:@"https://localhost:4443/"];

self.session = [[AFHTTPSessionManager alloc]initWithBaseURL:mailserver];
self.session.securityPolicy.allowInvalidCertificates = TRUE;
self.session.responseSerializer = [AFJSONResponseSerializer serializer];
self.session.requestSerializer = [AFJSONRequestSerializer serializer];
NSDictionary *parameters = @{@"username": @"testtest"};

[self.session POST:@"api/v0/login/salt" parameters:parameters success:^(NSURLSessionDataTask *operation, id responseObject) {
    NSLog(@"JSON: %@", responseObject);
} failure:^(NSURLSessionDataTask *operation, NSError *error) {
    NSLog(@"Error: %@", error);
}];

显示您的URL出现错误...也许应该将localhost转换为您的IP地址? - Tj3n
有时候参数将会在请求体中,并且该参数字段为nil,例如https://localhost:4443/api/v0/login/salt?username=testtest。 - Tj3n
我刚试了一下,但是不起作用,至少感谢你的帮助。 - xikimay
在我的情况下,它应该是这样的一个请求:'https://localhost:4443/api/v0/login/salt',这在我的其他应用程序中运行良好。 - xikimay
我在谷歌上进行了一些搜索,他们说这是因为之前的一个请求还没有完成,而另一个请求已经发送,因此您会收到“取消”错误。 - Tj3n
显示剩余2条评论
5个回答

25

在我的情况下,iOS 10 SDK导致了AFNetworking错误代码-999。如果你想要访问一个具有SSL的服务器而又不想检查它,那么在Afnetworking中添加一些隐私策略。

AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeNone];
securityPolicy.allowInvalidCertificates = YES;

[securityPolicy setValidatesDomainName:NO];

1
提供更多上下文会更有帮助,比如在哪里分配这个安全策略,或者它是否是单例等等。仅凭这个回答还不够。 - shortstuffsushi
值得一提的是,这个答案的前提很有用——在会话管理器上设置安全策略确实有帮助(至少在我的情况下)。 - shortstuffsushi
1
_sessionManager = [[AFURLSessionManager alloc] initWithSessionConfiguration:_sessionConfiguration];AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeNone]; securityPolicy.allowInvalidCertificates = YES; [securityPolicy setValidatesDomainName:NO]; _sessionManager.securityPolicy = securityPolicy; - munibsiddiqui
我遇到了一个关于AFSSLPinningModeNone模糊的错误(AFNetworking 3.1)(使用[AFSecurityPolicy defaultPolicy]解决了这个问题,它内部调用了相同的东西)。 - Can Poyrazoğlu
这个并没有完全成功,现在出现了这个警告:"为了验证自签名证书的域名,您必须使用固定引用(pinning)"。 - iosdude

12

错误代码是-999而不是999,这是NSURLErrorCancelled。在请求完成之前,您的请求已被取消。

看看您的代码,您没有在任何地方保留AFHTTPSessionManager *manager。这意味着该管理器将在+simpleRequest返回后立即被处理。我猜这就是取消您的请求的原因。

您需要保存管理器以便它在整个请求期间都存在。请在某个属性中保存它。


我认为我已经正确保存了管理器,但它仍然失败了,我错过了什么吗? - xikimay
@xikimay,这可能是因为在响应返回之前,拥有您的属性的实例已被解初始化。一个hack的方法可能是在块内调用管理器(通过Log())例如。 - Nico

3
在我的情况下,iOS 9 SDK的"应用传输安全"导致了AFNetworking错误代码:-999。如果您尝试连接没有SSL证书的服务器,请像下面的截图添加键。

enter image description here


4
现在不应再接受这个答案。自iOS 10起,允许任意加载需要经过苹果的审核和特定的允许。更好的答案是使用ATS通过使用例外来允许加载HTTP位置。请查看此帖子https://dev59.com/o10Z5IYBdhLWcg3wnBb_,以获取此问题的真正解决方案。 - Olyve

0

[原始的 OP 问题可能没有提到 Cordova,但是当在谷歌搜索这个问题时,这个链接排名非常靠前]

对于我的 Cordova 项目(或类似项目),结果是一个插件问题。确保您没有漏掉任何插件,并确保它们被正确安装且没有问题。

最简单的验证方法是通过重新创建 Cordova 项目cordova create <path>),以及添加所需平台(cordova platform add <platform name>),并使用详细标志(--verbose)添加每个插件,以便您可以在控制台日志中查看插件下载、添加到项目和为每个平台安装时是否出现任何错误(cordova plugin add cordova-plugin-device --verbose

总结: cordova create <path> cordova platform add <platform name> cordova plugin add cordova-plugin-device --verbose


0

我注意到你的API端点指示了一个安全连接:

httpS://localhost:4443/api/v0/login/salt

试一试,也许可以解决你的问题。

在我的情况中,这是API管理器代码中的一个打字错误。可以说这部分与应用程序传输安全设置有关。

将受保护协议从httpS://更改为http://,错误:

NSURLErrorDomain Code = -999 "cancelled"

就消失了,一切正常

+如果你有类似的问题,请务必与处理应用程序服务器或API配置的后端专家讨论此事。这意味着服务器没有有效的安全证书。也许你仍然需要一个安全连接。或者这位专家可以再次将一切配置回来,从http://改为httpS://,我不确定(没有检查),当你在代码中已经使用非安全的http://连接时,这是否还能再次工作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接