天天看点

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 百度百科