十八、ajax,fetch,axios

83 阅读5分钟

1. ajax

1.1 什么是ajax

  • Asynchronous Javascript And XML(异步 JavaScript 和 XML)。
  • 浏览器和服务器的一种 通信 技术
  • 可以访问服务器数据局部刷新

【补充】 xml 可扩展标记语言(重量级的数据格式)

① 网络传输 ② 配置文件

1.2 ajax的核心对象:XMLHttpRequest

1.3 ajax函数的封装

1.3.1 get同步不传参的ajax封装
  • 缺点:同步会造成阻塞

      1. 封装一个创建xhr的方法
      function createXhr(){
          if(window.XMLHttpRequest){
              return new XMLHttpRequest(); // 谷歌火狐
          }
          return new ActiveXObject("Msxml2.HTTP"); //ms微软  ie
      }
      
      2. get同步不带参的ajax封装
      function get(url){
          // 2.1 创建一个xhr
          var xhr = createXhr();
          // 2.2 调用open方法,准备数据  
          //     参数:请求方式,请求路径,同步/异步(true异步false同步,默认是true异步)
          xhr.open("get",url,false);
          // 2.3 调用send方法,发送请求
          xhr.send(null);
          // 2.4 判断并接收数据
          if(xhr.status==200){
              return xhr.response;
          }
      }
    
1.3.2 post同步不传参的ajax封装
  • 缺点:同步会造成阻塞

      1. 封装一个创建xhr的方法
      function createXhr(){
          if(window.XMLHttpRequest){
              return new XMLHttpRequest();
          }
          return new ActiveXObject("Msxml2.HTTP");
      }
      
      2. post同步不带参的ajax封装
      function post(url){
          // 2.1 创建一个xhr
          var xhr = createXhr();
          // 2.2 调用open方法,准备数据  
          //     参数:请求方式,请求路径,同步/异步(true异步false同步,默认是true异步)
          xhr.open("post",url,false);
          // 2.3 调用send方法,发送请求
          xhr.send(null);
          // 2.4 判断并接收数据
          if(xhr.status==200){
              return xhr.response;
          }
      }
    
1.3.3 get异步不传参的ajax封装 ---> 回调函数解决异步
  • ajax异步:onreadystatechange事件 + callback获取数据

      1. 封装一个创建xhr的方法
      function createXhr(){
          if(window.XMLHttpRequest){
              return new XMLHttpRequest();
          }
          return new ActiveXObject("Msxml2.HTTP");
      }
      
      2. get异步不传参的ajax封装
      function get(url,callback){
          var xhr = createXhr();
          xhr.open("get",url); //默认异步
          xhr.send(null);
          // onreadystatechange事件在响应数据回来时会自动触发
          // xhr.status==200指http协议状态码
          // xhr.readyState==4指xhr的响应码
          xhr.onreadystatechange=function(){
              if(xhr.status==200&&xhr.readyState==4){
                  if(callback){
                      callback(xhr.response);
                  }
              }
          }
      }
    

QQ图片20230424213037.jpg

QQ图片20230424213044.jpg

1.3.4 post异步不传参的ajax封装 ---> 回调函数解决异步
  • ajax异步:onreadystatechange事件 + callback获取数据

      1. 封装一个创建xhr的方法
      function createXhr(){
          if(window.XMLHttpRequest){
              return new XMLHttpRequest();
          }
          return new ActiveXObject("Msxml2.HTTP");
      }
      
     2. post异步不传参的ajax封装
      function post(url,callback){
          var xhr = createXhr();
          xhr.open("post",url); //默认异步
          xhr.send(null);
          // onreadystatechange事件在响应数据回来时会自动触发
          // xhr.status==200指http协议状态码
          // xhr.readyState==4指xhr的响应码
          xhr.onreadystatechange=function(){
              if(xhr.status==200&&xhr.readyState==4){
                  if(callback){
                      callback(xhr.response);
                  }
              }
          }
      }
    
1.3.5 get异步传参的ajax封装 ---> 回调函数解决异步
  • get传参:通过url传参

      1. 封装一个创建xhr的方法
      function createXhr(){
          if(window.XMLHttpRequest){
              return new XMLHttpRequest();
          }
          return new ActiveXObject("Msxml2.HTTP");
      }
      
      2. 封装一个处理参数的方法(键值对的字符串,比如 id=1&&name=小刘&)
      注意:= & 在ajax中属于有特殊含义的字符,可多不可少
      function getParams(obj){
          let str = '';
          for(let key of Object.keys(obj)){
              str += key + "=" + obj[key] + "&";
          }
          return str;
      }
      
      3. get异步传参的ajax封装
      function get(url,obj,callback){
          let xhr = createXhr();
          xhr.open("get",url+"?"+getParams(obj));
          xhr.send(null);
          xhr.onreadystatechange = function(){
              if(xhr.status==200&&xhr.readyState==4){
                  if(callback){
                      callback(xhr.response);
                  }
              }
          }
      }
    
1.3.6 post异步传参的ajax封装 ---> 回调函数解决异步
  • post传参:send方法传参

  • send前需要设置请求头 xhr.setRequestHeader("Content-Type","application-x-www-form-urlencoded")

      1. 封装一个创建xhr的方法
      function createXhr(){
          if(window.XMLHttpRequest){
              return new XMLHttpRequest();
          }
          return new ActiveXObject("Msxml2.HTTP");
      }
      
      2. 封装一个处理参数的方法(键值对的字符串,比如 id=1&&name=小刘&)
      注意:= & 在ajax中属于有特殊含义的字符,可多不可少
      function getParams(obj){
          let str = '';
          for(let key of Object.keys(obj)){
              str += key + "=" + obj[key] + "&";
          }
          return str;
      }
      
      3. get异步传参的ajax封装
      function post(url,obj,callback){
          let xhr = createXhr();
          xhr.open("post",url);
          xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
          xhr.send(getPatams(obj));
          xhr.onreadystatechange = function(){
              if(xhr.status==200&&xhr.readyState==4){
                  if(callback){
                      callback(xhr.response);
                  }
              }
          }
      }
    
1.3.7 get异步传参的ajax封装 ---> promise+async+await获取数据
    1. 封装一个创建xhr的方法
    function createXhr(){
        if(window.XMLHttpRequest){
            return new XMLHttpRequest();
        }
        return new ActiveXObject("Msxml2.HTTP");
    }
    
    2. 封装一个处理参数的方法(键值对的字符串,比如 id=1&&name=小刘&)
    注意:= & 在ajax中属于有特殊含义的字符,可多不可少
    function getParams(obj){
        let str = '';
        for(let key of Object.keys(obj)){
            str += key + "=" + obj[key] + "&";
        }
        return str;
    }
    
    3. get异步传参的ajax封装
    function getP(url,obj){
        return new Promise((resolve,reject)=>{
            let xhr = createXhr();
            xhr.open("get",url+"?"+getParams(obj));
            xhr.send(null);
            xhr.onreadystatechange = function(){
                if(xhr.status==200&&xhr.readyState==4){
                    resolve(xhr.response);
                }
            }
        })
    }
    
    // 使用
    async function(){
        let res = await getP('http://xxxx', {name:"小刘"});
        console.log(res);
    }
1.3.8 post异步传参的ajax封装 ---> promise+async+await获取数据
    1. 封装一个创建xhr的方法
    function createXhr(){
        if(window.XMLHttpRequest){
            return new XMLHttpRequest();
        }
        return new ActiveXObject("Msxml2.HTTP");
    }
    
    2. 封装一个处理参数的方法(键值对的字符串,比如 id=1&&name=小刘&)
    注意:= & 在ajax中属于有特殊含义的字符,可多不可少
    function getParams(obj){
        let str = '';
        for(let key of Object.keys(obj)){
            str += key + "=" + obj[key] + "&";
        }
        return str;
    }
    
    3. post异步传参的ajax封装
    function postP(url,obj){
        return new Promise((resolve,reject)=>{
            let xhr = createXhr();
            xhr.open("post",url);
            xhr.setRequestHeader("Content-Type","application/x-www-form-encoded");
            xhr.send(getParams(obj));
            xhr.onreadystatechange = function(){
                if(xhr.status==200&&xhr.readyState==4){
                    resolve(xhr.response);
                }
            }
        })
    }
    
    // 使用
    async function(){
        let res = await postP('http://xxxx', {name:"小刘"});
        console.log(res);
    }

2. fetch的使用

fetch是ES6新增的内置方法,可以直接使用。

1.1 fetch(url,init) 基本规则

  • ① 作用:
  • ② 参数:
    • 参数1:url (必写)---> 请求地址
    • 参数2:init (选写)---> 是一个对象,包括发送http请求的配置信息。可选值:
      • method:请求方式。GET、POST、PUT、DELETE、PATCH。默认是GET请求
      • headers:请求头的信息。
      • body:请求体的信息。
  • ③ 返回值:返回一个promise对象

【补充】fetch的具体使用规则

1.2 fetch(url,init) 实现简单的增删改查

    // 传递的参数处理
    function getParams(obj){
        let str = '';
        for(let key of Object.keys(obj)){
            str += key + '=' + obj[key] + '&';
        }
        return str;
    }

    // 1. 增加,POST,传递一个对象
    fetch('http://localhost:8890/items',{
        method:'POST',
        headers:{
            'Content-Type':'application/x-www-form-urlencoded'
        },
        body:getParams({name:'刘亦菲',age:24}); // 这里传的对象也可以直接用JSON.stringify(obj)转换为字符串
    }).then(res=>res.json()).then(res=>{console.log(res)});
    
    // 2. 删除,DELETE,根据id删除
     fetch('http://localhost:8890/items/2',{
         method:'DELETE',
     }).then(res=>res.json()).then(res=>{console.log(res)});
     
    // 3. 修改,PATCH,根据id修改,传递一个对象
    fetch('http://localhost:8890/items/3',{
       method:'PATCH',
       headers:{
           'Content-Type':'application/x-www-form-urlencoded'
       },
       body:getParams({name:'刘亦菲',age:24}); //  // 这里传的对象也可以直接用JSON.stringify(obj)转换为字符串
    }).then(res=>res.json()).then(res=>{console.log(res)});
    
    // 4. 查询,GET 
    let str = '王';
    fetch(`http://localhost:8890/items?name_like=${str}`).then(res=>res.json()).then(res=>{console.log(res)});
    

3. axios的使用

3.1 什么是axios

  • 基于promise的异步ajax请求库。
  • 可以用在浏览器和 node.js 中
  • 使用前要引入和封装。

3.2 axois使用前的引入和封装

// 引入js库
import axios from 'https://cdn.bootcdn.net/ajax/libs/axios/1.3.6/esm/axios.min.js'; // 模块化的导入写法
// 这里的三方库做了一些处理,所以后续在使用的时候发送post,patch,put,delete请求的时候不用设置请求头,在传递数据的时候也不需要转换为字符串。

// 1. 创建一个axios对象
let http = axios.create({
    baseURL:'http://localhost:8890', // 设置请求的基本路由
    timeout:5000  // 服务器5秒没有返回数据,就判断服务器挂了
});

// 2. 请求拦截
http.interceptors.request.use((config)=>{
    // 在发送请求前可以做一些数据配置
    config.headers['token']=localStorage.getItem('token'); // 这里在发送请求前自定义了请求头。 token:令牌
    return config;
},(err)=>{
    return Primose.reject(err);
})

// 3. 响应拦截
http.interceptors.response.use((response)=>{
    // 获取响应回来的数据,可以进行二次加工
    return response;
},(err)=>{
    return Promise.reject(err);
})

// 4. 暴露新的axios实例对象
export default http;

3.3 axios()的基本使用规则

3.3.1 axios基本请求:通用/最本质的发任意类型请求的方式
http({
    url:'/items', // 请求路径
    method:'get', // 请求方式:get、post、put、patch、delete,若不写默认是get请求
    params:{      // get请求用传参的键名是params,其他请求传参的键名是data
        name:'小刘',
        age:20
    }
})
3.3.2 axios的请求路径固定
http(url,{
    method:'get', // 请求方式:get、post、put、patch、delete,若不写默认是get请求
    params:{      // get请求用传参的键名是params,其他请求传参的键名是data
        name:'小刘',
        age:20
    }
})
3.3.3 axios的请求别名
http.get(url,{
    params:{      // get方式请求使用params参数传递,params必须是一个无格式对象(plain object)或 URLSearchParams 对象,params必须是键值对方式传递,否则axios会自动帮你处理为0=参数
        name:'小刘',
        age:20
    }
})

http.post(url,{     //post方式传递参数使用data字段
        name:'小刘',
        age:20
        })

3.4 axios的增删改查封装

1. 添加 POST 传递对象
export const add1 = (data)=>{
    return http({
        url:'/items',
        method:'post',
        data
    })
}

export const add2 = (data)=>{
    return http.post(url,data)
}


2. 删除 DELETE 根据id删除
export const del1 = (id)=>{
    return http({
        url:`/items/${id}`,
        method:'delete'
    })
}

export const del2 = (id)=>{
    return http.delete(`/items/${id}`)
}

3. 修改 patch 根据id修改,传递对象
export const update1 = (id,data)=>{
    return http({
        url:`/items/${id}`,
        method:'patch',
        data
    })
}

export const update2 = (id,data)=>{
    return http.patch(`/items/${id}`,data)
}


4. 查询 get 带参数查询
export const search1 = (params)=>{  // 注意:在使用的时候params传递的参数为{name_like:'刘'}形式
    return http({
        url:'/items',
        method:'get',
        params
    })
}

export const search2 = (params)=>{  // 注意:在使用的时候params传递的参数为{name_like:'刘'}形式
    return http.get('/items',params);
}