原生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 () {
                }
            });
        }
    };
原生ajax解析&封装原生ajax函数的更多相关文章
- 原生ajax与封装的ajax使用方法
		当我们不会写后端接口来测试ajax时,我们可以使用node环境创建一个本地服务器. 1.创建一个本地服务器可参考http://www.cnblogs.com/heyujun-/p/6793900.ht ... 
- js实现原生Ajax的封装及ajax原理详解
		原理及概念 AJAX即“Asynchronous Javascript And XML”(异步JavaScript和XML),是一种用于创建快速动态网页的技术. 动态网页:是指可以通过服务器语言结合数 ... 
- Ajax的封装,以及利用jquery的ajax获取天气预报
		1.Ajax的封装 function ajax(type,url,param,sync,datetype,callback){//第一个参数是获取数据的类型,第二个参数是传入open的url,第三个是 ... 
- 原生实现ajax解析--XMLHttpRequest
		ajax基础: Asynchronous JavaScript and XML,意思就是用JavaScript执行异步网络请求. 如果仔细观察一个Form的提交,你就会发现,一旦用户点击“Submit ... 
- js原生Ajax 的封装和原理
		原理及概念 AJAX即“Asynchronous Javascript And XML”(异步JavaScript和XML),是一种用于创建快速动态网页的技术. 动态网页:是指可以通过服务器语言结合数 ... 
- 原生封装的ajax
		原生封装的ajax的代码如下: //将数据转换成 a=1&b=2格式; function json2url(json){ var arr = []; //加随机数防止缓存; json.t = ... 
- js原生Ajax的封装与使用
		一.原生Ajax代码的封装如下: (function() { var XHR = { createStandardXHR: function() { return new XMLHttpRequest ... 
- JavaScript的原生Ajax解析
		通过JavaScript的Ajax进行详细的解析过程,从而更好的了解Jquery的Ajax. 顺带,我会在后面把我整理的一整套CSS3,PHP,MYSQL的开发的笔记打包放到百度云,有需要可以直接去百 ... 
- javascript - 封装原生js实现ajax
		1 /* * ajax方法 */ var Ajax = function() { var that = this; //创建异步请求对象方法 that.createXHR = function() { ... 
随机推荐
- OpenShift 4.2环境离线部署Operatorhub
			缺省离线环境安装的ocp4的Operatorhub是没有内容的.详细离线文档参考官网文档 https://docs.openshift.com/container-platform/4.2/opera ... 
- vue-cli3项目关闭烦人的代码检测
			参考博客:https://blog.csdn.net/e1172090224/article/details/99636767 vue.config.js module.exports = { lin ... 
- windows下ffmpeg批量转码
			以mp4转mp3为例 for %%i in (*.mp4) do ffmpeg -i "%%i" "%%i.mp3" 将当前文件夹下的mp4文件全部转码为mp3 
- springboot踩坑记
			1. @ConditionalOnProperty 根据配置加载不同的 bean 场景:对 redis 配置进行封装,实现自动化配置,能兼容哨兵模式和集群模式.想到在 redis 配置中加一个 red ... 
- Spring、SpringMVC、Spring Boot、Spring Cloud 概念、关系及区别
			注:此文章转载于其他大神 一.正面解读: Spring主要是基于IOC反转Beans管理Bean类,主要依存于SSH框架(Struts+Spring+Hibernate)这个MVC框架,所以定位很明确 ... 
- Laravel实现from的curl文件转发
			文件的使用curl分发时发现不能直接将其传入curl,需要使用CURLFile()来实现 分发类 <?php /** * 请求转发控制器 * Created by PhpStorm. * Use ... 
- [数据结构 - 第6章] 树之二叉排序树(C语言实现)
			一.什么是二叉排序树? 对于普通的顺序存储来说,插入.删除操作很简便,效率高:而这样的表由于无序造成查找的效率很低. 对于有序线性表来说(顺序存储的),查找可用折半.插值.斐波那契等查找算法实现,效率 ... 
- MD5用户密码加密工具类  MD5Util
			一般记录用户密码,我们都是通过MD5加密配置的形式.这里记录一下,MD5加密的工具类. package com.mms.utils; import java.security.MessageDiges ... 
- PyGSP
			PyGSP # PyGSP (0.5.1) # matplotlib (3.1.2) # networkx (2.4) # numpy (1.17.4) from pygsp import graph ... 
- 【转帖】Intel AMD 龙芯2019年12月份最新产品线
			Intel未来三代U集体曝光:14nm退回去了! https://news.cnblogs.com/n/651244/ 不过没搞懂 为啥中芯国际已经开始量产14nm了 龙芯为什么不用.. 3A4000 ... 
