深入學習ajax系列之二-請求方式

最常見的請求莫過於get和post了,今天詳細的學習一下兩種方式的內容,

GET

GET是常見的請求方式,常用於向服務器查詢某些信息,它適用於URL完全指定資源,當請求對服務器沒有任何副作用以及服務器的響應式可緩存的。

數據發送

使用GET的方式發送請求時,數據被追加到open()方法中URL的末尾 
數據以問號開始,名和值之間用等號鏈接起來,名值對之間用&分割,使用GET方式發送的數據常常被稱之爲查詢字符串。

xhr.open("get","example.php?name1=value1&name2=value2",true)
  • 1

【編碼】

由於URL無法識別特殊字符,如果數據中包含特殊字符,則要使用encodeURLcomponent()進行編碼

var url = 'test.php' +'?name='  + encodeURIComponent("小夢夢");
xhr.open('get',url,true);
  • 1
  • 2

上面的URL將會被編碼爲:

test.php?name=%E5%B0%8F%E6%A2%A6%E6%A2%A6
  • 1

【函數編碼】

下面這個函數可以向現有的URL的末尾添加查詢字符串的參數

function newParm(url,name,value){
    url+= (rul.indexOf('?')==-1 ? '?': '&');
    url +=encodeURIComponent(name) + "=" + encodeURIComponent(value);
    return url;
}
  • 1
  • 2
  • 3
  • 4
  • 5

  這個addURLParam()函數接受三個參數:要添加參數的URL、參數的名稱和參數的值。這個函數首先檢查URL是否包含問號(以確定是否已經有參數存在)。如果沒有,就添加一個問號;否則,就添加一個和號。然後,將參數名稱和值進行編碼,再添加到URL的末尾。最後返回添加參數之後的URL.

var url = 'test.php';
url = addURLParam(url,'name','aaa');
url = addURLParam(url,'data','bbb');

xhr.open('get',url,true);
  • 1
  • 2
  • 3
  • 4
  • 5

緩存

 在GET請求中,爲了避免緩存的影響,可以向URL添加一個隨機數或時間戳。 
 

xhr.open('GET',url + '&' + Number(new Date()),true);
xhr.open('GET',url + '&' + Math.random(),true);
  • 1
  • 2
這裏寫代碼片
  • 1

  下面把使用get方式發送ajax請求的操作封裝爲get()函數.

function get(url,data,callback){
    //創建xhr對象
    var xhr;
    if(window.XMLHttpRequest){
        xhr = new XMLHttpRequest();
    }else{
        xhr = new ActiveXObject('Microsoft.XMLHTTP');
    }
    //異步接受響應
    xhr.onreadystatechange = function(){
        if(xhr.readyState == 4){
            if(xhr.status == 200){
                //實際操作
                callback && callback(xhr.responseText);
            }
        }
    }
    for(var key in data){
        url += (url.indexOf("?") == -1 ? "?" : "&");
        //編碼特殊字符
        url += encodeURIComponent(key) + "=" + encodeURIComponent(data[key]);
    }
    //增加隨機數,防止緩存    
    xhr.open('get',url+'&'+Number(new Date()),true);
    //發送請求
    xhr.send();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
//前端
<script>
    get('form.php',{
    a:1,
    b:2,
    c:3
},function(data){
    //'a:1;b:2;c:3;'
    console.log(data);
})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
//後端
<?php
foreach($_GET as $key => $value){
    if(!empty($value)){
        echo $key. ":" .$value .";";        
    }
}
?> 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

POST

通常用於服務器發送應該被保存的數據,‘POST’常用與HTML表單,它在請求主題中包含額外數據且這些數據常存儲在服務器上數據庫中。相同的URL的重複POST請求從服務器上得到的響應可能不同,同時不應該緩存使用這個方法的請求。

POST請求應該把數據作爲一個請求的主體提交,而GET上不是這樣的,POST可以請求的主體可能包含非常多的數據。而且格式不限。在open()方法第一個參數的位置傳入”post”,就可以初始化一個POST請求。

xhr.open("post","example.php",true);
  • 1

【設置請求頭】

發送POST請求的第二部就是向send()中傳入某些數據,由於xhr的最初設計是主要爲了處理XML,因此可以在次傳入xml文檔,傳入的文檔進過序列化之後將作爲請求的主體提交到服務器,也可以在此傳入任何想發送到服務器的字符串。

在默認情況下服務器對POST請求和提交web表單的請求並不會一視同仁,因此服務器必須有相應的程序來讀取發送過來的數據,並從中解析出有用的部分。不過,可以使用XHR來模仿表單提交:首先將Content-Type頭部信息設置爲application/x-www-form-urlencoded,也就是表單提交時的內容類型.

xhr.setRequestHeader("content-type","application/x-www-form-urlencoded");
  • 1

  如果不設置Content-Type,發送給服務器的數據就不會出現在POSRPOSR超級全局變量中。這時要訪問同樣的數據,須藉助HTTP_RAW_POST_DATA. 
   
  如果對相同的頭調用多次setReQuestHeader(),新值不會取代之前指定的值。相反,HTTP請求將包含這個頭的多個副本或這個頭將指定多個值.

發送主體

  接下來要以適當的格式創建一個字符串,並使用send()方法發送

  POST數據的格式與查詢字符串格式相同,名和值之間用等號鏈接,名值對之間用和號(&)分隔,如下所示

xhr.send('name="aaa"&number=123');
  • 1

【編碼和緩存】

  由於使用POST方式傳遞數據時,需要設置請求頭”content-type”,這一步驟已經能夠自動對特殊字符(如中文)進行編碼,所以就不再需要使用encodeURIComponent()方法了

  POST請求主要用於數據提交,相同URL的重複POST請求從服務器得到的響應可能不同,所以不應該緩存使用POST方法的請求.

【性能】

  GET對所發送信息的數量有限制,一般在2000個字符。與GET請求相比,POST請求消耗的資源會更多一些。從性能角度來看,以發送相同的數據計,GET請求的速度最多可POST請求的兩倍.

【封裝函數】

function post(url,data,callback){
    //創建xhr對象
    var xhr;
    if(window.XMLHttpRequest){
        xhr = new XMLHttpRequest();
    }else{
        xhr = new ActiveXObject('Microsoft.XMLHTTP');
    }
    //異步接受響應
    xhr.onreadystatechange = function(){
        if(xhr.readyState == 4){
            if(xhr.status == 200){
                //實際操作
                callback && callback(xhr.responseText);
            }
        }
    }
    var strData = '';
    for(var key in data){
        strData += '&' + key + "=" + data[key];
    }
    strData = strData.substring(1); 
    xhr.open('post',url,true);
    //設置請求頭
    xhr.setRequestHeader("content-type","application/x-www-form-urlencoded");
    //發送請求
    xhr.send(strData);    
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
//前端
<script>
post('form.php',{
    a:1,
    b:2,
    c:3
},function(data){
    //'a:1;b:2;c:3;'
    console.log(data);
})
</script>   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
//後端
<?php
foreach($_POST as $key => $value){
    if(!empty($value)){
        echo $key. ":" .$value .";";        
    }
}
?>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章