在最近的一个项目中前端使用了Angular,后台使用了ThinkPHP。但是在前后台数据交换的时候发现下面问题:
ThinkPHP的I方法并不能解析出POST请求携带的数据。
一、场景还原
Angular 的POST请求:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body ng-app="myAPP">
<div ng-controller="testPostController"></div>
<script src="//cdn.bootcss.com/jquery/1.11.1/jquery.min.js"></script>
<script src="//cdn.bootcss.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
<script src="//cdn.bootcss.com/angular.js/1.5.3/angular.js"></script>
<script type="text/javascript">
var app = angular.module("myAPP",[])
app.controller("testPostController",function($http){
$http({
url:"/index.php?c=test&a=testPost",
method:"post",
data:{
name:"wanghao",
gender:"男"
}
}).success(function(){});
})
</script>
</body>
</html>
对应的ThinkPHP处理程序:
<?php
namespace Main\Controller;
use Think\Controller;
class TestController extends Controller
{
public function testPost()
{
$name = I("post.name");
$gender = I("post.gender");
echo "收到的数据:name:" . $name . " gender: " . $gender;
}
}
测试:
1)请求的发出:
回应:
发现并没有取到数据。。。。。。。。
下面用普通的HTML写法来发送POST请求:
<form action="/index.php?c=test&a=testPost" method="post">
<input type="text" name="name" id="">
<input type="text" name="gender" id="">
<input type="submit" id="">
</form>
测试结果:
在chrome的控制台比较原生HTML发送POST请求和使用Angular的$http服务发送POST请求,发现这里的不同:
1、Angular的$http服务:
2、原生HTML
简言之,1:HTTP请求的content-Type字段指明了报文的数据格式,如Angular的POST的请求将数据封装成了json,而原生HTML的数据格式是x-www-form-urlencode
2、ThinkPHP默认以x-www-form-urlencode的方式去解析POST的参数,所以解析不了Angular的请求。。。。
一种解决方案是将Angular的POST换成x-www-urlencode模式,对应的代码:
var transform = function(data){
return $.param(data);
}
$http.post("/foo/bar", requestData, {
headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'},
transformRequest: transform
}).success(function(responseData) {
//do stuff with response
});
更多:请见 StackOverflow上的讨论