1. 程式人生 > >原生JavaScript實現Ajax(二):同步,非同步,GET,POST

原生JavaScript實現Ajax(二):同步,非同步,GET,POST

上文使用同步方式實現了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請求

  1. 將GET –> POST;
  2. 要傳的引數,不再是追加在URL,而是send()中傳送到伺服器;
  3. 修改請求頭:一般來說,向伺服器傳送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方法中

這裡寫圖片描述