浅析Ajax和axios

95 阅读4分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第30天,点击查看活动详情

1.Ajax(基于XMLHttpRequest(XHR))

Ajax是一种异步通信的方法,通过 js 脚本向服务器发起 http 通信,然后根据服务器返回的数据,更新网页的相应部分,而不用刷新整个页面的一种方法。(异步局部刷新技术)

创建步骤:

创建对象 => 配置Ajax请求地址 => 发送请求 => 监听请求,接受响应

原生写法:

//1:创建Ajax对象
var xhr = window.XMLHttpRequest?new XMLHttpRequest():new 
//2:配置 Ajax请求地址
xhr.open('get','url',true);
//3:发送请求
xhr.send(null); // 严谨写法
//4:监听请求,接受响应
xhr.onreadysatechange=function(){
    //readystate是当前的状态值
    //status是Http的状态码 200表示ok  
    if(xhr.readySate==4&&xhr.status==200)  console.log(xhr.responseText)
}

2. axios

axios是基于promise对ajax的封装库,可以用在浏览器和 node.js 中。

具有以下特征:

  • 从浏览器中创建XMLHttpRequests
  • 从 node.js 创建 http 请求
  • 支持 Promise API
  • 拦截请求和响应
  • 转换请求数据和响应数据
  • 取消请求
  • 自动转换 JSON 数据
  • 客户端支持防御 XSRF

1. axios请求方式

axios(url[, config])
axios.request(config)
axios.get(url [,config])
axios.delete(url [,config])
axios.head(url [,config])
axios.post(url [,data [,config]])
axios.put(url [,data [,config]])

注:

  1. axios可以用作函数使用,也可以用作对象使用(函数对象)
  2. [, ] 是可选参数列表

2.常见的配置选项

请求地址 url: '/user',
请求类型 method: 'get',
请求根路径(axios会自动将baseURL 和 url 进行拼接,从而得出正确的请求路径。) baseURL: 'http://www.xxx.com/api',
请求前的数据处理(只能用在 'PUT', 'POST' 和 'PATCH' 这几个请求方法) transformRequest:[function(data){}],
请求后的数据处理 transformResponse: [function(data){}],
自定义的请求头 headers:{'x-Requested-With':'XMLHttpRequest'},
URL查询对象 params:{ id: 12 },
超时设置(timeout指定请求超时的毫秒数(0 表示无超时时间,超过多少时间就取消请求)) timeout: 1000,
响应的数据格式 (json / blob /document /arraybuffer / text / stream) responseType: 'json',

3. 拦截器

用于我们在发送每次请求或者得到相应后,进行对应的处理。

a. 请求拦截的作用:

  • 当发送网络请求时,在页面中添加一个loading组件,作为动画

  • 某些请求要求用户必须登录,判断用户是否有token,如果没有token就跳转到login页面

  • config中的一些信息不符合服务器要求

    请求拦截中错误拦截较少,通常都是配置相关的拦截 可能的错误比如请求超时,可以将页面跳转到一个错误页面中。

b. 响应拦截中完成的事情:

  • 响应的成功拦截中,主要是对数据进行过滤。
  • 响应的失败拦截中,可以根据status判断报错的错误码,跳转到不同的错误提示页面。
// axios拦截器:配置请求和响应拦截
  instance.interceptors.request.use(config => {
    // 请求拦截:success中
    return config  //拦截了需要返回
  },err => {
    // 请求拦截:failure中
    return err  
  })

  instance.interceptors.response.use(response => {
    // 响应拦截:success中
    return response.data
  },err => {
    // 响应拦截:failure中
    if(err && err.response){
      switch (err.response.status){
        case 400:
          err.message = '请求错误'
          break
        case 401:
          err.message = '未授权的访问'
          break
      }
    }
    return err  
  })

4.发送基本请求

a. 发送并发请求(同时发送多个请求)

使用axios.all, 可以放入多个请求的数组.

axios.all([]) 返回的结果是一个数组,使用 axios.spread 可将数组 [res1,res2] 展开为 res1, res2

import axios from 'axios'
export default {
  name: 'App',
  created(){
    // 发送并发请求
    axios.all(
      [
        axios.get('http://123.207.32.32:8000/home/multidata'),
        axios.get('http://123.207.32.32:8000/category')      
      ])
      .then(axios.spread((res1,res2)=>{
        console.log(res1);
        console.log(res2);     
      }))
  }
}

b. 全局配置

在开发中可能很多参数都是固定的。这个时候我们可以进行一些抽取, 也可以利用axios的全局配置

axios.defaults.baseURL = ‘123.207.32.32:8000’
axios.defaults.headers.post[‘Content-Type’] = ‘application/x-www-form-urlencoded’;
import axios from 'axios'
export default {
  name: 'App',
  created(){
    //提取全局的配置
    axios.defaults.baseURL = 'http://123.207.32.32:8000'
    // 发送并发请求
    axios.all(
      [
        axios.get('/home/multidata'),
        axios.get('/category')      
      ])
      .then(axios.spread((res1,res2)=>{
        console.log(res1);
        console.log(res2);     
      }))
  }
}

5. axios简单实例

src目录下新建network文件夹,并在该文件夹下新建request.js,封装axios模块

import axios from 'axios'
 一、回调函数的方式
export function request(config,success,failure){ 
  // 1.创建axios的实例
  const instance = axios.create({
    baseURL:'http://123.207.32.32:8000',
    timeout:5000
  })
  // 2.发送真正的网络请求
  instance(config)
  .then(res => {
    success(res);
  })
  .catch(err => {
    failure(err);
  })
}
 二、promise的方式
 export function request(config){ 
  return new promise((resolve,reject) => {
      // 1.创建axios的实例
      const instance = axios.create({
        baseURL:'http://123.207.32.32:8000',
        timeout:5000
      })
      // 2.发送真正的网络请求
      instance(config)
      .then(res => {
        resolve(res);
      })
      .catch(err => {
        reject(err);
      })
  })
}
三、最简单的封装
 export function request(config){ 
      // 1.创建axios的实例
      const instance = axios.create({
        baseURL:'http://123.207.32.32:8000',
        timeout:5000
      })
      // 2.发送真正的网络请求
      return instance(config) //instance(config) 直接返回的是promise
}

在需要的位置使用封装的网络请求模块

// request模块
import {request} from './network/request.js'
export default {
  name: 'App',
  created(){
   一、回调函数的方式
   request({
     url:'/home/multidata'
   },res => {
     console.log(res);  
   },err => {
     console.log(err);
   })
   二、promise的方式(第三种方式同样)
    request({
     url:'/home/multidata'
   }).then (res =>{
       console.log(res);
    }).catch(err => {
      console.log(err);
    })
  }
}