Objective-C调用无SSL的API首次正常二次报SSL错误如何解决
问题原因
- 核心触发逻辑是HTTP Strict Transport Security(HSTS) 策略生效:首次发起HTTP请求时,服务端响应头携带了
Strict-Transport-Security字段,iOS系统会在该字段指定的有效期内,强制将该域名的所有请求改为HTTPS协议发起,无需再经过服务端跳转,因此你第二次请求时,系统自动将你传入的HTTP地址替换为了HTTPS地址。 - 报错根因:你的8080端口仅提供HTTP服务,未配置HTTPS证书,HTTPS请求发起后SSL握手失败,因此抛出-1200的SSL连接错误。
注意:你现有代码中配置的
allowInvalidCertificates、validatesCertificateChain仅用于HTTPS请求的证书校验,不会阻止系统将HTTP请求转为HTTPS的逻辑,对该问题无修复效果。
解决方案
服务端方案(最优)
如果该业务域名不需要强制走HTTPS,直接移除服务端响应头中的Strict-Transport-Security字段即可。已触发HSTS规则的用户等待规则有效期过期,或是卸载重装App即可恢复正常访问。
客户端兼容方案(服务端无法修改时使用)
方案1:修改请求缓存策略,避免HSTS规则被系统持久化
你使用的是AFNetworking 2.x版本,可以在请求初始化时添加如下配置:
AFHTTPRequestOperationManager *opManager = [AFHTTPRequestOperationManager manager]; opManager.responseSerializer = [AFJSONResponseSerializer serializer]; [opManager.requestSerializer setValue:@"no-cache" forHTTPHeaderField:@"Cache-Control"]; // 新增:设置请求忽略本地缓存,避免HSTS规则被读取 opManager.requestSerializer.cachePolicy = NSURLRequestReloadIgnoringLocalCacheData; // 新增:发起请求前清空该域名已有缓存 NSURL *domainURL = [NSURL URLWithString:@"http://www.example.com:8080"]; [[NSURLCache sharedURLCache] removeCachedResponsesForRequest:[NSURLRequest requestWithURL:domainURL]]; opManager.securityPolicy.allowInvalidCertificates = NO; opManager.securityPolicy.validatesCertificateChain = NO; NSDictionary* parameters = @{@"phone_number":self.phoneNumberTextField.text, @"password":self.passwordTextField.text}; [opManager POST:@"http://www.example.com:8080/api.php/login" parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) { NSLog(@"Login Response Object %@",responseObject); } failure:^(AFHTTPRequestOperation *operation, NSError *error) { NSLog(@"Login2222-2 - %@",error); }];
方案2:手动重写请求URL,强制使用HTTP协议
如果方案1不生效,可以手动构造请求,覆盖系统自动修改的HTTPS地址:
AFHTTPRequestOperationManager *opManager = [AFHTTPRequestOperationManager manager]; opManager.responseSerializer = [AFJSONResponseSerializer serializer]; [opManager.requestSerializer setValue:@"no-cache" forHTTPHeaderField:@"Cache-Control"]; opManager.securityPolicy.allowInvalidCertificates = NO; opManager.securityPolicy.validatesCertificateChain = NO; NSDictionary* parameters = @{@"phone_number":self.phoneNumberTextField.text, @"password":self.passwordTextField.text}; // 手动构造请求,强制覆盖URL为HTTP NSMutableURLRequest *request = [opManager.requestSerializer requestWithMethod:@"POST" URLString:@"http://www.example.com:8080/api.php/login" parameters:parameters error:nil]; request.URL = [NSURL URLWithString:@"http://www.example.com:8080/api.php/login"]; AFHTTPRequestOperation *operation = [opManager HTTPRequestOperationWithRequest:request success:^(AFHTTPRequestOperation *operation, id responseObject) { NSLog(@"Login Response Object %@",responseObject); } failure:^(AFHTTPRequestOperation *operation, NSError *error) { NSLog(@"Login2222-2 - %@",error); }]; [opManager.operationQueue addOperation:operation];
方案3:开发阶段临时修复
开发测试时如果需要快速验证,可以直接卸载App重装或是重启手机,清除本地已存储的HSTS规则即可临时恢复正常。
内容的提问来源于stack exchange,提问作者Test
相关产品推荐
相关产品推荐

