本篇文章更新時間:2019/02/16
如有資訊過時或語誤之處,歡迎使用 Contact 功能通知。
一介資男的 LINE 社群開站囉!歡迎入群聊聊~
如果本站內容對你有幫助,歡迎使用 BFX Pay 加密貨幣 或 新台幣 贊助支持。
問題描述
怎麼 POST
過去給 PHP
都收不到資料?
$_POST
方法取不到正確的傳入值!
原理說明
AngularJS 這套 framework 使用的 AJAX 方法中,資料傳遞的格式為 JSON
,送出去的header為
Content-Type: application/json
而非 JQuery 或是 HTML form 送出的
multipart/form-data
或
application/x-www-form-urlencoded
解決辦法
- AngularJS 配合,去把請求的 header 改成 PHP 能夠接受的
- PHP 配合,改成接受 JSON 格式的請求
我個人比較傾向解決辦法2(以JSON溝通為主),JSON格式在前後端的溝通上有著很好的彈性,前端包裝,後端收到資料輕鬆的拆解。
先說辦法1 的解法,首先要把預設值改掉
//替換成自己的模組名稱後使用config設定header
angular.module("YourAppModule", ["SomeModule"]).config(function($httpProvider) {
$httpProvider.defaults.headers.put['Content-Type'] =
'application/x-www-form-urlencoded';
$httpProvider.defaults.headers.post['Content-Type'] =
'application/x-www-form-urlencoded';
});
如上解法
但是這樣只會讓 POST 方法中,傳資料的欄位,變成一次送出 1
團,而且是無屬性欄位只有 值
的一團! (就是 JSON 字串)
所以要
用 AngularJS 的方法自己寫一個中間層(interceptor)來打包請求/回應
$httpProvider.interceptors.push(['$q', function($q) {
return {
request: function(config) {
if (config.data && typeof config.data === 'object') {
//請求在這邊做處理,下方針對請求的資料打包
config.data = serialize(config.data);
//serialize 序列化的程式碼可以參考下方
}
return config || $q.when(config);
}
};
}]);
ref: 參考 <<推薦一讀
var serialize = function(obj, prefix) {
var str = [];
for(var p in obj) {
var k = prefix ? prefix + "[" + p + "]" : p, v = obj[p];
str.push(typeof v == "object" ? serialize(v, k) : encodeURIComponent(k) + "=" + encodeURIComponent(v));
}
return str.join("&");
}
ref: 參考
如此一來,PHP 在後端的部分可以完全不用修改,就接上囉!
雖然有點多此一舉,但是從這可以知道,AngularJS 有 interceptor 可以來包裝請求/回應這件事的設計其實還滿不錯的說~
針對無登入或任何伺服器回應事件,前端網頁需要做跳轉還是其他處理時有個中控管理的機制,減少在其他方法的判斷與 code 的維護
接下來是辦法2
不改動到前端,對後端PHP做一點修改
$content_type_args = explode(';', $_SERVER['CONTENT_TYPE']);
if ($content_type_args[0] == 'application/json')
$_POST = json_decode(file_get_contents('php://input'),true);
ref: 參考
在使用 $_POST
方法前 或 檔案開頭處,補上這三行就OK,與以往開發無兩樣!
原理就是把前端傳過來的 JSON 做 parsing 配給 $_POST ,搞定
後記
目前我只有找到這兩個還滿漂亮的解法,如果還有找到更好的再補,或是麻煩留言推薦囉!
發佈留言