axios使用介绍及封装

一.axios是什么

概述:

Axios 是一个基于 promise 网络请求库,作用于node.js 和浏览器中。 它是 isomorphic 的(即同一套代码可以运行在浏览器和node.js中)。在服务端它使用原生 node.js http 模块, 而在客户端 (浏览端) 则使用 XMLHttpRequests。

axios有以下特性:

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

历史:

在旧浏览器页面在向服务器请求数据时,因为返回的是整个页面的数据,页面都会强制刷新一下,这对于用户来讲并不是很友好。我们只是需要修改页面的部分数据,也希望不刷新页面,但是从服务器端发送的却是整个页面的数据,十分消耗网络资源,因此异步网络请求(Ajax)就应运而生。

Ajax(Asynchronous JavaScript and XML):
异步网络请求。Ajax能够让页面无刷新的请求数据。

实现ajax的方式有多种,如jQuery封装的ajax,原生的XMLHttpRequest,以及axios。但各种方式都有利弊:

  • 原生的XMLHttpRequest的配置和调用方式都很繁琐,实现异步请求十分麻烦
  • jQuery的ajax相对于原生的ajax是非常好用的,但是jQuery框架比较‘重’,没有必要因为要用ajax异步网络请求而引用jQuery框架
  • Axios(ajax i/o system):这不是一种新技术,本质上还是对原生XMLHttpRequest的封装,可用于浏览器和nodejs的HTTP客户端,只不过它是基于Promise的,符合最新的ES规范。

想要知道更多关于Ajax的内容请看我的这篇文章,戳我传送,本篇文章主要讲解axios,Ajax在这里就不过多介绍了 

二.axios介绍

axios是基于Promise的,因此可以使用Promise API

1.axios可以请求的方法:

  1. get:获取数据,请求指定的信息,返回实体对象
  2. post:向指定资源提交数据(例如表单提交或文件上传)
  3. put:更新数据,从客户端向服务器传送的数据取代指定的文档的内容
  4. patch:更新数据,是对put方法的补充,用来对已知资源进行局部更新
  5. delete:请求服务器删除指定的数据
  6. head:获取报文首部

2.请求方法别名

为了方便起见,axios为所有支持的请求方法提供了别名:

  1. axios(config)
  2. axios.request(config)
  3. axios.get(url [,config])
  4. axios.post(url [,data [,config]])
  5. axios.put(url [,data [,config]])
  6. axios.delete(url [,config])
  7. axios.patch(url [,data [,config]])
  8. axios.head(url [,config])

get、post请求代码示例: 

//执行GET请求
import axios from 'axios'
axios.default.baseURL = 'http://localhost:3000/api/products'
axios.get('/user?ID=12345')  //返回的是一个Promise
    .then(res=>console.log(res))
    .catch(err=>console.log(err));

//可配置参数的方式
axios.get('/user',{
    params:{
        ID:12345
    }
}).then(res=>console.log(res))
  .catch(err=>console.log(err));

//发送post请求
axios.post('/user',{
    firstName: 'ziming',
    lastName:'song'
}).then(res=>console.log(res))
  .catch(err=>console.log(err));

3.并发请求

通过axios.all(iterable)可实现发送多个请求,参数不一定是数组,只要有iterable接口就行,函数返回的是一个数组

axios.spread(callback)可用于将结果数组展开

 axios.all([
	axios.get('/goods.json'),
	axios.get('/class.json')
]).then(axios.spread((goodsRes,classRes)=>{
		console.log(goodsRes.data);
		console.log(classRes.data);
	}))

三.axios API

1.向 axios 传递相关配置来创建请求

代码示例:

1.axios(config)
// 发送 POST 请求
axios({
  method: 'post',
  url: '/user/12345',
  data: {
    firstName: 'song',
    lastName: 'ziming'
  }
});
 
2.axios(url[, config])
// 默认发送 GET 请求
axios('/user/12345');

2.用axios提供的请求方法发送请求

代码示例:

1.axios.get(url[, config])  执行 GET 请求
 
	// 向具有指定ID的用户发出请求
	axios.get('/user?ID=12345')
	  .then(function (res) {
		console.log(res);
	  })
	  .catch(function (err) {
		console.log(err);
	  });
	  
	// 也可以通过 params 对象传递参数
	axios.get('/user', {
		params: {
		  ID: 12345
		}
	  })
	  .then(function (res) {
		console.log(res);
	  })
	  .catch(function (err) {
		console.log(err);
	  });
 
2.axios.post(url[, data[, config]]) 执行 POST 请求

	axios.post('/user', {
		firstName: 'song',
		lastName: 'ziming'
	  })
	  .then(function (res) {
		console.log(res);
	  })
	  .catch(function (err) {
		console.log(err);
	  });

3.axios.request(config)//用法同上
4.axios.head(url[, config])//用法同上
5.axios.delete(url[, config])//用法同上
6.axios.put(url[, data[, config]])//用法同上
7.axios.patch(url[, data[, config]])//用法同上

8.axios.all(iterable)执行多个并发请求
9.axios.spread(callback)展开

		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实例及配置方法

1.创建axios实例

axios.create([config])

可以同时创建多个axios实例。

代码示例:

const instance = axios.create({
  baseURL: 'https://some-domain.com/api/',
  timeout: 1000,
  headers: {'X-Custom-Header': 'foobar'}
});

实例方法

以下是可用的实例方法。指定的配置将与实例的配置合并。

  • axios#request(config)
  • axios#get(url[, config])
  • axios#delete(url[, config])
  • axios#head(url[, config])
  • axios#options(url[, config])
  • axios#post(url[, data[, config]])
  • axios#put(url[, data[, config]])
  • axios#patch(url[, data[, config]])
  • axios#getUri([config])

2.配置方法

配置对象常用的配置项:

这些是创建请求时可以用的配置选项。只有 url 是必需的。如果没有指定 method,请求将默认使用 GET 方法。更多配置项请查看官方文档,戳我传送

{
  // 路径url
  url: '/user',

  // 请求方法,默认get
  method: 'get', 

  //基础url,最终请求的url是 baseURL+url拼接,所以再全局设置默认,可以使得发送请求时的url变得简洁
  baseURL: 'https://some-domain.com/api/',

  //设置请求头
  headers: {'X-Requested-With': 'XMLHttpRequest'},

  //设置请求url的query参数,可以使得url简洁。
  //比如url是https://some-domain.com/api/user  然后params如下设置,那么最终的url是:
  //https://some-domain.com/api/user?ID=12345&name=Jack
  params: {
    ID: 12345,
    name:"Jack"
  },

 //设置请求体
  data: {
    firstName: 'Fred'
  },
  
  //设置请求的另外一种格式,不过这个是直接设置字符串的
  data: 'Country=Brasil&City=Belo Horizonte',

 //请求超时,单位毫秒,默认0,不超时。
  timeout: 1000,

  //响应数据类型,默认json
  responseType: 'json', 

  //响应数据的编码规则,默认utf-8
  responseEncoding: 'utf8',

	//响应体的最大长度 
  maxContentLength: 2000,

  // 请求体的最大长度
  maxBodyLength: 2000,

  //设置响应状态码为多少时是成功,调用resolve,否则调用reject失败
  //默认是大于等于200,小于300
  validateStatus: function (status) {
    return status >= 200 && status < 300; 
  },

默认配置

可以设置全局默认配置,是为了避免多种重复配置在不同请求中重复,比如baseURL、timeout等,这里设置baseURL。

全局 axios 默认值

axios.defaults.baseURL = 'https://api.example.com';
axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';

自定义实例默认值

// 创建实例时配置默认值
const instance = axios.create({
  baseURL: 'https://api.example.com'
});

// 创建实例后修改默认值
instance.defaults.headers.common['Authorization'] = AUTH_TOKEN;

配置的优先级

配置将会按优先级进行合并。它的顺序是:在 lib/defaults.js 中找到的库默认值,然后是实例的 defaults 属性,最后是请求的 config 参数。后面的优先级要高于前面的

五.拦截器

在请求或响应被 then 或 catch 处理前拦截它们,自定义的axios实例也可添加拦截器,如:

const instance = axios.create();
instance.interceptors.request.use(function () {/*...*/});

请求拦截器

示例代码:

// 添加请求拦截器
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);
  });

取消拦截器

示例代码:

const myInterceptor = axios.interceptors.request.use(function () {/*...*/});
axios.interceptors.request.eject(myInterceptor);

六.取消请求

注意:从 v0.22.0 开始,Axios 支持以 fetch API 方式——  AbortController 取消请求,CancelToken API被弃用

 这里我们两种方法都介绍一下,使用过程中能用 AbortController 就尽量别用 CancelToken

 AbortController

const controller = new AbortController();

axios.get('/foo/bar', {
   signal: controller.signal
}).then(function(response) {
   //...
});
// 取消请求
controller.abort()

CancelToken

let source = axios.CancelToken.source();

axios.get('/users/12345',{
				cancelToken: source.token
			}).then(res=>{
				console.log(res)
			}).catch(err=>{
				//取消请求后会执行该方法
				console.log(err)
			})

//取消请求,参数可选,该参数信息会发送到请求的catch中
source.cancel('取消后的信息');

 也可以通过传递一个 executor 函数到 CancelToken 的构造函数来创建一个 cancel token:

const CancelToken = axios.CancelToken;
let cancel;

axios.get('/user/12345', {
  cancelToken: new CancelToken(function executor(c) {
    // executor 函数接收一个 cancel 函数作为参数
    cancel = c;
  })
});

// 取消请求
cancel();

注意: 可以使用同一个 cancel token 或 signal 取消多个请求 

axios封装

先设计我们想要这个通用请求能达到什么样的效果:

  • 优化配置,设置默认配置项(responseType、跨域携带cookie、token、超时设置)
  • 统一设置请求头
  • 根据环境设置 baseURL
  • 通过 Axios 方法直接发起请求
  • 添加请求拦截器
  • 添加响应拦截器
  • 导出 Promise 对象
  • 封装 Post 方法,精简 post 请求方式
  • 封装 Get 方法,精简 get 请求方式
  • 请求成功,配置业务状态码
  • 全局的loading配置

我们需要根据不同的需求进行不同程度的封装,这里介绍一下封装方法,就不一一进行二次封装实现

// src/api/axios.js
import axios from "axios";
import Qs from 'qs'
import store from '@/store'
import { getToken } from '@/utils/auth'

export const Axios = (url,method='get',params={},headers={})=>{
    // 根据定义的环境状态,切换不同的 baseURL 开发环境使用代理, 生产环境可以直接使用域名全拼
    const BaseUrl = process.env.NODE_ENV==='development'? '' : process.env.BASEURL;
    let defaultHeaders = {
        'Content-Type': 'application/json;charset=UTF-8',
        // 'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8', // 指定提交方式为表单提交 或上传
        // 'Content-Type' :'multipart/form-data;charset=UTF-8',
        'Accept': 'application/json', // 通过头指定,获取的数据类型是JSON
        // 'Access-Control-Allow-Origin': 'true',
        // 'Access-Control-Allow-Credentials': 'true',
    }

    if(headers){
        for (let i in headers) {
            defaultHeaders[i] = headers[i];
        }
    }
//在响应拦截中,如果有需要还可以对状态码提示进行处理。现在项目一般后端都会给处理好,
//这个根据自己的项目情况进行配置,这里只做部分常见的示例
    const showResState = (state) => {
        let message = ''
        switch (state) {
            case 400:
                message = '请求错误(400)'
                break
            case 401:
                message = '未授权,请重新登录(401)'
                break
            case 403:
                message = '拒绝访问(403)'
                break
            case 404:
                message = '请求出错(404)'
                break
            case 500:
                message = '服务器错误(500)'
                break
            case 501:
                message = '服务未实现(501)'
                break
            case 502:
                message = '网络错误(502)'
                break
            case 503:
                message = '服务不可用(503)'
                break
            default:
                message = `连接出错(${state})!`
        }
        return `${message},请检查网络或联系网站管理员!`
    }

    // 添加请求拦截器
    axios.interceptors.request.use( config =>  {
    // 在发送请求之前做些什么

   // header 配置 Token 判断Token是否过期 没过期则正常处理 过期则发起刷新Token的请求拿到新的Token保存
        config.headers.Authorization = null;
        // if (store.getters.token) {
     // config.headers['token'] = getToken()
    //}
       //else{
       // alert("Token已失效")
     // }
        return config;
    }, function (error) {
        // 对请求错误做些什么
        return Promise.reject(error);
    });

    // 添加响应拦截器
    axios.interceptors.response.use((res) => {
        // 对响应数据做点什么
        const status = res.status;
        let msg = ''
        if (status < 200 || status >= 300) {
            // 处理http错误,抛到业务代码
            msg = showResState(status)
            
            if (typeof res.data === 'string') {
               res.data = { msg }
            } else {
               res.data.msg = msg
            }
        }
        return res;
    }, function (error) {
        // 对响应错误做点什么
        return Promise.reject(error);
    });

    // 1. 执行异步ajax请求
    const instance = axios({
        // `baseURL` 将自动加在 `url` 前面,除非 `url` 是一个绝对 URL。
        // 它可以通过设置一个 `baseURL` 便于为 axios 实例的方法传递相对 URL
        baseURL: BaseUrl,

        // `url` 是用于请求的服务器
        url: url,

        // `method` 是创建请求时使用的方法
        method: method || 'get',

        // mode: 'cors',
        // cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached

        // `headers` 是即将被发送的自定义请求头
        headers: {...defaultHeaders},

        // `transformRequest` 允许在向服务器发送前,修改请求数据
        // 只能用在 'PUT', 'POST' 和 'PATCH' 这几个请求方法
        // 后面数组中的函数必须返回一个字符串,或 ArrayBuffer,或 Stream
        transformRequest: [function (data, headers) {
            // 对 data 进行任意转换处理
            return data;
        }],

        // `transformResponse` 在传递给 then/catch 前,允许修改响应数据
        transformResponse: [function (data) {
            // 对 data 进行任意转换处理
            return data;
        }],

        // `params` 是即将与请求一起发送的 URL 参数
        // 必须是一个无格式对象(plain object)或 URLSearchParams 对象
        params: method === 'get' ? params || {} : {},

        // `paramsSerializer` 是一个负责 `params` 序列化的函数
        paramsSerializer: function(params) {
            return Qs.stringify(params, {arrayFormat: 'brackets'})
        },

        // `data` 是作为请求主体被发送的数据
        // 只适用于这些请求方法 'PUT', 'POST', 和 'PATCH'
        // 在没有设置 `transformRequest` 时,必须是以下类型之一:
        // - string, plain object, ArrayBuffer, ArrayBufferView, URLSearchParams
        // - 浏览器专属:FormData, File, Blob
        // - Node 专属: Stream
        data: method === 'post' ? params || {} : {},

        // `timeout` 指定请求超时的毫秒数(0 表示无超时时间)
        // 如果请求话费了超过 `timeout` 的时间,请求将被中断
        timeout: 0,

        // `withCredentials` 表示跨域请求时是否需要使用凭证
        withCredentials: false, // default 为true则产生跨域,跨域携带cookie

        // `responseType` 表示服务器响应的数据类型,可以是 'arraybuffer', 'blob', 'document', 'json', 'text', 'stream'
        responseType: 'json', // default
    });

    return new Promise((resolve, reject) => {
        instance.then(response => {
            // 2. 如果成功了, 调用resolve(value)
            resolve(response);
        })
            .catch(error => {
                // 3. 如果失败了, 不调用reject(reason), 而是提示异常信息
                reject(error)
            }).finally(() => {
        })
    });
}

// GET 请求 get 下 params 为查询参数
export const Get = (url,params={},headers={}) => {
    return Axios(url,'get',params,headers)
}

// POST 请求 post 下 params 为body参数, 如果 post 下既需要传查询参数也需要传实体参数,则查询参数配置在 url 中
export const Post = (url,params={},headers={}) => {
    return Axios(url,'post',params,headers)
}
  • 2
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
axios是现在前端开发中最主流的网络请求库之一,常用于请求后端API接口。虽然axios本身已提供了很好的配置及封装接口,但在实际项目开发中,我们还是需要针对项目的需要进行一些额外的封装和配置。 常用配置 1. baseURL:设置默认请求的url,方便统一管理。 2. timeout:设置请求超时时间。 3. withCredentials:设置是否携带cookie。 4. headers:设置请求头信息,如token等。 5. responseType:设置返回数据的类型。 常用封装 1. 请求拦截器:在请求发送之前进行一些处理,如设置请求头,loading等。 ``` axios.interceptors.request.use(config => { // do something return config; }, error => { return Promise.reject(error) }); ``` 2. 响应拦截器:在请求返回之后进行一些处理,如对返回状态码做统一处理。 ``` axios.interceptors.response.use(response => { // do something return response; }, error => { return Promise.reject(error) }); ``` 3. 错误处理:对接口请求出错进行统一处理,如弹窗提示等。 ``` function errorHandler(error) { // do something return Promise.reject(error); } axios.get(url).then(response => { // do something }).catch(error => { errorHandler(error); }); ``` 4. 封装请求方法:根据具体场景,将常用的请求方法进行封装,方便调用。 ``` function get(url, params) { return axios.get(url, { params }) } function post(url, data) { return axios.post(url, data) } ``` 5. 配置化封装:根据项目需要,将axios的配置及封装放到一个统一的文件中,方便管理。 ``` import axios from 'axios'; import qs from 'qs'; // 设置默认请求url axios.defaults.baseURL = process.env.VUE_APP_BASE_URL; // 请求拦截器 axios.interceptors.request.use(config => { // do something return config; }, error => { return Promise.reject(error) }); // 响应拦截器 axios.interceptors.response.use(response => { // do something return response; }, error => { return Promise.reject(error) }); // 封装请求方法 function get(url, params) { return axios.get(url, { params }) } function post(url, data) { return axios.post(url, qs.stringify(data)) } export default { get, post } ``` 综上所述,axios的配置及封装对于提高开发效率和项目的可维护性非常重要。在实际项目开发中,我们需要根据具体需要对axios进行适当的封装和配置,使其更符合项目的实际需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码上十七

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值