iOS9中關于 NSURLSession/NSURLConnection HTTP load failed 的解決辦法

最近為了新的存管app上線,忙了近一個月,重新過了一段996的日子,今天終于可以喘口氣,繼續更新博客了。本文記錄一下在iOS 9中發送https請求遇到的問題及解決辦法,希望通過本文,可以對ATS的配置有一個更深入的了解。

問題描述

在開發app時,遇到了在iOS 9中發送https請求報錯的問題:

NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9801)

我們知道,在iOS 9以后,所有的網絡請求默認使用https,如果你發送http請求,則會報如下錯誤,但是我們可以通過在info.plist中設置NSAppTransportSecurity - NSAllowsArbitraryLoads的值為YES來允許http請求:

App Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure. Temporary exceptions can be configured via your app's Info.plist file.

info.plist

<Center>


允許http請求

</Center>

這樣解決了http的請求問題,但是我發送是https請求,還是出現HTTP laod failed的問題,盡管使用上述方法也可以解決,但這不是根本的解決辦法。

解決辦法

經過分析,懷疑是TLS的問題,因為iOS 9默認需要TLS1.2版本來加密數據,如果服務端不支持TLS1.2,則URLSession:task:didCompleteWithError:會返回nilerror,但是后端開發同事說服務器支持TLS1.0TLS1.1TLS1.2,這好像又不是TLS的問題。于是不放心,用nscurl測試了一下測試服務器,果然不支持TLS1.2,問題找到。

# 加 --verbose 是為了顯示詳細的調試信息
/usr/bin/nscurl --ats-diagnostics --verbose https://testresource.chaoaicai.com

通過輸出看出,服務器只支持TLS1.0,于是讓后臺開發的同事測試并修改后,再次測試,發現服務器支持TLS1.2了,并且https的網絡請求也正常了。

支持TLS1.2

ATS異常配置

其實,針對服務器不支持TLS1.2,而客戶端發送https請求還有其它的解決方法,就是配置ATS,設置最低的TLS版本即可,如下info.plist所示:

<key>NSAppTransportSecurity</key>
  <dict>
  <key>NSExceptionDomains</key>
  <dict>
    <!--你的https域名-->
    <key>testresource.chaoaicai.com</key>
    <dict>
      <!--允許子域-->
      <key>NSIncludesSubdomains</key>
      <true/>
      <!--TLS允許的最低版本號-->
      <key>NSExceptionMinimumTLSVersion</key>
      <string>TLSv1.0</string>
    </dict>
  </dict>
</dict>

其中,NSExceptionDomains的具體設置項介紹如下,可以更詳細的了解ATS的異常配置

  • NSIncludesSubdomains:是否應用到子域名,默認是NO
  • NSExceptionAllowsInsecureHTTPLoads:是否允許http請求,YES(允許),默認是NO
  • NSExceptionMinimumTLSVersion:最低的TLS版本
  • NSExceptionRequiresForwardSecrecy:是否需要前置加密,NO(允許加密,但不支持PFS:perfect forward secrecy),默認是YES
  • NSRequiresCertificateTransparency:是否需要有效的簽名證書,YES(需要),默認是NO

本文只是簡單的介紹了一下如何配置ATS,及解決由于服務器不支持TLS1.2造成的https無法訪問的問題,需要了解httpsTLS的具體工作流程,請參考相關資料。

參考資料

#iOS問題記錄#關于NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9801)

iOS 9 適配系列教程

iOS 9.0

整理iOS9適配中出現的坑(圖文)

Cocoa Keys

NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9802) on a subdomain?

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容