用angularJS中的$http服務碰到了一個問題:運用$http.post方法向後臺傳遞數據時,後臺的php頁面獲取不到data參數傳過來的值。
不論是這種姿勢:
$http.post( "1.php", { id: 1 }).success(function (data) {
console.log(data);
});
還是這種姿勢:
$http({
method: 'POST',
url: '1.php',
data: { id: 1 }
}).success(function (data) {
console.log(data);
});
後臺php中的$_POST或$_REQUEST都無法獲取到data中的值:
<?php
echo json_encode($_POST);
?>
輸出爲一個空數組。爲了測試php本身是不是真的獲取不到值,我就寫了個表單測試下:<form action="1.php" method="post">
<input type="text" name="tid">
<input type="submit" value="submit">
</form>
輸出結果爲:{"tid":"2"},也就是說表單裏的值是可以獲取的,但是用ajax發送的數據獲取不了!
那麼表單數據和ajax發送的post數據之間有什麼差異呢?於是我悄悄瞄一眼請求頭...
1.表單的請求頭部:
2.ajax發送的數據的請求頭部: 問題一下子就出來了!表單發送的文本類型是表單類型,而angular的ajax默認發送的則是json數據。那麼怎麼把Content-type給改了呢?於是我就打開了angular的官網,照着改一下請求頭:
$http({
method: 'POST',
url: '1.php',
data: { id : 1 }
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
}).success(function (data) {
console.log(data);
});
於是輸出結果爲:{"{\"test\":1}":""},還是有問題。對象並沒有自動地序列化(jQuery用習慣了都快忘了居然還有這個問題!)
那麼解決方案有:
1.不寫成對象的形式,直接寫字符串:
$http({
method: 'POST',
url: '1.php',
data: 'test=1',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
}).success(function (data) {
console.log(data);
});
2.重寫angular中transformRequest,自己寫一個轉換方法:
$http({
method: 'POST',
url: '1.php',
data: $scope.data,
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
transformRequest: function ( data ) {
var str = '';
for( var i in data ) {
str += i + '=' + data[i] + '&';
}
return str.substring(0,str.length-1);
}
}).success(function (data) {
console.log(data);
});
3.重寫angular中的transformRequest,簡單粗暴地把jquery拿過來:
$http({
method: 'POST',
url: '1.php',
data: $scope.data,
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
transformRequest: function ( data ) {
return $.param(data);
}
}).success(function (data) {
console.log(data);
});
4.修改默認的transformations(這個不太熟,先看一眼官網上怎麼說的):
Default Transformations
The $httpProvider
provider
and $http
service expose defaults.transformRequest
and defaults.transformResponse
properties.
If a request does not provide its own transformations then these will be applied.
You can augment or replace the default transformations by modifying these properties by adding to or replacing the array.
Angular provides the following default transformations:
Request transformations ($httpProvider.defaults.transformRequest
and $http.defaults.transformRequest
):
- If the
data
property of the request configuration object contains an object, serialize it into JSON format.
Response transformations ($httpProvider.defaults.transformResponse
and $http.defaults.transformResponse
):
- If XSRF prefix is detected, strip it (see Security Considerations section below).
- If JSON response is detected, deserialize it using a JSON parser.
app.config(['$httpProvider', function ( $httpProvider ) {
$httpProvider.defaults.transformRequest = function ( data ) {
var str = '';
for( var i in data ) {
str += i + '=' + data[i] + '&';
}
return str.substring(0,str.length-1);
}
}]);
$http({ method: 'POST', url: '1.php', data: $scope.data, headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }).success(function (data) { console.log(data); });