ajax,axios,fetch

本文介绍了Ajax的工作原理,包括其在用户与服务器间添加中间层、异步请求的四个步骤。还对比了axios和fetch的特性,以及如何使用axios的请求/响应拦截器。最后,讨论了Fetch作为现代API与传统Ajax的不同之处。
摘要由CSDN通过智能技术生成

ajax

工作原理

Ajax的工作原理相当于在用户和服务器之间加了—个中间层(AJAX引擎),使用户操作与服务器响应异步化。并不是所有的用户请求都提交给服务器。像—些数据验证和数据处理等都交给Ajax引擎自己来做,,只有确定需要从服务器读取新数据时再由Ajax引擎代为向服务器提交请求。

ajax发请求四个步骤

创建xmlhttprequest对象

//第一步:创建XMLHttpRequest对象
 
var xmlHttp;
if (window.XMLHttpRequest) {            //非IE
    xmlHttp = new XMLHttpRequest();
} else if (window.ActiveXObject) {       //IE
    xmlHttp = new ActiveXObject("Microsoft.XMLHTTP")
}

设置请求方式


xmlHttp.open("POST", url, true);

设置回调函数

//第三步:注册回调函数
 
xmlHttp.onreadystatechange = function() {
    if (xmlHttp.readyState == 4) {
        if (xmlHttp.status == 200) {
            ......
        } else {
            ......
        }
    }
}

xmlHttp.readyState是存有XMLHttpRequest 的状态。从 0 到 4 发生变化。0: 请求未初始化。1: 服务器连接已建立。2: 请求已接收。3: 请求处理中。4: 请求已完成,且响应已就绪

具体状态码如下:
AJAX状态码说明
1**:请求收到,继续处理
2**:操作成功收到,分析、接受
3**:完成此请求必须进一步处理
4**:请求包含一个错误语法或不能完成
5**:服务器执行一个完全有效请求失败

再具体就如下:

100——客户必须继续发出请求
101——客户要求服务器根据请求转换HTTP协议版本
200——交易成功
201——提示知道新文件的URL
202——接受和处理、但处理未完成
203——返回信息不确定或不完整
204——请求收到,但返回信息为空
205——服务器完成了请求,用户代理必须复位当前已经浏览过的文件
206——服务器已经完成了部分用户的GET请求
300——请求的资源可在多处得到
301——删除请求数据
302——在其他地址发现了请求数据
303——建议客户访问其他URL或访问方式
304——客户端已经执行了GET,但文件未变化
305——请求的资源必须从服务器指定的地址得到
306——前一版本HTTP中使用的代码,现行版本中不再使用
307——申明请求的资源临时性删除
400——错误请求,如语法错误
401——请求授权失败
402——保留有效ChargeTo头响应
403——请求不允许
404——没有发现文件、查询或URl
405——用户在Request-Line字段定义的方法不允许
406——根据用户发送的Accept拖,请求资源不可访问
407——类似401,用户必须首先在代理服务器上得到授权
408——客户端没有在用户指定的饿时间内完成请求
409——对当前资源状态,请求不能完成
410——服务器上不再有此资源且无进一步的参考地址
411——服务器拒绝用户定义的Content-Length属性请求
412——一个或多个请求头字段在当前请求中错误
413——请求的资源大于服务器允许的大小
414——请求的资源URL长于服务器允许的长度
415——请求资源不支持请求项目格式
416——请求中包含Range请求头字段,在当前请求资源范围内没有range指示值,请求也不包含If-Range请求头字段
417——服务器不满足请求Expect头字段指定的期望值,如果是代理服务器,可能是下一级服务器不能满足请求
500——服务器产生内部错误
501——服务器不支持请求的函数
502——服务器暂时不可用,有时是为了防止发生系统过载
503——服务器过载或暂停维修
504——关口过载,服务器使用另一个关口或服务来响应用户,等待时间设定值较长
505——服务器不支持或拒绝支请求头中指定的HTTP版本

发送请求

xmlHttp.send(params)

自封装ajax

封装get方法

 let Aget={
            createXHR: function(){
                if(window.XMLHttpRequest){
                    return new XMLHttpRequest()
                }else{
                    return new ActiveXObject()
                }
            },
            get:function(url,data,callback,dataType){
                //避免dataType大小写
                let dataType = dataType.toLowerCase()
                if(data){
                    url+='?'
                    Object.keys(data).forEach(key => url+=`${key}=${data[key]}&`)
                    url=url.slice(0,-1)
                }

                let xhr=this.createXHR()
                //创建请求
                xhr.open('get',url)
                //发送请求
                xhr.send()
                xhr.onreadystatechange = function(){
                    if(xhr.readyState==4){
                        if(xhr.status>=200&&xhr.status<300||xhr.status==304){
                            let res = dataType=='json'? JSON.parse(xhr.responseText) : xhr.responseText

                            callback(res,xhr.status,xhr)
                        }
                    }
                }

            }
        }

封装post方法

 let Pget={
            createXHR: function(){
                if(window.XMLHttpRequest){
                    return new XMLHttpRequest()
                }else{
                    return new ActiveXObject()
                }
            },
            get:function(url,data,callback,dataType){
                //避免dataType大小写
                let dataType = dataType.toLowerCase()
                let xhr=this.createXHR()
                let str=''
                if(data){
                    Object.keys(data).forEach(key => str+=`${key}=${data[key]}&`)
                    str=str.slice(0,-1)
                }
                xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
                
                //发送请求
                xhr.send(str)
                xhr.onreadystatechange = function(){
                    if(xhr.readyState==4){
                        if(xhr.status>=200&&xhr.status<300||xhr.status==304){
                            let res = dataType=='json'? JSON.parse(xhr.responseText) : xhr.responseText

                            callback(res,xhr.status,xhr)
                        }
                    }
                }

            }
        }
       

封装请求

 let aj={
            createXHR: function(){
                if(window.XMLHttpRequest){
                    return new XMLHttpRequest()
                } else{
                    return new ActiveXObject()
                }
            },
            ajax:function(params){
                let type = params.type ? params.toLowerCase() :'get'
                let isAsync=params.isAsync? params.isAsync : 'true'
                let url=params.url
                let data= params.data ? params.data :{}
                let dataType = params.dataType.toLowerCase()

                let xhr=createXHR()

                let str=''
                Object.keys(data).forEach(key=>str+=`${key}=${data[key]}&`)
                if(type==='get') url+=`?${str}`
                return new Promise((resolve, reject) => {
                    xhr.open(type,url,isAsync)

                    if (type=='post'){
                        xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
                        xhr.send(str)
                    }else{
                        xhr.send()
                    }
                    xhr.onreadystatechange=function(){
                        if(xhr.readyState==4){
                            if(xhr.status==200&&xhr.status<300|| xhr.status==304){
                               let res=dataType==='json'? JSON.parse(responseText): responseText 
                               resolve(res)
                            }else{
                                reject(xhr.status)
                            }
                        }
                    }


                })
                

            }

        }

axios

axios 特性

基于promise的异步ajax请求库
浏览器端/node端都可以使用
支持请求/响应拦截器
支持请求取消
请求/响应数据转换
批量发送多个请求

如何用

const axios = require('axios');

// 向给定ID的用户发起请求
axios.get('/user?ID=12345')
  .then(function (response) {
    // 处理成功情况
    console.log(response);
  })
  .catch(function (error) {
    // 处理错误情况
    console.log(error);
  })
  .finally(function () {
    // 总是会执行
  });

// 上述请求也可以按以下方式完成(可选)
axios.get('/user', {
    params: {
      ID: 12345
    }
  })
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  })
  .finally(function () {
    // 总是会执行
  });  

// 支持async/await用法
async function getUser() {
  try {
    const response = await axios.get('/user?ID=12345');
    console.log(response);
  } catch (error) {
    console.error(error);
  }
}

配置拦截器

const instance = axios.create({
  baseURL: 'https://some-domain.com/api/',
  timeout: 1000,
  headers: {'X-Custom-Header': 'foobar'}
});
// 添加请求拦截器
axios.interceptors.request.use(function (config) {
    // 在发送请求之前做些什么
    return config;
  }, function (error) {
    // 对请求错误做些什么
    return Promise.reject(error);
  });

// 添加响应拦截器
axios.interceptors.response.use(function (response) {
    // 2xx 范围内的状态码都会触发该函数。
    // 对响应数据做点什么
    return response;
  }, function (error) {
    // 超出 2xx 范围的状态码都会触发该函数。
    // 对响应错误做点什么
    return Promise.reject(error);
  });

fetch

Fetch 是在 ES6 出现的,它使用了 ES6 提出的 promise 对象。它是 XMLHttpRequest 的替代品。
很多小伙伴会把它与 Ajax 作比较,其实这是不对的,我们通常所说的 Ajax 是指使用 XMLHttpRequest 实现的 Ajax,所以真正应该和 XMLHttpRequest 作比较。

Fetch 是一个 API,它是真实存在的,它是基于 promise 的。

特点:

使用 promise,不使用回调函数。
采用模块化设计,比如 rep、res 等对象分散开来,比较友好。
通过数据流对象处理数据,可以提高网站性能。

所以这里就和 Ajax 又很大不同了,一个是思想,一个是真实存在的 API,不过它们都是用来给网络请求服务的,我们一起来看看利用 Fetch 实现网络请求。

<body>
  <script>
    function ajaxFetch(url) {
      fetch(url).then(res => res.json()).then(data => {
        console.info(data)
      })
    }
    ajaxFetch('https://smallpig.site/api/category/getCategory')
  </script>
</body>


三者区别

在这里插入图片描述

在这里插入图片描述

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值