Ajax Promise Axios

记录一些前端知识

Ajax

Ajax : Asynchronous·+ XML缩写,能够向服务器额外请求数据而不须卸载页面。Ajax的核心为XMLHttpRequest(XHR)

创建一个xhr对象

因为IE5是第一款引入XHR对象的浏览器,在IE5中,XHR是通过MSXML库中的ActiveX对象实现的,所以在IE浏览器中,XHR有三个不同的版本:MSXML2.XMLHttp、MSXML2.XMLHttp.3.0、MSXML2.XMLHttp.6.0
复制代码
//对于IE7版本之前
function createXHR(){
    if(typeof agruments.callee.activeXString!='string'){
        var versions = ["MSXML2.XMLHttp","MSXML2.XMLHttp.3.0","MSXML2.XMLHttp.6.0"],i,len;
        for(i=0;len = versions.length;itry{
                new ActiveXObject(versions[i])
                agruments.callee.activeXString = version[i];
            }catch(ex){
                
            }
        }
    }
    return new ActiveXObject(agruments.callee.activeXString);
}
//对于IE7+、Firefox、Opera、Chrome、Safari支持原生的XHR对象
var xhr = new XMLHttpRequest();
复制代码

总结上面情况

function createXHR(){
    if(typeof XMLHttpRequest!='undefined'){
        return new XMLHttpRequest();
    }else if(typeof ActiveXObject!='undefined'){
        if(typeof agruments.callee.activeXString!='string'){
            var versions = ["MSXML2.XMLHttp","MSXML2.XMLHttp.3.0","MSXML2.XMLHttp.6.0"],i,len;
        for(i=0;len = versions.length;itry{
                new ActiveXObject(versions[i])
                agruments.callee.activeXString = version[i];
            }catch(ex){
                
            }
        }
    }
    return new ActiveXObject(agruments.callee.activeXString);
    }else{
        throw new Error("No XHR object available");
    }
}
var xhr = createXHR();
复制代码

XHR的用法

(1)open():接受三个参数:请求类型,请求url,是否异步发送请求的布尔值。

//调用open不会发送请求,只是启动了一个请求以备发送
xhr.open("get",url,false);
复制代码
  • GET:用于获取资源
  • HEAD:与get方法类似,但是不返回message body 内容,返回HTTP头信息
  • POST:向服务器提交数据
  • DELETE:删除资源
  • PUT:与POST相似,但是PUT指定资源存放位置,但是POST由服务器自己决定
  • OPTIONS:用于获取当前URL所支持的方法。若请求成功,则它会在HTTP头中包含一个名为“Allow”的头,值是所支持的方法,如“GET, POST”

(2)send():接受一个参数,作为请求主体发送的数据,如果不需要,则必须传入null。调用send后请求会分派到服务器

(3)readyState:表示请求/响应过程的当前活动阶段

0 :未初始化,没有调用open()方法
1 :启动,调用open()方法,没有调用send()
2 :发送,调用send,但没有收到响应
3 :接收,收到部分响应数据
4 :完成,接收全部响应数据,而且可以在客户端使用
复制代码

(4)onreadystatechange():因为readyState属性值由一个变成另外一个值,都会触发onreadystatechange,可以利用该事件检验readyState的值,必须在open()之前使用

var xhr = createXHR();
xhr.onreadystatechange = function(){
    if(xhr.readyState ==4){
        if((xhr.status>=200&&xhr.status<300)||xhr.status==304){
            console.log(xhr.reponseText)
        }else{
            console.log("Request was unsuccessful: "+xhr.status);
        }
    }
}
xhr.open("get",url,true);
xhr.send(null);
复制代码

在浏览器收到服务器响应后,响应数据会自动填充到XHR对象的属性中:

  • responseText :作为响应主体被返回的文本
  • responseXML:如果响应的内容类型是“text/xml”或“application/xml”,这个属性中将保存包含着响应数据的XML DOM文档
  • status:响应的HTTP状态
  • statusText:HTTP状态的说明》

(4) Http头部信息

  • accept:浏览器能够处理的内容类型
  • accept-charset:浏览器能够显示的字符集
  • accept-encoding:浏览器能够处理的压缩编码
  • accept-language:浏览器当前设置的语言
  • connection:浏览器与服务器之间连接的类型
  • cookie:当前页面设置的任何cookie
  • host:发送请求的页面所在的域
  • referer:发送请求的页面的url
  • user-agent:浏览器的用户代理字符串

使用sendRequestHeader()方法可以设置自定义的请求头部信息,但是必须在open之后send之前使用

xhr.open("get",url,true);
xhr.sendRequestHeader("Content-Type","application/x-www-form-unlecoded");
xhr.send(null);
复制代码

(5)超时设定 timeout

xhr.open("get",url,true);
xhr.sendRequestHeader("Content-Type","application/x-www-form-unlecoded");
xhr.timeout = 1000;
xhr.send(null);
复制代码

优点: 1.无刷新更新数据 2.异步与服务器通信 3.前后端负载平衡

缺点:1.AJAX干掉了Back和History功能,即对浏览器机制的破坏。 2.AJAX的安全问题。

$.ajax

该方法是 jQuery 底层 AJAX 实现。简单易用的高层实现见 $.get, $.post 等。$.ajax() 返回其创建的 XMLHttpRequest 对象。

jQuery.ajax([settings]) 参数:

  • url: 发送请求的地址
  • async 默认值true,为异步请求
  • beforeSend(XHR):Function 发送请求前可修改 XMLHttpRequest 对象的函数,如添加自定义 HTTP 头。如果返回 false 可以取消本次 ajax 请求
  • cache:默认值: true,dataType 为 script 和 jsonp 时默认为 false。设置为 false 将不缓存此页面。
  • contentType:默认值: "application/x-www-form-urlencoded"。发送信息至服务器时内容编码类型。
  • context:这个对象用于设置 Ajax 相关回调函数的上下文。让回调函数内 this 指向这个对象
$.ajax({ url: "test.html", context: document.body, success: function(){
        $(this).addClass("done");
      }})
复制代码
  • data:发送到服务器的数据。将自动转换为请求字符串格式
  • error:请求失败时调用此函数
  • success:请求成功后的回调函数
$.ajax({
             type: "GET",
             url: "test.json",
             data:data,
             dataType: "json",
             success: function(data){},
             error:function(err){}
         });
复制代码

Promise

Promise解决回调地狱问题。

Promise的用法

let promise = new Promise((resolve,reject)=>{
    setTimeout(()=>{
        let rand = Math.random();
        if(rand>0.3){
            resolve("大于0.3: "+rand)
        }else{
            reject("小于0.3: "+rand)
        }
    },1000)
})
复制代码

利用构造函数模式创建一个对象,即promise._proto_ == Promise.prototype为true。

Promise构造函数接收一个函数作为参数,该函数接受两个各位的函数resolve,reject为参数。这两个函数分别代表将当前Promise置为fulfilled(解决)和rejected(拒绝)两个状态。

promise只是Promise的一个实例对象,在声明的时候并不会立即执行,而每一个Promise的实例对象都有一个then方法,这个方法就是用来处理之前的异步逻辑的结果。

promise.then(resolve=>{
console.log(resolve)
},reject=>{
    console.log(reject)
})
复制代码

then方法也有两个参数,第一个调用resolve函数,第二个调用reject函, 并且Promise的then()方法,then总是会返回一个Promise实例,由此可以一直then().then()...

catch

这个方法其实是then方法的一种特例.then(null, rejection)相当于我们不使用then方法的第一个函数,只是用第二个函数;catch函数比较简单,就是用来捕获之前的then方法里面的异常

var promise = new Promise((res,rej)=>{
    rej("error123456")
});
promise.then(()=>{
    consoel.log(123)
}).catch((err)=>{
    console.log(err)
})
//运行结果error123456
复制代码

Promise.all

Promise.all可以将多个Promise实例包装成一个新的Promise实例。成功的时候返回的是一个结果数组,而失败的时候则返回最先被reject失败状态的值

let p1 = new Promise((res,rej)=>{
    res("success 1");
})
let p2 = new Promise((res,rej)=>{
    res("success 2");
})
let p3 = new Promise((res,rej)=>{
    rej("error");
})

//["success 1", "success 2"]
Promise.all([p1,p2]).then(success=>{
    console.log(success)
}).catch(err=>{
     console.log(err)
})

//["success 1", undefined]
Promise.all([p1,p2.p3]).then(success=>{
    console.log(success)
}).catch(err=>{
     console.log(err)
})

//error
Promise.all([p1,p3,p2]).then((result) => {
  console.log(result)
}).catch((error) => {
  console.log(error)      // 失败了,打出 '失败'
})
复制代码

Promise.race

赛跑,哪个Promise实例获取结果结果快就返回哪个,不管结果本身是成功状态还是失败状态

let p1 = new Promise((res,rej)=>{
    setTimeout(()=>{
        res("success 1");
    },500)
})
let p2 = new Promise((res,rej)=>{
    setTimeout(()=>{
        res("success 2");
    },1000)
})
//success 1
Promise.race([p1,p2]).then((result) => {
  console.log(result)
}).catch((error) => {
  console.log(error)      // 失败了,打出 '失败'
})
复制代码

一个简单的promise的实现

juejin.im/post/5aa786…

ajax+promise

function request(
    url: String = "",
    method: String = "GET",
    data: Object = null,
    async: Boolean = true,
    headers: Object = {
        'content-type': 'application/x-www-form-urlencoded'
    }) {
    let xhr = new XMLHttpRequest();
    method = method.toUpperCase();
    xhr.open(method, url, async);
    for (let header in headers) {
        xhr.setRequestHeader(header, headers[header])
    }
    xhr.send(method === "GET" ? null : JSON.stringify(data));
    return new Promise((resolve, reject) => {
        xhr.onreadystatechange = function () {
            if (this.readyState === 4) {
                if (this.status === 200) {
                    resolve(JSON.parse(this.responseText), this)
                } else {
                    let resJson = {code: this.status, response: this.response}
                    reject(resJson, this)
                }
            }
        };
    })
}
复制代码

Axios

Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。

使用方法

//get
axios.get('/user?ID=12345')
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });
  
  //post
  axios.post('/user', {
    firstName: 'Fred',
    lastName: 'Flintstone'
  })
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });
复制代码

axios + promise

import axios from "axios";

let cancel;
const CancelToken = axios.CancelToken;
//请求拦截器
axios.interceptors.request.use(config => {
//一些操作
    return config
}, error => {
    return Promise.reject(error)
})

//响应拦截器即异常处理
axios.interceptors.response.use(response => {
    return response
}, err => {
    //...一些操作
    return Promise.resolve(err.response)
})
axios.defaults.baseURL = 'XXX'
//设置默认请求头
axios.defaults.headers = {
    'X-Requested-With': 'XMLHttpRequest'
}
axios.defaults.timeout = 10000
export default {
    //get请求
    get(url, param) {
        return new Promise((resolve, reject) => {
            axios({
                method: 'get',
                url,
                params: param,
                cancelToken: new CancelToken(c => {
                    cancel = c
                })
            }).then(res => {
                //可以根据后端返回status做resolve还是reject
                resolve(res)
            })
        })
    },
    //post请求
    post(url, param) {
        return new Promise((resolve, reject) => {
            axios({
                method: 'post',
                url,
                data: param,
                cancelToken: new CancelToken(c => {
                    cancel = c
                })
            }).then(res => {
                resolve(res)
            })
        })
    }
}

复制代码

你可能感兴趣的:(Ajax Promise Axios)