1、問題的來源php
咱們都知道向後臺傳參可使用get、put,其形式就相似於name=jyy&id=001。可是在ng中我卻發現使用$http post進行異步傳輸的過程當中後臺是接收不到數據的。其實這個問題是由於請求頭的緣故。在ng中默認的請求頭是:「Content-Type":"application/json",也就是說傳遞參數是使用的就是json格式。可是後臺默認的倒是Content-Type': 'application/x-www-form-urlencoded'。所以在這樣的狀況下後臺接收到的數據就會是空的。jquery
那麼爲何使用get形式就能夠傳參呢?在書中我發現這樣的一句話:」這個鍵的值是一個字符串map或對象,會被轉換成查詢字符串追加在URL後面。若是值不是字符串,會被JSON序列化」,能夠理解爲在get中參數的傳遞是直接追加在url後面的,那麼此時參數形式{"id":"1","name":"jyy"}會被轉化成id=1&name=jyy追加在url後面。那麼在後臺中就能夠直接獲取到了。例如:json
var app = angular.module('app',[]); app.controller('ctrl',function($scope,$q,$http){ var defer = $q.defer(); var promise = defer.promise; $http({ method: "get", params:{id:1,name:jyy}, url:"1.php" }).success(function(data){ defer.resolve(data); }); promise.then(function(data){ $scope.data = data; }) })
在後臺(PHP)輸入echo $_GET[id]就能夠正常顯示了。promise
那麼接下來就研究怎麼解決post的傳值了。app
2、問題的解決異步
1. 修改請求頭
ide
第一種方法就是在ng中修改請求頭將json格式改爲x-www-form-urlencoded。修改方法點擊便可查看。post
值得注意的是,在使用第二種方法時,能夠修改put,get,post,common的傳參格式。所以修改哪一種方式,就只能使用這種方式才能在後臺獲得參數。這篇博文寫到使用common進行設置能夠同時使用put、get、post進行傳參。可是在個人實際操做中發現對common進行修改並不能使用post進行傳參,而只有設置了post的請求頭才能夠。url
另外因爲在ng中的參數都是使用json格式表達,所以須要引入jquery,使用其$.param("參數列表的json格式")進行序列化表示。spa
首先使用修改post請求頭。具體代碼以下:
var app = angular.module('app');
app.config(function($httpProvider){ $httpProvider.defaults.headers.post = { 'Content-Type': 'application/x-www-form-urlencoded' } }) app.controller('ctrl',function($scope,$resource,$q,$http){ var defer = $q.defer(); var promise = defer.promise; $http({ method: "post", data:$.param({"id":"1","name":"jyy"}), url:"1.php" }).success(function(data){ defer.resolve(data); }); promise.then(function(data){ $scope.data = data; }) })
此時在後臺中(使用的是php),輸入echo $_POST[id],就會顯示。而debug其中顯示的請求頭正是咱們設置的。
2.在後臺進行解決
因爲使用的是php,因此暫時用php的方法解決。在這個方法中,咱們不修改請求頭。由於get傳值是正常的,那麼,只要可以獲得post的值就好。既然ng向後臺傳值了,即使是由於請求頭不一樣,可是總會傳過來什麼的吧,既然可以傳過來,就先獲取它。這個時候使用$GLOBALS['HTTP_RAW_POST_DATA']將這個傳過來的東西顯示出來。那麼這個$GLOBALS['HTTP_RAW_POST_DATA']是什麼呢?在網上查詢得知$HTTP_RAW_POST_DATA 變量包含有原始的 POST 數據。此變量僅在碰到未識別 MIME 類型的數據時產生,PHP不能識別的Content-Type類型的時候,會將http請求包中相應的數據填入變量$HTTP_RAW_POST_DATA。就是說如今這個請求頭雖然是有衝突的,可是卻可以顯示出來。以下:
var app = angular.module('app',[]); app.controller('ctrl',function($scope,$q,$http){ var defer = $q.defer(); var promise = defer.promise; $http({ method: "post", data:{'id':'1','name':'jyy'}, url:"1.php" }).success(function(data){ defer.resolve(data); }); promise.then(function(data){ $scope.data = data; }) })
php代碼:
echo $GLOBALS['HTTP_RAW_POST_DATA'];
此時顯示出來的東西是:{"id":"1","name":"jyy"}。發現這個結果是正確顯示了。那麼直接對齊進行操做不就能夠了?好吧,那就先看看是什麼類型:使用gettype()獲得的是string,就是說他是個json字符串。那就使用json_decode()轉換,發現會報錯。好吧,放棄使用這個方法。
可是此時還有另外的方法。使用file_get_contents("php://input"),這個方法中 php://input 是個能夠訪問請求的原始數據的只讀流。 POST 請求的狀況下,最好使用 php://input 來代替 $HTTP_RAW_POST_DATA,由於它不依賴於特定的 php.ini 指令。 此時這個方法就能夠返回傳過來的參數了。代碼以下:
$a = json_decode(file_get_contents("php://input")); echo $a->id;
結果輸出正確的id。