iOS Error Domain=NSURLErrorDomain Code=-999 “cancelled” 解決辦法

RoshanDev發表於2016-12-07

先上我這兒成功的程式碼

- (void)testATS {
    //先匯入證照,找到證照的路徑
    NSString *cerPath = [[NSBundle mainBundle] pathForResource:@"cert" ofType:@"cer"];
    NSData *certData = [NSData dataWithContentsOfFile:cerPath];
    
    //AFSSLPinningModeNone 這個模式表示不做 SSL pinning,只跟瀏覽器一樣在系統的信任機構列表裡驗證服務端返回的證照。若證照是信任機構簽發的就會通過,若是自己伺服器生成的證照,這裡是不會通過的。
    //AFSSLPinningModeCertificate 這個模式表示用證照繫結方式驗證證照,需要客戶端儲存有服務端的證照拷貝,這裡驗證分兩步,第一步驗證證照的域名/有效期等資訊,第二步是對比服務端返回的證照跟客戶端返回的是否一致。
    //AFSSLPinningModePublicKey 這個模式同樣是用證照繫結方式驗證,客戶端要有服務端的證照拷貝,只是驗證時只驗證證照裡的公鑰,不驗證證照的有效期等資訊。只要公鑰是正確的,就能保證通訊不會被竊聽,因為中間人沒有私鑰,無法解開通過公鑰加密的資料。
    
    AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeNone];
    if (certData) {
        securityPolicy.pinnedCertificates = @[certData];
    }
    AFHTTPSessionManager *sessionManager = [AFHTTPSessionManager manager];
    [sessionManager setSecurityPolicy:securityPolicy];
    sessionManager.responseSerializer = [AFJSONResponseSerializer serializer];
    sessionManager.responseSerializer.acceptableContentTypes = [sessionManager.responseSerializer.acceptableContentTypes setByAddingObject:@"text/html"];

    NSString *urlStr = @"https://huifang.tech/info.php";
    [sessionManager GET:urlStr parameters:nil success:^(NSURLSessionDataTask *task, id responseObject) {
DDLog(@"responseObject = %@", responseObject);
    } failure:^(NSURLSessionDataTask *task, NSError *error) {
        DDLog(@"error = %@", error);
    }];
}

因為之前使用了 AFSSLPinningModeCertificate 模式
AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate];
改成現在的 AFSSLPinningModeNone 模式,解決問題。
因為我的證照是 Symantec 的 DV SSL 證照,所以 securityPolicy 的 allowInvalidCertificates 和 validatesDomainName 屬性都是預設值?。自籤的還沒試過。
參考連結:

  1. AFNetworking原始碼解析<三>

  2. stackoverflow

蛋疼的自己的 hexo 搭建的部落格很久沒弄,今天給弄成 404 了= =。。。先放這兒存個檔吧。

2016-12-07 10:59:52更新:
部落格好了Y(^o^)Y連結

相關文章