Ajax原理及封装

662 阅读2分钟

Ajax原理

第一步:创建XMLHTTPRequest对象

  var xhr = new XMLHttpRequest();

第二步:配置 xhr 对象

xhr.open("请求方式" , "请求地址");

第三步:发送请求

xhr.send( null );

第四步:响应接收

 xhr.onreadystatechange = function(){
 // console.log(1);
       // 只要判定成功状态即可,成功的状态码为4
       if( xhr.readyState === 4){
       	   console.log("数据请求成功");
           // 取出相应数据;
           console.log(xhr.responseText)
       }
   }

GET 请求

数据发送是在地址栏里进行拼接

  var xhr = new XMLHttpRequest();
      xhr.open("GET" , "./03_data.php");
       xhr.send( null );
       xhr.onreadystatechange = function(){
           if( xhr.readyState === 4){
               console.log(xhr.responseText)
           }

PHP数据交互代码

<?php

    $username = $_REQUEST["username"];
    $password = $_REQUEST["password"];
    echo "用户名是: $username , 密码是 :$password";
?>

POST请求

数据是放在send之中,由send放入请求体之中带到后端去。

var data = {
    a : 10,
    b : 20
}
var xhr = new XMLHttpRequest();
xhr.open("POST","./02_data.php");
xhr.setRequestHeader('content-type', 'application/x-www-form-urlencoded');
xhr.send("a=10&b=20");
xhr.onload = function(){
    console.log( xhr.responseText );
}

PHP数据交互代码

<?php
    $a = $_POST["a"];
    $b = $_POST["b"];

    echo "$a , $b";
?>

仿照JQuery对Ajax进行封装

完整代码

   function ajax( options ){
        var _default = {
            type : "GET",
            url : "",
            data : null,
            dataType : "text",
            status : null,
            success : function(){},
            complete : function(){},
            error : function(){}
        }
        options = assign( _default , options );
        options.type = options.type.toLowerCase();
        if( isObject(options.context) ){
            var callback_list = ["success","complete","error"];
            callback_list.forEach( function( item ){
                // console.log(options[item]);
                options[item] = options[item].bind( options.context );
            })
        }
        
        // 1. 创建shr ;
        var xhr = null;
        if(typeof XMLHttpRequest === "function"){
            xhr = new XMLHttpRequest();
        }else{
            xhr = new ActiveXObject("Microsoft.XMLHTTP");
        }
        // 1. 如果请求方式为get,那么我们把数据拼接到url上;
        if(options.type === "get"){
            options.url =  toUrlData( options.data , options.url , options.type)
        }
        // 2. 如果请求方式为post,那么我们把数据拼接到data上;
        if(options.type === "post"){
            options.data =  toUrlData( options.data , options.url , options.type)
        }
        // 3. 根据数据进行方法的调用;
        xhr.open( options.type , options.url , true ) ;
        options.type === "post" ? xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded") : "";
        // 4. 调用send方法;
        xhr.send( options.type=== "get" ? null : options.data );
        // 5. 调用回调函数;
        xhr.onreadystatechange = function(){
            if( xhr.readyState === 4 ){
                options.complete();
                if( /^2\d{2}$/.test(xhr.status) ){
                    // 6.传递数据
                    try{
                        var res = options.dataType === "json" ? JSON.parse(xhr.responseText) : xhr.responseText; 
                        options.success(res);
                    }catch(e){
                        options.error(e,xhr.status);
                    }
                }else{
                    options.error("error",xhr.status);
                }
                // 策略模式调用 : 
                if( isObject(options.status) ){
                    typeof options.status[xhr.status] === "function" ? options.status[xhr.status]() : "";
                }
            }
        }
    }
    var options = {
        url : "./02_data.php",
        // dataType : "json",
        data : {
            a : 1, 
            b : 2
        },
        type : "post",
        success : function(res){
            console.log(res , this);
        },
        error : function(res){
            console.log("失败",res);
        },
        complete : function(){
            console.log("完成");
        },
        context : { c : 1 },
        status : {
            200 : function(){
                console.log("我的状态码是200,非常正常");
            },
            404 : function(){
                console.log("我找不到页面了")
            }
        }
    }
    ajax( options )
    function assign(){
        var target = arguments[0];
        for(var i = 1 ; i < arguments.length ; i ++){
            // console.log(arguments[i]);
            for(var attr in arguments[i]){
                target[attr] = arguments[i][attr];
            }
        }
        return target;
    }

    function toUrlData( obj , url , method){
        if( isObject(obj) ){
            var str = "";
            for(var attr in obj){
                str += "&" + attr + "=" + obj[attr]
            }
            str = str.slice(1);
            method = method || "";
            if( method.toUpperCase() === "POST"){
                return str;
            }
            url += "?" + str;
            return url;
        }
        return url;
    }
    function isObject( data ){
        return (typeof data === "object" && data !== null && data.constructor && data.constructor === Object)
    }