zoukankan      html  css  js  c++  java
  • 原生ajax解析&封装原生ajax函数

      前沿:对于此篇随笔,完是简要写了几个重要的地方,具体实现细节完在提供的源码做了笔记

    <一>ajax基本要点介绍--更好的介绍ajax

    1. ajax对象中new XMLHttpRequest()属性和方法列表

    2. 常用事件介绍

    事件触发时机
    onreadystatechange 当readyState的值改变时触发,除了当它从非0变成0时
    onloadstart 当调用send方法时会触发xhr.onloadstart,然后会触发xhr.upload.onloadstart,代表开始上传数据
    onprogress 上传数据过程中会触发xhr.upload.onprogress,下载数据过程中会触发xhr.onprogress,onprogress每50ms会触发一次
    onabort 调用abort方法后会触发
    onerror 当发生网络异常的时候会触发,如果上传数据的过程还未结束,此时会先触发xhr.upload.onerror,然后再触发xhr.onerror;如果上传数据的过程已经结束,此时只会触发xhr.onerror
    onload 上传数据成功,会触发xhr.upload.onload;下载数据成功会触发xhr.onload
    ontimeout 当服务端响应的时间超过指定的timeout时间时,会触发此事件
    onloadend 上传数据完成(成功或者失败)时会触发xhr.upload.onloadend;下载数据完成(成功或失败)会触发

    3. 请求开始和结束零界点

    【3.1】请求开始

      xhr.onloadstart事件触发的时候,也就是你调用xhr.send()方法的时候。
    因为xhr.open()只是创建了一个连接,但并没有真正开始数据的传输,而xhr.send()才是真正开始了数据的传输过程。只有调用了xhr.send(),才会触发xhr.onloadstart 。

    【3.2】请求结束

      xhr.loadend事件触发的时候

    备注:

      a.可以在 send()之后再设置此xhr.timeout,但计时起始点仍为调用xhr.send()方法的时刻。

      b.当xhr为一个sync同步请求时,xhr.timeout必须置为0,否则会抛错。原因可以参考本文的【如何发一个同步请求】一节。

    4. 具体实现细节--封装ajax

    function _ajax(obj){
        var xhr = null;
        // 创建-非IE6 : IE6及其以下浏览器
        if(window.XMLHttpRequest){
            xhr=new XMLHttpRequest();
            //针对某些特定版本的Mozillar浏览器的BUG进行修正
            if(xhr.overrideMimeType) {
                xhr.overrideMimeType("text/xml");
            }
        }else if(window.ActiveXObject){
            var arr = ['MSXML2.XMLHTTP', 'Microsoft.XMLHTTP'];
            for(var i = 0; i < arr.length; i++){
                try {
                    xhr = new ActiveXObject(arr[i]);
                    break;
                }catch (e){
                    console.log(e);
                }
            }
        }
    
        // 默认是异步请求
        var asyc = obj.asyc || true;
        var type = obj.type.toUpperCase() || "GET";
        var url = obj.url;
        var data = obj.data || {};
    
        console.log(objToStr(data));
    
        //选择发送请求方式
        if(type === "GET"){
            xhr.open(type,url+'?'+objToStr(data),asyc);
            xhr.send();
        }else if(type === "POST"){
            xhr.open(type,url,asyc);
            // 告诉后台传的是什么
            xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
            // xhr.setRequestHeader('Last-Modified', 'faqenfaAWASVaewfc');
            xhr.send(objToStr(data));
        }
    
        // 设置超时请求时间
        xhr.timeout = 3000;
    
        // 发送异步回调函数
        xhr.onreadystatechange = function () {
            console.log(xhr.readyState);
            // 测试追踪ajax处于那种状态,在正式代码中要隐藏此switch
            switch (xhr.readyState){
                case 0:
                    console.log('xhr对象被成功构造,open()方法还未被调用');
                    break;
                case 1:
                    console.log('open()方法已被成功调用,send()方法还未被调用');
                    break;
                case 2:
                    console.log('send()方法已经被调用, 响应头和响应状态已经返回');
                    break;
                case 3:
                    console.log('响应体(response entity body)正在下载中,此状态下通过xhr.response可能已经有了响应数据');
                    break;
                case 4:
                    console.log('整个数据传输过程结束,不管本次请求是成功还是失败');
                    break;
            }
    
            if(xhr.readyState === 4 && xhr.status === 200){
                obj.success(xhr.responseText)
            }else {
                obj.error && obj.error();
            }
        };
    
        // 请求开始
        xhr.onloadstart = function (e) {
            console.log(e,'start');
        };
    
        //ajax请求结束
        xhr.loadend = function (e) {
            console.log(e,'end');
        };
    
        // 超时函数处理
        xhr.ontimeout = function (e) {
            obj.timeout && obj.timeout();
            console.log(e,'timeout');
        };
    
        // ajax请求错误处理
        xhr.onerror = function (e) {
            obj.errorAsyc && obj.errorAsyc();
            console.log(e,'error');
        };
    
        // 上传进度处理--upload用于在数据传输到服务器时收集一些传输信息,比如上传了多少字节,总共多少字节等,其里面还包含了一些事件回调
        xhr.upload.onprogress = function (e) {
            obj.progress && obj.progress();
            console.log(e,'progress');
        };
    
        console.log(xhr.getAllResponseHeaders(),'0000');
        // 把对象转换成字符串
        function objToStr(obj) {
            var arr = [];
            for(var key in obj){
                arr.push(key+'='+obj[key])
            }
            return arr.join('&');
        }
    }

    【封装ajax调用方式】

       window.onload = function () {
            btn.onclick= function () {
                _ajax({
                    url:'http://localhost:8800',
                    type:'post',
                    asyc:true, //默认是true
                    data:{
                        username:'zhange',
                        password:'123456'
                    },
                    success:function (data) {
                        console.log(data);
                    },
                    error:function () {
    
                    }
                });
            }
        };
  • 相关阅读:
    每日日报
    每日日报
    JAVA日报
    JAVA日报
    JAVA日报
    JAVA日报
    NavigationDuplicated {_name: "NavigationDuplicated", name: "NavigationDuplicated"}
    2020.11.07
    2020.11.05
    2020.11.09
  • 原文地址:https://www.cnblogs.com/yyy6/p/8252342.html
Copyright © 2011-2022 走看看