AJAX - REST
Table of Contents
#
AJAX - REST
在 REST 當道的現在, 不得不了解一下如何實作 CRUD(create, read, update, delete) 本文 server side 以 php 為例子
var xhr = new XMLHttpRequest();
xhr.open('GET', 'example.html', true);
xhr.onreadystatechange = function() {
if (xhr.readyState === 4 && xhr.status === 200) {
document.getElementById('myDiv').innerHTML = xhr.responseText;
}
};
xhr.send();
上面為一個簡單的 AJAX 行為
在此之前須了解在做 AJAX 行為時, 資料是如何跟 request 一起帶到 server side 大致上有 3 種
- FormData
- application/x-www-form-urlencoded
- payload
前面 2 種是用傳統的 form 包起來一起帶到 server side
再經由 php 解析 GET / POST
由於 php 只有 $_GET
& $POST
這無法達到真正的 rest(不過有人硬幹出來 tronice/epv)
所以必須由其他方式實作
最簡單的實作就是使用 $_SERVER['REQUEST_METHOD']
來捕捉 4 種 request 的 method
$method = $_SERVER['REQUEST_METHOD'];
print_r($method);
switch($method)
{
case "PUT":
// do somethong
break;
case "GET":
// do somethong
break;
case "DELETE":
// do somethong
break;
case "POST":
// do somethong
break;
}
這是最簡單實作 rest 的方式 目前 php framework 大部份都有實作 rest, 所以也不用擔心加重開發上的負擔
##
FormData or application/x-www-form-urlencoded or payload?
接下來介紹一下這 3 種方式在前後端的行為差異
相信大家都了解 form
表單 submit
那在 AJAX 崛起之後把 Content-Type
設定成 application/x-www-form-urlencoded
是一個普遍的做法
jQuery 也是採用這方式實作的
###
setRequestHeader(‘Content-Type’, ‘application/x-www-form-urlencoded’)
var obj = {
'user': 'ted',
'password': '123456'
},
jsonData;
jsonData = JSON.stringify(obj);
var xhr = new XMLHttpRequest();
xhr.open('POST', 'test.php', true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.onreadystatechange = function() {
if (xhr.readyState === 4 && xhr.status === 200) {
document.getElementById('myDiv').innerHTML = xhr.responseText;
}
};
xhr.send('json=' + jsonData);
###
FormData
之後出現 FormData
這個物件, 它的優勢在於使用比 application/x-www-form-urlencoded
的方式簡單而且 Content-Type
是 multipart/form-data
用 boundary
的方式傳送
這有一個好處就是可以實作 AJAX 的 file upload, 而不是傳統的 form 表單檔案上傳
至於 AJAX 上傳的好處就是可以捕捉上傳進度、取消上傳, 做多檔上傳的排程(目前常見的 cloud storage service 幾乎都是這樣做)
var formData = new FormData();
formData.append('str', 'string');
formData.append('num', 123);
var xhr = new XMLHttpRequest();
xhr.open('POST', 'test.php');
xhr.onreadystatechange = function() {
if (xhr.readyState === 4 && xhr.status === 200) {
document.getElementById('myDiv').innerHTML = xhr.responseText;
}
};
xhr.send(formData);
以上兩種方式在 PHP 中皆是以 $_GET
or $_POST
接下來處理
if (isset($_POST['json']))
{
echo $_POST['json'];
}
if (isset($_POST['str']))
{
echo $_POST['str'];
}
if (isset($_POST['num']))
{
echo $_POST['num'];
}
###
payload
這方法是個高端的方法, 第一次遇到這方法是在 AngularJS 上, 不過貌似國外開始漸漸這樣做了
這有方式個好處, 就是接收端不須經由 $_POST
or $_GET
進來, 直接用 file_get_contents("php://input")
接收 client 端的 data
還有效能上的優勢, 因為不經由 $_POST
or $_GET
進來可以減少成本增進效能
在 AngularJS 中會把 Content-Type
指定為 application/json
方便 server side 識別與處理
var obj = {
'user': 'ted',
'password': '123456'
},
jsonData;
jsonData = JSON.stringify(obj);
var xhr = new XMLHttpRequest();
xhr.open('POST', 'test.php', true);
xhr.onreadystatechange = function() {
if (xhr.readyState === 4 && xhr.status === 200) {
document.getElementById('myDiv').innerHTML = xhr.responseText;
}
};
xhr.send('json=' + jsonData);
在 PHP 必須用 file_get_contents("php://input")
來接資料
$request = file_get_contents("php://input");
var_dump($request);
$data = json_decode($request);
echo '<br>';
echo 'data:';
echo '<br>';
echo 'User:' . $data->user;
echo '<br>';
echo 'Pwd:' . $data->password;
##
Finally
關於使用 FormData 與 payload 處理 file upload 之後會有文章補充