手写ajax

axios

客户端 请求 服务端

  • 请求行

    url

    请求方式

  • 多个请求头

    域名,cooike,content-Type等

  • 请求体

post方法传的参数

服务端 响应 客户端

  • 响应行

    status statusText

  • 多个响应头

    Content-Type:text/html

  • 响应体

    数据返回

XHR

XMLHttpRequest对象可以和服务器交互 不会刷新网页

只有XHR和fetch发出的才是ajax请求

一般的请求就类似跳转和刷新页面

ajax只是调用监视回调函数并传入响应相关的数据

API

XMLHttpRequest() //创建XHR对象的构造函数

status:响应状态码

statusText:响应状态文本

onreadystatechange:绑定readyState改变的监听

open(method,url):初始化请求

send(data):发送请求

abort():中断请求



手写实现ajax

<script>
    
    //接口在本地node.js实现
      function getdata()
    {
        console.log('发送get请求');
        ajax({
            url:'http://localhost:3000/getposition',
            parmas:{
               
            name:'fanfan',
            age:19,
            number:13142278876
            }
        }).then(res=>{
            console.log(res);
        })
    }

    
    //ajax手写实现
     
    function ajax({
        //解构赋值  写好默认值
        url,
        method='GET',
        data={},
        parmas={},
    }){
        //返回promise对象
         return new Promise( (resolve,reject)=>{
       
         //对url的处理  有些get请求参数需要拼接另外函数实现拼接
            url+='?'+pinjie(parmas)
    
             //创建xhr对象
             const request=new XMLHttpRequest()
            //打开连接
             request.open(method,url,true) 
            //转换为JSON对象 
            if(method=='GET')
            {
                request.send()
            }
           else if(method=='post')
           {
          
           //发送JSON格式的对象肯定要加请求头 告诉服务器请求体是JSON格式
            request.setRequestHeader('Content-Type','application/json;charset=uft-8')
            //转换为JSON发送
            request.send(JSON.stringify(data))
           }
    
           //绑定状态改变的监听 从发送变为成功或者失败调用的函数
           request.onreadystatechange=function(){
                //进入判断 如果请求没有完成 直接结束
                if(request.readyState!==4)
                {
                    return 
                }
                //如果响应状态码在 200~299为成功
                const {status,statusText} =request
                //自己加的属性
                let author='fanfan'
                
                if(status>=200&&status<=299)
                {
                    //准备结果对象response 的其中几条
                    const response={
                        //对应返回的数据可以知道这些东西是什么
                        data:JSON.parse(request.response),
                        status,
                        statusText,
                        //自己添加的属性
                        author
                      
                    }
                    resolve(response)
                }else{
                    //请求失败返回message信息和状态码
                    reject(new Error('requset error status is '+status))
                }
           }
              
         })
    }

    //拼接参数 for-in解决
    function pinjie(obj)
    {
        let  queryString=''
        for(let k in obj)
        {
            queryString+= k+'='+obj[k]+'&'
        }
        //判断有没有值
        if(queryString)
        {
            queryString=queryString.slice(0,queryString.length-1)
        }
        //拼接到url上面
       return  queryString
    }
    
    
</script>




实现结果

axios特点

  • 基本promise的异步ajax请求库

  • 浏览器和node都可以使用

  • 支持请求/响应数据转换

  • 支持请求取消

多个请求/响应拦截器 (洋葱模型)

请求拦截器 先添加后执行 响应拦截器 先添加先执行

 //添加请求拦截器
    axios.interceptors.request.use(
        config=>{
            console.log('request interceptor1');
            return config
        },
        error=>{
            return Promise.reject(error)
        }
    )

     //添加请求拦截器
     axios.interceptors.request.use(
        config=>{
            console.log('request interceptor2');
            return config
        },
        error=>{
            return Promise.reject(error)
        }
    )
    //添加响应拦截器
    axios.interceptors.response.use(
        response=>{
            console.log('response interceptor1');
            return response
        },error=>{
            return Promise.reject(error)
        }
    )
      //添加响应拦截器
      axios.interceptors.response.use(
        response=>{
            console.log('response interceptor2');
            return response
        },error=>{
            return Promise.reject(error)
        }
    )


 //config 就是传的配置文件 不返回的话就传不过去

//response return的结果会给下一个响应拦截器 最后执行.then(res) 将数据传给res


/*request interceptor2
request interceptor1
response interceptor1
response interceptor2*/