接下來我們來介紹一下Ajax的第二種請求方式,post請求。一般情況下,瀏覽器發送的請求如果要進行更新修改某一數據的時候,我們會採用post請求方式而不是get請求.因爲這樣會有幾個好處。
- 請求的長度不會有限制。一般情況下get請求方式具有字符限制(不同瀏覽器的標準也有所不同,服務器也有所不同)。
- 在進行post請求的時候,瀏覽器會爲我們的數執行urlEncodeComponent()方法,將一些特殊字符如空格進行轉義。
- 不會產生緩存,每一次post請求都是獨立的。
當然這樣也會帶來一些問題。因此,具體情況下使用哪種請求方式是由需求決定的。
在使用post請求,同樣的和之前的例子一樣需要創建一個XMLHttpRequest的對象。爲了方便我們將對象進行了一次處理。與之前的例子一樣,代碼如下:
function createXHR(){
if( typeof XMLHttpRequest != "undefined"){
return new XMLHttpRequest();
}
if(typeof ActiveXobject == "undefined"){
throw new Error(" not support ");
}
//判斷是否爲 IE6或IE6以下版本
if(typeof arguments.callee.activeString != "string"){
var versions = ["MSXML2.XMLHttp.6.0",
"MSXML2.XMLHttp3.0","MSXML2.XMLHttp"],
i,len;
for (var i = 0;i<versions.length;i++) {
try{
//嘗試使用不同版本的插件新建對象
new ActiveXobject(versions[i]);
//將合適的版本保存至 activeString屬性中
//arguments.callee代表的是調用函數,這裏指的是createXHR
arguments.callee.activeString=versions[i];
break;
}catch(ex){
// no action
}
};
}
//返回實例對象
return new ActiveXobject(arguments.callee.activeString);
}
於是我們創建一個XMLHttpRequest對象
var request = createXHR(); // 函數返回XMLHttpRequest對象
簡單的post請求
post請求的方式與get請求有許多地方還是類似的,不過在請求頭部中會添加一個內容,描述請求方法是以html表單的形式傳遞。
function postData(url,data,callback){
var xhr = createXHR();
xhr.open("POST",url);
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
xhr.onreadystatechange = function(){
if(xhr.readyState === 4 && (xhr.status >= 200 || xhr.status <=304 ) ){ //
callback(xhr);
}
}
xhr.send(encodeFormData(data)); //發送表單 編碼數據
}
接下來我們來解釋一下這個函數
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded"); //設置請求頭部
這個操作在我們瀏覽器是可以看到的。使用瀏覽器調試工具F12,打開網絡後,我們經常會看到請求頭部和響應頭部。
在Content-Type 這裏 就是我們設置的請求內容的類型了。這樣是爲了讓服務器認識到是何種請求格式,以及如何對數據進行處理。
這裏的發送數據不在是將數據附加在url地址,而是直接使用的是
xhr.send(encodeFormData(data)); //encodeFormData 爲上一個例子的函數,主要是將對象屬性轉爲請求字符串格式。如 name1=value1&name2=value2
這裏基本上可以看到了get請求與post請求的區別。
- 請求類型 Content-Type 不同。
- 傳遞數據的方法不一樣。get請求附加在url地址欄,而post請求則放在xhr.send();方法內。
接下來我們用一個小小的案例,來讓我們的請求生效。
var url = "http://localhost:3000/demo/post.php";
var data = { q : "normal post request", name : "user" };
postData(url,data,function(res){
if(res.getResponseHeader("Content-Type") == "application/json"){
//判斷響應頭部是否爲json類型
console.log(JSON.prase(res.responseText));
}
}
這樣我們就缺少一個服務端的代碼,這時候我們使用原生php來接受這個請求。
<?php
header("Content-Type:application/json"); //設置響應頭部
$q= isset($_POST['q'])?$_POST['q'] : "";
$time =date("Y-m-d H:i:s"); // 日期字符串
$res = array("q"=>$q, "time"=>$time);
echo json_encode($res);
?>
得到的結果如上圖所示,我們發送過去的參數確實被服務端接受,服務端並且回傳給瀏覽器。
簡單的例子往往可以讓人明白許多技術上的問題。善於把複雜的問題弄得簡單是我追求的目標。