axios网络模块封装笔记

本文介绍了在前端开发中,为什么选择axios作为网络模块,而非传统的Ajax或jQuery-Ajax。详细阐述了JSONP的工作原理,并对axios的功能特点、使用方法、创建实例以及拦截器的应用进行了详细的讲解,包括其支持的多种请求方式、全局配置和拦截器中的请求与响应处理。此外,还讨论了如何在项目中封装axios实例以提高代码复用性和灵活性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.选择什么网络模块?

选择一: 传统的Ajax是基于XMLHttpRequest(XHR)

为什么不用它呢?

  • 非常好解释, 配置和调用方式等非常混乱.
  • 编码起来看起来就非常繁琐.
  • 所以真实开发中很少直接使用, 而是使用jQuery-Ajax

选择二: 在前面的学习中, 我们经常会使用jQuery-Ajax

相对于传统的Ajax非常好用.
为什么不选择它呢?

  • 首先, 我们先明确一点: 在Vue的整个开发中都是不需要使用jQuery了.
  • 那么, 就意味着为了方便我们进行一个网络请求, 特意引用一个jQuery, 不合理

选择三:axios

其实官方在Vue1.x的时候, 推出了Vue-resource.但是后来作者在说明不再继续更新和维护vue-resource了,所以现在推荐axios
axios有非常多的优点, 并且用起来也非常方便.

2.JSONP

在前端开发中, 我们一种常见的网络请求方式就是JSONP

  • 使用JSONP最主要的原因往往是为了解决跨域访问的问题.

JSONP的原理是什么呢?

  • JSONP的核心在于通过<script>标签的src来帮助我们请求数据.
  • 原因是我们的项目部署在domain1.com服务器上时, 是不能直接访问domain2.com服务器上的资料的.
  • 这个时候, 我们利用<script>标签的src帮助我们去服务器请求到数据, 将数据当做一个javascript的函数来执行,
    并且执行的过程中传入我们需要的json.
  • 所以, 封装jsonp的核心就在于我们监听window上的jsonp进行回调时的名称.

3.axios

功能特点:

  • 在浏览器中发送 XMLHttpRequests 请求
  • 在 node.js 中发送 http请求
  • 支持 Promise API
  • 拦截请求和响应
  • 转换请求和响应数据

支持多种请求方式:

  • axios(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]])
  • axios.patch(url[, data[, config]])

axios的使用

npm install axios --save

(1)最基本使用
import axios from 'axios'

//axios本身可以返回一个promise,调用内部resolve
axios({
  // url:'httpbin.org/'
  url:'http://123.207.32.32:8000/home/multidata',
  method:'get'//默认情况下get请求
}).then(res => {
  console.log(res)
})
(2)专门针对get请求的参数拼接
axios({
  url:'http://123.207.32.32:8000/home/data',
  params:{
    type:'pop',
    page:1
  },
  method:'get'
}).then(res => {
  console.log(res)
})
(3)axios.get()
// 为给定 page 的 data 创建请求
axios.get('http://123.207.32.32:8000/home/data?type=sell&page=3')
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });
// 可选地,上面的请求可以这样做
axios.get('http://123.207.32.32:8000/home/data', {
    params: {
        type:'pop',
    	page:1
    }
  })
  .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);
  });
(4)axios.all执行多个并发请求

axios.all([axios({}),axios({})]).then(=>res{})

function getUserAccount() {
  return axios.get('/user/12345');
}

function getUserPermissions() {
  return axios.get('/user/12345/permissions');
}

axios.all([getUserAccount(), getUserPermissions()])
  .then(axios.spread(function (acct, perms) {
    // 两个请求现在都执行完成
  }));

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

axios.all([axios.get('http://123.207.32.32:8000/home/multidata'),
  axios.get('http://123.207.32.32:8000/home/data',{params:{type:'pop',page:1}})
])
.then(axios.spread((res1,res2) => {
  console.log(res1);
  console.log(res2);
}))

补充一个小小的知识点
数组的解构

const names = ['11','22','33']
//const name1 = names[0]
//const name2 = names[1]
//const name3 = names[2]
const [name1,name2,name3] = names
(5)全局配置defaults

在这里插入图片描述

axios.defaults.baseURL='http://123.207.32.32:8000'
axios.defaults.timeout=5000

axios.all([axios.get('/home/multidata'),
  axios.get('/home/data',{params:{type:'pop',page:1}})
])
.then(axios.spread((res1,res2) => {
  console.log(res1);
  console.log(res2);
}))
(6)常见的配置选项

请求地址

  • url: ‘/user’,

请求类型

  • method: ‘get’,

请根路径

  • baseURL: ‘http://www.mt.com/api’,

请求前的数据处理

  • transformRequest:[function(data){}],

请求后的数据处理

  • transformResponse: [function(data){}],

自定义的请求头

  • headers:{‘x-Requested-With’:‘XMLHttpRequest’},

URL查询对象
(method: ‘get’,)

  • params:{ id: 12 },

查询对象序列化函数

  • paramsSerializer: function(params){ }

request body
(methos:‘post’)

  • data: { key: ‘aa’},

超时设置s

  • timeout: 1000,

跨域是否带Token

  • withCredentials: false,

自定义请求处理

  • adapter: function(resolve, reject, config){},

身份验证信息

  • auth: { uname: ‘’, pwd: ‘12’},

响应的数据格式 json / blob /document /arraybuffer / text / stream

  • responseType: ‘json’,

axios创建实例

为什么要创建axios的实例呢?

  • 当我们从axios模块中导入对象时, 使用的实例是默认的实例.
  • 当给该实例设置一些默认配置时, 这些配置就被固定下来了.
  • 但是后续开发中, 某些配置可能会不太一样.
  • 比如某些请求需要使用特定的baseURL或者timeout或者content-Type等.
  • 这个时候, 我们就可以创建新的实例, 并且传入属于该实例的配置信息.

服务器以后不在同一个ip地址里,就不方便使用全局配置,我们要创建对应的axios实例

const instancel = axios.create({
  baseURL:'http://123.207.32.32:8000',
  timeout:5000
})

instancel({
  url:'/home/multidata'
}).then(res => {
  console.log(res);
})

instancel({
  url:'/home/data',
  params:{type:'pop',page:1}
}).then(res => {
  console.log(res);
})

如果遇到不同的ip地址,再定义一个const instancel2 写上对应ip地址就好了
在每一个vue文件使用时在单独引入
HelloWorld.vue(这算一个子组件,注意要在父组件中引入)

<template>
  <h2>{{categories}}</h2>
</template>

<script>
  import axios from 'axios'
  export default {
    name: "HelloWorld",
    data() {
      return {
        categories: ''
      }
    },
    created() {//实例创建完成生命周期
      axios({
        url: 'http://123.207.32.32:8000/category'
      }).then(res => {
        this.categories = res;
      })
    }
  }
</script>

父组件中

<template>
  <div id="app">
    <div>{{result}}</div>
    <hello-world/>
  </div>
</template>

<script>
  import HelloWorld from './components/HelloWorld'

  import axios from 'axios'

  export default {
    name: 'App',
    components: {
      HelloWorld
    },
    data() {
      return {
        result: ''
      }
    },
    created() {
      axios({
        url: 'http://123.207.32.32:8000/home/multidata'
      }).then(res => {
        this.result = res;
      })
    }
  }
</script>

但是如果不封装一个实例,每次我们用到axios都要单独引用一下,很麻烦,下面我们进行封装
在这里插入图片描述

import axios from 'axios'

//考虑到扩展就不用defaule了
export function request(config) {
  //1.创建axios的实例
  const instance = axios.create({
    baseURL:'http://123.207.32.32:8000',
    timeout:5000
  })
  //发送真正的网络请求
  instance(config).then(res =>{
     console.log(res);
  }).catch(err => {
     console.log(err);
  })
}

console.log()但是我们不能在这个文件里进行传值呀,怎么传出去呢?
给request多添加两个参数 success, failure
方法一:

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
  })
  //发送真正的网络请求
  instance(config).then(res =>{
    // console.log(res);
    success(res)//回调数据
  }).catch(err => {
    // console.log(err);
    failure(err)
  })
}

再在main.js中封装一个request模块

import {request} from "./network/request";

request({
  url:'/home/multidata'
},res =>{
  console.log(res);
},err => {
  console.log(err);
})

在这里插入图片描述
方法二

import axios from 'axios'

export function request(config) {
  //1.创建axios的实例
  const instance = axios.create({
    baseURL:'http://123.207.32.32:8000',
    timeout:5000
  })
  //发送真正的网络请求
  instance(config.baseConfig).then(res =>{//config中取出baseConfig
    config.success(res)//config中取出success,在这里进行回调1
  }).catch(err => {
    config.failure(err)//config中取出failure
  })
}

main.js中

import {request} from "./network/request";

request({
  baseConfig:{
    
  },
  success: function (res) {
    
  },
  failure: function (err) {
    
  }
})

除了以上两种回调函数方式,我们一般在项目中用第三种方法,promise方式

方法三

request.js

import axios from 'axios'

export function request(config) {
  return new Promise(((resolve, reject) => {
    const instance = axios.create({
    baseURL:'http://123.207.32.32:8000',
    timeout:5000
  })
  //发送真正的网络请求
  instance(config)
    .then(res =>{
    resolve(res)
  })
    .catch(err => {
    reject(err)
  })
  }
  ))
}

main.js封装一个request模块

import {request} from "./network/request";

request({
  url:'/home/multidata'
}).then(res => {
  console.log(res)
}).catch(err => {
  console.log(err)
})

再或者request.js直接写成
面向request发送请求

export function request(config) {
      const instance = axios.create({
        baseURL:'http://123.207.32.32:8000',
        timeout:5000
      })
      //发送真正的网络请求
      return instance(config)
}

在这里插入图片描述
进入后再长按Ctrl进入AxiosInstance
在这里插入图片描述
也就是说我们定义的这个instance本身的返回值就是Promise
在这里插入图片描述
所以我们直接return instance,就可以了
封装好之后如果有一天axios不可用了,我们直接修改request.js中的引入,再修改export function request(config) {}中的内容就可以了

axios拦截器的使用

axios提供了拦截器,用于我们在发送每次请求或者得到相应后,进行对应的处理。
在这里插入图片描述

import axios from 'axios'

export function request(config) {
  //1.创建axios的实例
      const instance = axios.create({
        baseURL:'http://123.207.32.32:8000',
      })
      
  //2.axios拦截器
  instance.interceptors.request.use(config =>{
    console.log(config);
    //请求拦截
    return config//拦截掉之后还要原封不动的返回出去
  },err =>{} );
  
  instance.interceptors.response.use(res => {
  	//响应拦截
    // console.log(res);
    return res.data
  },err =>{
    console.log(err);
  });
  //3.发送真正的网络请求
      return instance(config)
}
//封装一个request模块
import {request} from "./network/request";

request({
  url:'/home/multidata'
}).then(res => {
  console.log(res)
}).catch(err => {
  // console.log(err)
})
拦截器中都做什么呢?
请求拦截
  • 1.比如config中的一些信息不符合服务器的要求
  • 2.比如每次发送网络请求时,都希望在界面中显示一个请求的图标(比如一个加载的图片)
  • 3.某些网络请求(比如说登录),必须携带一些特殊的信息
  • 请求拦截中错误拦截较少,通常都是配置相关的拦截
  • 可能的错误比如请求超时,可以将页面跳转到一个错误页面中。
响应拦截:
  • 响应的成功拦截中,主要是对数据进行过滤。上面代码中就对data进行了过滤return res.data
  • 响应的失败拦截中,可以根据status判断报错的错误码,跳转到不同的错误提示页面。
instance.interceptors.response.use(res => {
    return res.data
  },err =>{
    console.log(err);
    if (err && err.response) {
      switch (err.response.status) {
        case 400:
          err.message = '请求错误'
          break
        case 401:
          err.message = '未授权的防问'
          break
      }
    }
    return err
  });

(以上内容根据微博“coderwhy”的vue视频课程整理,感谢王红元老师ღ( ´・ᴗ・` )比心)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值