天天看點

iOS 9 Afnetworking 3.0 Request failed: unacceptable content-type: text/plainHTTP Content-type 與 AFNetworking

(2014-11-24 14:12:12)

<a target="_blank" href="http://blog.sina.com.cn/s/articlelist_1659996503_1_1.html"></a>

以前用的好端端的接口,今天通路居然出錯了,但是再用浏覽器測試,發現可以正常傳回資料,甚是奇怪啊。

下面是錯誤資訊:

擷取伺服器響應出錯 error=ErrorDomain=com.alamofire.error.serialization.response Code=-1016"Request failed: unacceptable content-type: text/html"UserInfo=0x7fdfd8729680{com.alamofire.serialization.response.error.response= { URL:http://172.16.1.31:7001/itom/getwork } { status code: 200, headers{

   "Cache-Control" = "no-cache";

   "Content-Type" = "text/html;charset=UTF-8";

    Date= "Mon, 24 Nov 2014 03:13:16 GMT";

   "Transfer-Encoding" = Identity;

   "X-Powered-By" = "Servlet/2.5 JSP/2.1";

} },NSErrorFailingURLKey=http://172.16.1.31:7001/itom/getwork,com.alamofire.serialization.response.error.data=&lt;5b7b227374617475 73223a22 73756363 65737322 2c226d73 67223a22 e799bbe99986e688 90e58a9f 227d5d&gt;, NSLocalizedDescription=Requestfailed: unacceptable content-type: text/html}

下面是百度出來的答案:

I also encountered the same problem.This means that your server issending <code>"text/html"</code> insteadof the already supported types. After a little search, my solutionwas toadd <code>"text/html"</code> to <code>acceptableContentTypes</code> setin <code>AFURLResponseSerialization</code> class.Just search for "acceptableContentTypes" andadd <code>@"text/html"</code> tothe set manually. Of course, the ideal solution will be to changethe tpe from the server, but for that you will hade to talk withthe server team.

I hope this helps you. Best regards andless bugs as possible in the code.

 <code>op.responseSerializer.acceptableContentTypes =[NSSet setWithObject:@"text/html”];</code>

<code></code>

<code>對應到自己的項目裡面,我用的是AFNetworking這套網絡請求包,需要改的是:</code>

<code>AFURLResponseSerialization.m檔案</code>

<code>223行:</code>

self.acceptableContentTypes =[NSSetsetWithObjects:@"application/json", @"text/html",@"text/json",@"text/javascript", nil];

加上藍色部分,其實就是添加一種伺服器傳回的資料格式。

這篇文章主要記錄一下之前爬過的一個坑,關于使用 AFNetworking 中請求資料和 HTTP 的 Content-type 關系。

在iOS端我們常用JSON來作為資料傳輸格式,對于HTTP網絡通信架構現在也是 AFNetworking 居多,在 AFNetworking 2.0 ,有了比較大的變化,引入了 iOS 7 / Mac OS X 10.9 的 <code>NSURLSession</code> ,而在 AFNetworking 中對JSON、XML等資料對象都有良好的支援,在文檔中就可以看到新增了 <code>Serialization</code> 對象,我簡單畫了個圖以看得更清晰:

可以看到 <code>Serialization</code> 派生出 <code>AFURLRequestSerialization</code> 和 <code>AFURLResponseSerialization</code> ,分别作為請求資料和接受資料的序列化方式。<code>AFURLResponseSerialization</code> 又派生出好幾種響應資料序列化方式,能正确的使用他們将給我們帶來極大的友善。

像我們如果用 <code>AFHTTPSessionManager</code> 的話,在初始化後就會設定一個屬性 <code>responseSerializer</code>,這就是上圖所述的 <code>AFURLResponseSerialization</code>,告訴AFNetworking 以怎樣的方式接受資料,如果後段接口都是标準的JSON資料格式,那麼很愉快的就選擇了 <code>AFJSONResponseSerializer</code> ,在請求成功的Block中的<code>responseObject</code> 就會是一個 AFNetworking 幫你解好檔的JSON,也就是一個 <code>NSDictionary</code>對象。

但有時候你是否遇到明明接口是傳回的JSON資料,可用 <code>AFJSONResponseSerializer</code> 就會報錯,錯誤資訊類似:

Request failed: unacceptable content-type: text/html

這就是因為HTTP響應頭中的 <code>Content-Type</code> 字段對不上号,最簡單的方法就是在浏覽器的開發者工具中看到:

如果接口傳回的 <code>Content-Type</code> 和實際情況不合時,有時候是因為後端開發人員不規範,我更有遇到一套接口中大多都是JSON傳回,還有個别方法傳回純文字,如:“YES”,這些都是接口開發人員不規範導緻的問題,作為iOS端,我們有兩種解決方案:

告訴接口開發人員規範寫法,你好我好大家好!(推薦)

<code>responseSerializer</code> 使用 <code>AFHTTPResponseSerializer</code>,這樣就不能享受 AFNetworking 自帶的JSON解析功能了,拿到 <code>responseObject</code> 就是一個 Data 對象,需要自己根據需要進行反序列化。

關于 Content-Type ,可能還是有些同學不太清楚的,這是HTTP的基礎知識,做後端的同學應該得知道。

Content-Type,内容類型,一般是指網頁中存在的Content-Type,用于定義網絡檔案的類型和網頁的編碼,決定浏覽器将以什麼形式、什麼編碼讀取這個檔案,這就是經常看到一些Asp網頁點選的結果卻是下載下傳到的一個檔案或一張圖檔的原因。 - via 百度百科