Skip to content
快速预览

axios初步认识

✍️ w 🕒 2023-10-13 00:51:20(2 minutes ago) 🔗 C.前端工程化

下面是常用的 axios 方法和属性

类别方法/属性描述
基本方法axios.request(config)用于发起请求
axios.get(url[, config])发起 GET 请求
axios.delete(url[, config])发起 DELETE 请求
axios.head(url[, config])发起 HEAD 请求
axios.post(url[, data[, config]])发起 POST 请求
axios.put(url[, data[, config]])发起 PUT 请求
axios.patch(url[, data[, config]])发起 PATCH 请求
并发处理axios.all(iterable)处理多个并发请求 ,随着 ES6 和后续版本中 Promise.all() 的普及,许多开发者发现直接使用 Promise.all() 更为直观和方便
axios.spread(callback)分割并发响应的结果 ,随着 ES6 和后续版本中 Promise.all() 的普及,许多开发者发现直接使用 Promise.all() 更为直观和方便
实例axios.create([config])创建一个新的 axios 实例
拦截器axios.interceptors.request.use(success[, error])添加请求拦截器
axios.interceptors.response.use(success[, error])添加响应拦截器
默认配置axios.defaults查看或修改默认配置
取消请求axios.CancelToken创建取消令牌
axios.isCancel(value)判断值是否为取消的请求
响应结构data, status, statusText, headers, config, request响应的各个部分
默认值axios.defaults.baseURL设置默认的 baseURL
axios.defaults.timeout设置请求的超时时间
axios.defaults.headers设置默认的请求头
  • config 属性介绍
属性描述示例
url用于请求的服务器URL/user
method创建请求时使用的方法get
baseURL将自动加在 url 前面的基础URLhttps://some-domain.com/api/
transformRequest在向服务器发送前,修改请求数据的函数[function (data, headers) { return data; }]
transformResponse在传递给 then/catch 前,允许修改响应数据的函数[function (data) { return data; }]
headers自定义请求头{'X-Requested-With': 'XMLHttpRequest'}
params与请求一起发送的URL参数{ ID: 12345 }
paramsSerializer用于序列化params的函数function (params) { return Qs.stringify(params, {arrayFormat: 'brackets'}) }
data作为请求体被发送的数据 (示例1){ firstName: 'Fred' }
data作为请求体被发送的数据 (示例2)'Country=Brasil&City=Belo Horizonte'
timeout指定请求超时的毫秒数1000
withCredentials表示跨域请求时是否需要使用凭证false
adapter允许自定义处理请求的函数function (config) { /* ... */ }
authHTTP Basic Auth{ username: 'janedoe', password: 's00pers3cret' }
responseType表示浏览器将要响应的数据类型json
responseEncoding表示用于解码响应的编码 (Node.js 专属)utf8
xsrfCookieNamexsrf token 的值,被用作 cookie 的名称XSRF-TOKEN
xsrfHeaderName带有 xsrf token 值的http 请求头名称X-XSRF-TOKEN
onUploadProgress允许为上传处理进度事件的函数function (progressEvent) { /* ... */ }
onDownloadProgress允许为下载处理进度事件的函数function (progressEvent) { /* ... */ }
maxContentLength定义了node.js中允许的HTTP响应内容的最大字节数2000
maxBodyLength定义允许的http请求内容的最大字节数 (仅Node)2000
validateStatus定义了对于给定的 HTTP状态码是 resolve 还是 reject promise的函数function (status) { return status >= 200 && status < 300; }
maxRedirects定义了在node.js中要遵循的最大重定向数5
socketPath在node.js中使用的UNIX套接字null
httpAgent & httpsAgent在node.js中用于执行http和https请求的自定义代理new http.Agent({ keepAlive: true })
proxy定义了代理服务器的配置{ protocol: 'https', host: '127.0.0.1', port: 9000, auth: { username: 'mikeymike', password: 'rapunz3l' } }
cancelToken取消请求的tokennew CancelToken(function (cancel) { })
decompress指示是否自动解压缩响应体true

简单封装进一步了解

  1. 首先,我们引入了axios库。
  2. 使用axios.create方法创建了一个axios实例,并为其设置了基础URL和请求超时时间。
  3. 使用interceptors.request.use方法添加了请求拦截器,可以在发送请求之前进行一些操作,例如添加token。
js
// 添加请求拦截器
axios.interceptors.request.use(function (config) {
    // 在发送请求之前做些什么
    return config;
  }, function (error) {
    // 对请求错误做些什么
    return Promise.reject(error);
  });
  1. 使用interceptors.response.use方法添加了响应拦截器,可以对返回的响应数据进行处理,例如根据响应码进行不同的操作。
  • 成功的回调:当请求成功返回(即HTTP状态码为2xx)时,这个函数会被调用。这个函数接受一个参数,即服务器的响应对象,并且必须返回一个值或Promise。返回的值将作为请求的响应传递给后续的 then 方法。

  • 错误的回调:axios将所有在范围外的状态码(即小于200或大于299)视为错误,当请求返回一个错误响应(例如HTTP状态码为4xx或5xx)或由于其他原因(例如网络问题)导致请求失败时,这个函数会被调用。这个函数接受一个错误对象作为参数,并且必须返回一个错误或Promise。返回的错误将被传递给后续的 catch 方法。

js
// 添加响应拦截器
axios.interceptors.response.use(function (response) {
    // 2xx 范围内的状态码都会触发该函数。
    // 对响应数据做点什么
    return response;
  }, function (error) {
    // 超出 2xx 范围的状态码都会触发该函数。
    // 对响应错误做点什么
    return Promise.reject(error);
  });
  • 设置指定错误状态码使用 axios.defaults.validateStatus 配置选项来自定义这个行为
js
validateStatus: function (status) {
  return status >= 200 && status < 300; // 默认的实现
}

案例一

导出了这个axios实例,这样在其他地方就可以直接使用这个已经配置好的axios实例进行请求。

javascript
// 引入axios库
import axios from 'axios';

// 创建axios实例
const instance = axios.create({
  baseURL: 'https://api.example.com',  // 基础URL,可以根据实际情况进行修改
  timeout: 5000,  // 请求超时时间
});

// 请求拦截器
instance.interceptors.request.use(
  config => {
    // 在发送请求之前做些什么,例如添加token
    // config.headers['Authorization'] = 'Bearer ' + token;
    return config;
  },
  error => {
    // 对请求错误做些什么
    return Promise.reject(error);
  }
);

// 响应拦截器
instance.interceptors.response.use(
  response => {
      // 2xx 范围内的状态码都会触发该函数。
      // 对响应数据做点什么
      return response.data.data;  
  },
  error => {
    // 超出 2xx 范围的状态码都会触发该函数。
    // 对响应错误做点什么
    return Promise.reject(error);
  }
);

export default instance;

案例二

一些其他详细封装

js
/* 
  axios二次封装:把每一次基于axios发送请求的公共部分进行提取
    + axios.defaults.xxx
    + axios.interceptors.request/response  拦截器 
 */
import axios from 'axios';
import qs from 'qs';
const isPlainObject = function isPlainObject (obj) {
  let proto, Ctor;
  if (!obj || Object.prototype.toString.call(obj) !== "[object Object]") return false;
  proto = Object.getPrototypeOf(obj);
  if (!proto) return true;
  Ctor = proto.hasOwnProperty('constructor') && proto.constructor;
  return typeof Ctor === "function" && Ctor === Object;
};

// 请求URL地址没有加前缀,则默认把BASE-URL加上;如果请求时候,自己设置前缀了,则以自己写的为主;
// 真实开发的时候,我们项目有各种不同的环境「开发、测试、灰度、生产」:我们需要针对不同的环境,有不同的BASE-URL
//  1)在运行编译的时候,设置环境变量
//    + 安装cross-env插件   $ npm i cross-env
//    + package.json的scripts中做处理
//      开发环境 serve:"cross-env NODE_ENV=development vue-cli-service serve",
//      生产环境 build:"cross-env NODE_ENV=production vue-cli-service build"
//  2)在代码中获取环境变量的值,根据不同值,设置不同的BASE-URL
let env = process.env.NODE_ENV || 'development',
  baseURL = '';
switch (env) {
  case 'development':
    baseURL = 'http://127.0.0.1:9999';
    break;
  case 'production':
    baseURL = 'http://api';
    break;
}
axios.defaults.baseURL = baseURL;

// 一些可以提取的小东西:超时时间 & CORS跨域中是否允许携带资源凭证(例如:cookie)
//   + 客户端的withCredentials:true,那么服务器端也要设置为允许
axios.defaults.timeout = 10000;
axios.defaults.withCredentials = true;

// 请求参数 拦截重新拼接的案例
// POST系列请求中:请求主体中传递给服务器的信息,项目要求需要是URLENCODED格式;(强行无论请求方式是什么都是URLENCODED格式)
// 当代浏览器中,我们请求主体传递给服务器的格式是啥,浏览器会自动在请求头中,更新Content-Type!
axios.defaults.transformRequest = data => {
  // 只有我们写的DATA是一个纯粹的对象,才需要按需求处理
  if (isPlainObject(data)) data = qs.stringify(data);
  return data;
};

// 自己规定,服务器返回的状态码,值是多少算是请求成功
//   成功:服务器正常返回响应信息,且返回的HTTP状态码是经过validateStatus校验通过的
//   失败:
//   + 服务器有返回的信息,但是返回的HTTP状态码并没有经过validateStatus的校验
//   + 请求超时或者请求中断  reason.code==='ECONNABORTED'
//   + 服务器没有返回任何信息「可能是断网了」
//   + ...
axios.defaults.validateStatus = status => {
  return status >= 200 && status < 400;
};

// 请求拦截器:在axios内部已经把config的那些配置项处理差不多了,并且打算按照配置项,向服务器发送请求之前进行拦截;
// 拦截目的是把配置项中的一些信息再改改!
axios.interceptors.request.use(config => {
  // 常见需求:在每一次发送请求的时候,通过请求头把token信息传递给服务器
  const token = localStorage.getItem('token');
  if (token) {
    config.headers['Authorization'] = token;
  }
  return config;
});

// 响应拦截器:onfulfilled/onrejected,发生在请求成功/失败,在业务层具体.then/catch之前进行拦截处理
axios.interceptors.response.use(response => {
  // 请求成功:一般我们会返回响应主体信息
  return response.data;
}, reason => {
  // 请求失败:一般我们会做统一的错误提示
  if (reason && reason.response) {
    let response = reason.response;
    // 有响应信息,但是状态码不对,我们根据不同的状态码做不同的提示
    switch (response.status) {
      case 400:
        // ...
        break;
      case 401:
        // ...
        break;
      case 404:
        // ...
        break;
    }
  } else {
    if (reason && reason.code === 'ECONNABORTED') {
      // 请求超时或者中断
    }
    if (!navigator.onLine) {
      // 断网了
    }
  }
  return Promise.reject(reason);
});

export default axios;

Released under the MIT License.