【Web全棧課程5】本身封裝一個簡單的ajax

ajax

ajax內部怎麼實現的?

使用一個php文件來模擬服務器返回,php代碼以下javascript

<?php
echo $_GET['a']+$_GET['b'];
?>

請求的發送實際上咱們都經過瀏覽器的XMLHttpRequest實現,ie6使用ActiveXObject,不考慮IE6的兼容,咱們實現一個簡單的xhr請求以下。php

<html>
    <meta charset="utf-8">
    <head></head>
    <script>
        window.onload=function(){
            let oBtn=document.getElementById('btn1');
            oBtn.onclick = function(){
                let xhr=new XMLHttpRequest(); // 不兼容ie6
                // 鏈接,true表明異步,false表明同步;瀏覽器對異步的xhr會報錯
                xhr.open('get','../server/a.php',true,);
                // 發送;send裏面是body,post須要發送header
                xhr.send();
                // 接收;4表明結束
                xhr.onreadystatechange = function(){
                    console.log(xhr.readyState);
                };
            };
        };
    </script>
    <body>
        <input type="button" value="提交" id="btn1">
    </body>
</html>

xhr.readyState狀態值

0:剛剛建立初始狀態
1:已鏈接
2:已發送
3:已接受-頭(32k上限)
4:已接受-body(1G上限)

http狀態碼

1XX 消息
2XX 成功
3XX 重定向
    301 永久重定向——瀏覽器永遠不會再次請求老的地址
    302 臨時重定向——瀏覽器下次還會請求老地址
    304 (not modified)重定向到緩存請求——所以304也是成功
4XX 請求錯誤,客戶端錯誤
5XX 服務端錯誤
6XX 擴展錯誤碼

所以能夠經過2XX和304的狀態碼判斷請求成功。html

// 接收;4表明結束
    xhr.onreadystatechange = function(){
        if (xhr.readyState ==4){
            if ((xhr.status>=200&&xhr.status<300)||xhr.status==304){
                alert('成功:'+xhr.responseText);
                console.log(xhr);
            } else {
                alert('失敗');
            }
        }
    };

xhr返回值

xhr.responseText 文本數據
xhr.responseXML XML數據(已經不經常使用)java

xml數據是不固定標籤組成的數據,xml數據更加佔空間,例如:ajax

<person>
    <name>xiaoyezi</name>
    <age>18</age>
    <job>front engineer</job>
</person>

json格式:json

let json={name:'xiaoyezi',age:18,job:'front engineer'};

XMLHttpRequest發送POST請求

按照咱們上面代碼的思路,post請求的寫法推導出來應該是以下寫法,實際上以下寫法並不行瀏覽器

// 鏈接,true表明異步,false表明同步;瀏覽器對異步的xhr會報錯
xhr.open('post','../server/a.php',true,);

// 發送;send裏面是body,post須要發送
xhr.send('a=12&b=5');

對比form的post提交方式,咱們能夠看到,Request Headers裏面有條設置和form提交的不一樣:緩存

Content-Type: text/plain;charset=UTF-8
form提交:Content-Type: application/x-www-form-urlencoded

須要增長setRequestHeader的設置,再send請求的body內容,請求成功。服務器

xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
xhr.send('a=12&b=5');
content-type類型及含義?
text/plain 文本
application/x-www-form-urlencoded &&&鏈接的方式,eg:a=12&b=5
multippart/form-data 定界符分割各個數據(文件上傳)

實現簡單的自定義ajax

function ajax(options){
    // 數據處理
    options = options || {};
    options.data = options.data || {};
    options.type = options.type || 'get';
    options.dataType = options.dataType || 'text'; //解析數據

    let arr = [];
    for (let name in options.data) {
        arr.push(`${name}=${encodeURIComponent(options.data[name])}`);
    }
    let dataStr = arr.join('&');

    // 不兼容ie6
    let xhr=new XMLHttpRequest();

    // 鏈接,true表明異步,false表明同步;瀏覽器對異步的xhr會報錯
    if (options.type == 'get'){
        xhr.open('get',options.url + '?' + dataStr,true);
        xhr.send();
    } else {
        xhr.open('post',options.url,true,);

        // 發送;send裏面是body,post須要發送Content-Type
        xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
        xhr.send(dataStr);
    }

    // 接收;4表明結束
    xhr.onreadystatechange = function(){
        if (xhr.readyState ==4){
            if ((xhr.status>=200&&xhr.status<300)||xhr.status==304){
                let result = xhr.responseText;
                switch (options.dataType){
                    case 'text':
                        break;
                    case 'json':
                        if (window.JSON && JSON.parse){
                            result = JSON.parse(result);
                        } else {
                            result = eval("("+result+")");
                        }
                        break;
                    case 'xml':
                        result = xhr.XMLHttpRequest;
                        break;
                    default:
                        break;

                }
                options.success && options.success(result);
            } else {
                options.error && options.error('error');
            }
        }
    };
}
相關文章
相關標籤/搜索