這篇文章主要記錄一下之前爬過的一個坑,關於使用 AFNetworking 中請求數據和 HTTP 的 Content-type 關系。
在iOS端我們常用JSON來作為數據傳輸格式,對於HTTP網絡通信框架現在也是 AFNetworking 居多,在 AFNetworking 2.0 ,有了比較大的變化,引入了 iOS 7 / Mac OS X 10.9 的 NSURLSession
,而在 AFNetworking 中對JSON、XML等數據對象都有良好的支持,在文檔中就可以看到新增了Serialization
對象,我簡單畫了個圖以看得更清晰:
試了下百度FEX開發的在線腦圖工具 kityminder ,並且是開源項目,還真方便,點這裡還可以在線查看。
可以看到 Serialization
派生出 AFURLRequestSerialization
和 AFURLResponseSerialization
,分別作為請求數據和接受數據的序列化方式。AFURLResponseSerialization
又派生出好幾種響應數據序列化方式,能正確的使用他們將給我們帶來極大的方便。
像我們如果用 AFHTTPSessionManager
的話,在初始化後就會設置一個屬性 responseSerializer
,這就是上圖所述的 AFURLResponseSerialization
,告訴AFNetworking 以怎樣的方式接受數據,如果後段接口都是標准的JSON數據格式,那麼很愉快的就選擇了 AFJSONResponseSerializer
,在請求成功的Block中的responseObject
就會是一個 AFNetworking 幫你解好檔的JSON,也就是一個 NSDictionary
對象。
但有時候你是否遇到明明接口是返回的JSON數據,可用 AFJSONResponseSerializer
就會報錯,錯誤信息類似:
Request failed: unacceptable content-type: text/html
這就是因為HTTP響應頭中的 Content-Type
字段對不上號,最簡單的方法就是在浏覽器的開發者工具中看到:
如果接口返回的 Content-Type
和實際情況不合時,有時候是因為後端開發人員不規范,我更有遇到一套接口中大多都是JSON返回,還有個別方法返回純文本,如:“YES”,這些都是接口開發人員不規范導致的問題,作為iOS端,我們有兩種解決方案:
responseSerializer
使用 AFHTTPResponseSerializer
,這樣就不能享受 AFNetworking 自帶的JSON解析功能了,拿到 responseObject
就是一個 Data 對象,需要自己根據需要進行反序列化。關於 Content-Type ,可能還是有些同學不太清楚的,這是HTTP的基礎知識,做後端的同學應該得知道。
Content-Type,內容類型,一般是指網頁中存在的Content-Type,用於定義網絡文件的類型和網頁的編碼,決定浏覽器將以什麼形式、什麼編碼讀取這個文件,這就是經常看到一些Asp網頁點擊的結果卻是下載到的一個文件或一張圖片的原因。 - via 百度百科
這裡還找到一個 Content-Type 對照表:http://tool.oschina.net/commons