標籤:3par ddt vrp jps ops lap car aop original
使用AFNetworking來訪問http請求非常方便快捷,最簡單的請求代碼如下:
#import "HSTestHTTPSViewController.h"#import <AFNetworking/AFNetworking.h>@interface HSTestHTTPSViewController ()@end@implementation HSTestHTTPSViewController- (void)viewDidLoad { [super viewDidLoad]; NSString *URLString = @"http://localhost:8000"; AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; manager.requestSerializer = [AFHTTPRequestSerializer serializer]; manager.responseSerializer = [AFHTTPResponseSerializer serializer]; [manager GET:URLString parameters:nil progress:nil success:^(NSURLSessionDataTask *task, id responseObject) { //返回NSData,轉化為String輸出 NSString *JSONString = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding]; NSLog(@"%@", JSONString); } failure:^(NSURLSessionDataTask *task, NSError *error) { NSLog(@"%@", error); }];}@end
當然,使用上述代碼來請求http能夠成功,但是當我們要訪問https的時候,如果僅僅是把上述的請求URL修改成對應的https,那麼很有可能會出現如下報錯:
NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9813)
Error Domain=NSURLErrorDomain Code=-1202 "The certificate for this server is invalid.
You might be connecting to a server that is pretending to be “localhost” which could put your confidential information at risk." UserInfo={NSURLErrorFailingURLPeerTrustErrorKey=<SecTrustRef: 0x600000108820>, NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9813, NSErrorPeerCertificateChainKey=
(
"<cert(0x7f9bcd84ea00) s: chenyufeng i: chenyufeng>"
), NSUnderlyingError=0x600000057730 {Error Domain=kCFErrorDomainCFNetwork Code=-1202 "(null)" UserInfo={_kCFStreamPropertySSLClientCertificateState=0, kCFStreamPropertySSLPeerTrust=<SecTrustRef: 0x600000108820>, _kCFNetworkCFStreamSSLErrorOriginalValue=-9813, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9813, kCFStreamPropertySSLPeerCertificates=
(
"<cert(0x7f9bcd84ea00) s: chenyufeng i: chenyufeng>"
)}}, NSLocalizedDescription=The certificate for this server is invalid. You might be connecting to a server that is pretending to be “localhost” which could put your confidential information at risk., NSErrorFailingURLKey=https://localhost:8001/, NSErrorFailingURLStringKey=https://localhost:8001/, NSErrorClientCertificateStateKey=0}
出現以上問題的主要原因是https認證是自我簽署憑證,沒有經過第三方機構認證(關於產生自我簽署憑證和nodejs配置自我簽署憑證可以瞭解《nodejs開發——express配置自簽名https伺服器》這篇部落格)。一個經過認證的認證一般不會出現以上問題。那麼在服務端https認證不變的情況下,如何在iOS用戶端修複該問題呢?
(1)從服務端那裡拿到認證crt尾碼檔案,我這裡的檔案名稱為“file.crt”. (建議看下《nodejs開發——express配置自簽名https伺服器》)。然後使用該crt檔案產生用於iOS的.cer檔案,我這裡的檔案名稱為“client.cer”. 產生命令如下:
openssl x509 -in file.crt -out client.cer -outform der
產生前與產生後的crt檔案如下:
(2)然後把client.crt檔案複製到iOS項目目錄下,然後在Build Phases中的Copy Bundle Resources中選中crt檔案進行添加:
(3)然後把AFN的網路請求代碼修改如下:主要增加Security設定
#import "HSTestHTTPSViewController.h"#import <AFNetworking/AFNetworking.h>@interface HSTestHTTPSViewController ()@end@implementation HSTestHTTPSViewController- (void)viewDidLoad { [super viewDidLoad]; NSString *URLString = @"https://localhost:8001"; AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; manager.requestSerializer = [AFHTTPRequestSerializer serializer]; manager.responseSerializer = [AFHTTPResponseSerializer serializer]; //增加AFSecurityPolicy設定 AFSecurityPolicy * securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate]; securityPolicy.allowInvalidCertificates = YES; securityPolicy.validatesDomainName = NO; manager.securityPolicy = securityPolicy; [manager GET:URLString parameters:nil progress:nil success:^(NSURLSessionDataTask *task, id responseObject) { //返回NSData,轉化為String輸出 NSString *JSONString = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding]; NSLog(@"%@", JSONString); } failure:^(NSURLSessionDataTask *task, NSError *error) { NSLog(@"%@", error); }];}@end
經過測試,能成功接收到https的返回結果。
AFNetworking訪問https出現"NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9813"