原生JavaScript實現Ajax(二):同步,非同步,GET,POST
阿新 • • 發佈:2019-01-24
上文使用同步方式實現了ajax,本文使用非同步的方式,因為非同步才是我們的目的,也是真正常用的手段,使用非同步需要觸發readystatechange事件,然後檢測readyState這個屬性就行。不同的瀏覽器,這裡略有不同,但大致分為下面5種狀態值:
- 0:未初始狀態 : 尚未呼叫open()方法,有的瀏覽器沒有此狀態;
- 1:啟動 : 已經呼叫open方法,尚未呼叫send方法;
- 2:傳送 : 已經呼叫send()方法,但是還未收到任何響應;
- 3:接受 : 已經接收到部分響應資料了,此狀態一般沒啥用,有的瀏覽器沒有;
- 4:完成 : 已經成功收到全部響應資料,而且可以使用,大功告成!
非同步
此時,send方法裡的引數就不能為空了,因為非同步的需要,更是要對readystatechange事件的readyState狀態碼進行判斷,也就是上面一段話。
function createXHR() {
if (window.XMLHttpRequest) {
return new XMLHttpRequest();
} else {
return new ActiveXObject('MicroSoft.XMLHTTP');
}
}
var xhr = createXHR();
xhr.onreadystatechange = function () {
//如果不用等於4判斷一下,這個函式會執行四五次,也只有等於4的時候才是真的成功
if (xhr.readyState == 4) {
if (xhr.status == 200) {
alert(xhr.responseText);
} else {
alert('獲取資料錯誤,錯誤程式碼:' + xhr.status + '錯誤資訊:' + xhr.statusText);
}
}
}
xhr.open('get', 'test.php?rand='+Math.random(), true );
xhr.send(null);
GET和POST
一般而言,在web應用中,GET一般是URL提交請求,test.php?user=guoyu&age=28,POST一般是表單提交,比如:
<form method="POST">
<input type="text" name="user" value="guoyu">
<input type="text" name="age" value=28>
</form>
不過呢,在ajax中,就不分什麼表單了,語法差別不大。
HTTP頭資訊
兩種頭資訊:
1,響應頭資訊:伺服器返回的資訊,客戶端可以獲取,不可以設定;
2,請求頭資訊:客戶端傳送的資訊,客戶端可以設定,不可以獲取;
獲取響應頭資訊:
1,getAllResponseHeaders();//獲取整個響應頭資訊
2,getResponseHeader('Content-Type');//比如只獲取Content-Type資訊
function createXHR() {
if (window.XMLHttpRequest) {
return new XMLHttpRequest();
} else {
return new ActiveXObject('MicroSoft.XMLHTTP');
}
}
var xhr = createXHR();
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
alert(xhr.getAllResponseHeaders());
} else {
alert('獲取資料錯誤,錯誤程式碼:' + xhr.status + '錯誤資訊:' + xhr.statusText);
}
}
}
xhr.open('get', 'test.php?rand='+Math.random(), true);
//設定請求頭資訊,比如新增一些資訊
xhr.setRequestHeader('myname','guoyu');
xhr.send(null);
GET請求是最常見的請求型別,最常用於向伺服器查詢某些資訊。必要時,可將查詢字串引數追加到URL的尾部,以便提交給伺服器。
xhr.open('get','test.php?rand='+Math.random()+'&user=guoyu&age=28',true);
將test.php改為
<?php
header('Content-Type:text/html;charset=utf-8');
//echo Date('Y-m-d H:i:s');
print_r($_GET);
print_r($_POST);
?>
前端檔案改為:
function createXHR() {
if (window.XMLHttpRequest) {
return new XMLHttpRequest();
} else {
return new ActiveXObject('MicroSoft.XMLHTTP');
}
}
var xhr = createXHR();
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
alert(xhr.responseText);//注意這裡,見下圖
} else {
alert('獲取資料錯誤,錯誤程式碼:' + xhr.status + '錯誤資訊:' + xhr.statusText);
}
}
}
xhr.open('get', 'test.php?rand='+Math.random()+'&user=guoyu&age=28', true);
xhr.send(null);
特殊字元問題,比如&的衝突處理
有些特殊字元會造成引數傳遞錯誤,比如user是gu&oyu,也就是本身就帶&,這個時候,需要用js提供的一個方法:encodeURIComponent()方法。
先新增一個addParam()方法,用於在URL後面追加引數
function createXHR() {
if (window.XMLHttpRequest) {
return new XMLHttpRequest();
} else {
return new ActiveXObject('MicroSoft.XMLHTTP');
}
}
function addParams(url, name, value) {
//先判斷url有沒有‘?’,若果無,加引數時需要補上,如果已經有了,則不需在加‘?’
url += url.indexOf('?') == -1 ? '?' : '&';
url += name + '=' + value;
return url;
}
var xhr = createXHR();
var url = 'test.php?rand='+Math.random();
url = addParams(url, 'user', 'g&uoyu');//注意這裡特殊符號
url = addParams(url, 'age', 28);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
alert(xhr.responseText);
} else {
alert('獲取資料錯誤,錯誤程式碼:' + xhr.status + '錯誤資訊:' + xhr.statusText);
}
}
}
xhr.open('get', url, true);
xhr.send(null);
encodeURIComponent
function addParams(url, name, value) {
//先判斷url有沒有‘?’,若果無,加引數時需要補上,如果已經有了,則不需在加‘?’
url += url.indexOf('?') == -1 ? '?' : '&';
url += encodeURIComponent(name) + '=' + encodeURIComponent(value);
return url;
}
POST請求
- 將GET –> POST;
- 要傳的引數,不再是追加在URL,而是send()中傳送到伺服器;
- 修改請求頭:一般來說,向伺服器傳送POST請求由於解析機制的原因,需要進行特別處理,因為POST請求和web表單提交是不同的,需要使用XHR來模仿表單提交,不然,POST資料不能提交到伺服器,顯示空白,需要如下處理:
xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
function createXHR() {
if (window.XMLHttpRequest) {
return new XMLHttpRequest();
} else {
return new ActiveXObject('MicroSoft.XMLHTTP');
}
}
var xhr = createXHR();
var url = 'test.php?rand='+Math.random();
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
alert(xhr.responseText);
} else {
alert('獲取資料錯誤,錯誤程式碼:' + xhr.status + '錯誤資訊:' + xhr.statusText);
}
}
}
xhr.open('POST', url, true);//第一步:GET換成POST
xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');//第二步:修改請求頭,模仿form提交
xhr.send('user=guoyu&age=28');//第三步:要提交的資料放到send方法中