----------------------------------------- 引文 ---------------------------------------------
application/jsonapplication/json 这个 Content-Type 作为响应头大家肯定不陌生。实际上,现在越来越多的人把它作为请求头,用来告诉服务端消息主体是序列化后的 JSON 字符串。由于 JSON 规范的流行,除了低版本 IE 之外的各大浏览器都原生支持 JSON.stringify,服务端语言也都有处理 JSON 的函数,使用 JSON 不会遇上什么麻烦。 JSON 格式支持比键值对复杂得多的结构化数据,这一点也很有用。记得我几年前做一个项目时,需要提交的数据层次非常深,我就是把数据 JSON 序列化之后来提交的。不过当时我是把 JSON 字符串作为 val,仍然放在键值对里,以 x-www-form-urlencoded 方式提交。 Google 的 AngularJS 中的 Ajax 功能,默认就是提交 JSON 字符串。例如下面这段代码: var data = {'title':'test', 'sub' : [1,2,3]};$http.post(url, data).success(function(result) { ...});最终发送的请求是: POST http://www.example.com HTTP/1.1 Content-Type: application/json;charset=utf-8{"title":"test","sub":[1,2,3]}这种方案,可以方便的提交复杂的结构化数据,特别适合 RESTful 的接口。各大抓包工具如 Chrome 自带的开发者工具、Firebug、Fiddler,都会以树形结构展示 JSON 数据,非常友好。但也有些服务端语言还没有支持这种方式,例如 php 就无法通过 $_POST 对象从上面的请求中获得内容。这时候,需要自己动手处理下:在请求头中 Content-Type 为 application/json 时,从 php://input 里获得原始输入流,再 json_decode 成对象。一些 php 框架已经开始这么做了。 ----------------------------------------- 引文 --------------------------------------------- 我代码里 Input.php 这样修改的: public function post_get($index, $xss_clean = NULL) { $r_data = null; if(is_null($index)){ $tP = $this->post($index,$xss_clean); if(count($tP)){ $tg = $this->get($index,$xss_clean); foreach($tg as $t_field=>$t_value){ if(array_key_exists($t_field,$tP)){ if(is_array($tP[$t_field]) && is_array($t_value)) $tP[$t_field] = $tP[$t_field] + $t_value; }else{ $tP[$t_field] = $t_value; } } $r_data = $tP; // return $tP; }else{ $r_data = $this->get($index,$xss_clean); } // return $this->get($index,$xss_clean); $t_data = file_get_contents('php://input', 'r'); $j_data = json_decode($t_data,true); if(is_array($j_data) && array_key_exists('data',$j_data) && count($j_data['data'])){ if(count($r_data)){ $r_data =array_unique(array_merge($r_data,$j_data['data'])); }else{ $r_data = $j_data['data']; } } return $r_data; } return isset($_POST[$index]) ? $this->post($index, $xss_clean) : $this->get($index, $xss_clean); }
|