axios库学习笔记

使用网络请求库会方便很多,一般不需要自己来原生封装
如果要原生封装,去找学后端时的封装代码和相关笔记

认识axios库

axios–ajax i/o system

功能特点:
在浏览器中发送XMLHttpRequests请求,兼容性好
在 nodejs 中发送 http请求
支持 Promise API拦截请求和响应
转换请求和响应数据

axios发送请求(重要)

先安装axiosnpm install axios
导入axiosimport axios from 'axios'
然后就能使用了

  1. axios支持很懂请求方式
    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]])
  2. 常见的配置选项
    请求地址 url: ‘/user’
    请求类型 method: ‘get’.
    请根路径 baseURL: ‘http://www.mt.com/api
    请求前的数据处理 transformRequest:[function(data){}],
    请求后的数据处理 transformResponse: [function(data){}].
    自定义的请求头 headers:{‘x-Requested-With’:’XMLHttpRequest’}
    URL查询对象 params:{ id:12 }
    查询对象序列化函数
    paramsSerializer: function(params){ }口request body
    data: { key: ‘aa’},
    超时设置 timeout: 1000,
  3. 有时可能需求同时发送两个请求
    使用axios.all,可以放入多个请求的数组.
    axios.all([])返回的结果是一个数组,使用 axios.spread 可将数组 [res1,res2]展开为 res1,res2
    只有两个请求都有结果,才会进行then回调
  4. 代码演示
    有用的数据一般都在res.data
    浏览器输入地址敲回车能直接拿到数据的都是get请求
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    import { createApp } from 'vueimport axios from 'axiosimport App from './App.vue'
    createApp(App).mount('#app')

    //1.发送request请求
    axios.request({
    url:"http://123.207.32.32:8000/home/multidata"
    method:"get"
    }).then(res =>{
    console.log("res:",res.data)
    })
    //2. 发送get请求
    axios.get('https://api.example.com/data')
    .then(response => {
    console.log('响应数据:', response.data);
    })
    .catch(error => {
    console.error('请求失败:', error);
    });
    //3. 发送post请求
    axios.post('https://api.example.com/submit', {
    name: 'Alice',
    age: 25
    })
    .then(response => {
    console.log('响应数据:', response.data);
    })
    .catch(error => {
    console.error('请求失败:', error);
    });
    //自定义请求头
    axios.get('https://api.example.com/data', {
    headers: {
    'Authorization': 'Bearer your_token_here',
    'Content-Type': 'application/json'
    }
    })
    .then(response => {
    console.log('响应数据:', response.data);
    })
    .catch(error => {
    console.error('请求失败:', error);
    });
    //带请求头的post请求
    // JavaScript
    axios.post('https://api.example.com/submit', {
    username: 'Alice',
    password: '123456'
    }, {
    headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer your_token'
    }
    })
    .then(response => console.log(response.data))
    .catch(error => console.error(error));

    //使用 Axios 实例(设置 baseURL)
    const api = axios.create({
    baseURL: 'https://api.example.com'
    });

    api.get('/data')
    .then(response => {
    console.log('响应数据:', response.data);
    })
    .catch(error => {
    console.error('请求失败:', error);
    });

axios创建实例

baseURL和公共基础配置

通过axios.defaults.baseURL = baseURL配置baseURL,后续输入地址会自动帮你在baseurl后面进行拼接
使用axios.defaults..可以给axios实例配置公共的基础配置
这样有缺点:应用在所有请求上,不够灵活,后续有解决方式

1
2
3
4
5
6
7
8
9
import {createApp }from 'vueimport axios from 'axiosimport App from './App.vue'
createApp(App).mount('#app')
//baseURL
const baseURL ="http://123.207.32.32:8000"
//给axios实例配置公共的基础配置
axios.defaults.baseURL = baseURL
axios.defaults.timeout = 5000
axios.defaults.headers={}
axios.get("/home/multidata").then(res =>{console.log("res:",res.data)})

axios的创建实例–给单个网络请求进行配置

前面提到的axios.defaults..配置方式有缺点:应用在所有请求上,不够灵活,在实际开发中某些配置可能会不太一样
需要创建单独的实例发送网络请求
看代码就懂了,创建了两个单独的实例发送网络请求:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import {createApp }from 'vueimport axios from 'axiosimport App from './App.vue'
createApp(App).mount('#app')

axios.get("https//xxxxxx")
//创建单独的实例发送网络请求
const instance1 = axios.create({
baseURL = "https//xxxxxx",
timeout = 5000,
headers={}
})

//实例1使用时:
instance1.get("/xxx",{
params:{
name:"nienie"
}
}).then(res=>{
console.log(res.data)
})

//继续创建单独的实例发送网络请求
const instance2 = axios.create({
baseURL = "https//xxxxxx",
timeout = 6000,
headers={}
})

axios拦截器

基础知识

  1. 请求拦截器:
    在请求发送到服务器之前执行
    多用于:添加请求头,比如token
  2. 响应拦截器:
    在服务器返回响应之后、在调用 .then() 或 .catch()之前,执行
    多用于:统一处理响应数据(如解析 JSON);全局错误处理(如 401 未授权、500 服务器错误);关闭加载状态(如 Loading 效果)
  3. 拦截器执行顺序
    请求拦截器按添加顺序依次执行
    响应拦截器按添加顺序的逆序执行(先添加的最后执行)
  4. 拦截器抛出错误Promise.reject(error);
  5. 拦截器的移除
    移除单个拦截器:
    1
    2
    const requestInterceptor = instance.interceptors.request.use(...);
    instance.interceptors.request.eject(requestInterceptor);
    移除所有拦截器
    1
    2
    instance.interceptors.request.clear(); // 移除所有请求拦截器
    instance.interceptors.response.clear(); // 移除所有响应拦截器
  6. 拦截器的优势
    • 代码复用
      通过拦截器,可以将通用逻辑(如 Token 添加、错误处理)集中管理,避免重复代码。
    • 统一处理逻辑
      所有请求/响应都会经过拦截器,便于统一处理认证、日志、错误提示等。
    • 提升可维护性
      修改拦截器逻辑即可影响所有请求/响应,无需修改业务代码。
    • 增强用户体验
      通过拦截器可以实现全局的 Loading 效果、错误提示,提升用户交互体验。

对实例配置拦截器(看代码看下面完整版的)

下面两个拦截器都有俩个回调函数,如果发送成功回调前面的同时回调一个config,可以在这里进行判断,很灵活;发送失败回调后面的
请求拦截器axios.interceptors.request.use(config=>{return config},err=>{return err})
响应拦截器axios.interceptors.response.use(res=>{return res},err=>{return err})

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
axios.interceptors.request.use((config)=>{
console.log("请求成功的拦截")
//开始loading的动画
//对配置文件进行修改
},(err)=>{
console.log("请求失败的拦截")
return err
})
axios.interceptors.response.use((res)=>{
console.log("响应成功的拦截")
//结束loading的动画
//对数据进行转化,再返回数据
return res.data
},(err)=>{
console.log("响应失败的拦截")
return err
})

拦截器完整代码示例(重要)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
import axios from 'axios';

// 创建实例
const instance = axios.create({
baseURL: 'https://api.example.com',
timeout: 5000
});

// 请求拦截器
instance.interceptors.request.use(
config => {
const token = localStorage.getItem('token');
if (token) {
//加到请求头(config.headers)中的 Authorization 字段里
config.headers.Authorization = `Bearer ${token}`;
}
return config;// 必须返回 config,否则请求无法发送
},
error => {
return Promise.reject(error);// 抛出错误
}
);

// 响应拦截器
instance.interceptors.response.use(
response => {
// 响应成功,统一处理响应数据
if (response.status === 200) {
return response.data;
} else {
return Promise.reject(new Error(`HTTP 错误: ${response.status}`));
}
},
error => {
if (error.response) {
// 服务器返回了错误响应(如 401、404、500)
console.error('服务器错误:', error.response.status, error.response.data);
} else if (error.request) {
// 请求已发出,但未收到响应(如网络断开)
console.error('请求无响应:', error.request);
} else {
// 其他错误(如请求配置错误)
console.error('请求异常:', error.message);
}
return Promise.reject(error);
}
);

export default instance;

应用场景

拦截器全局错误处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 响应拦截器中统一处理错误
instance.interceptors.response.use(
response => response,
error => {
if (error.response.status === 401) {
// 未授权:跳转到登录页
router.push('/login');
} else if (error.response.status >= 500) {
// 服务器内部错误:提示用户
alert('服务器出现异常,请稍后再试');
}
return Promise.reject(error);
}
);

显示加载状态

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 请求拦截器中开启 Loading
instance.interceptors.request.use(config => {
showLoading(); // 自定义的 Loading 显示方法
return config;
});

// 响应拦截器中关闭 Loading
instance.interceptors.response.use(
response => {
hideLoading(); // 自定义的 Loading 关闭方法
return response;
},
error => {
hideLoading();
return Promise.reject(error);
}
);

自动刷新 Token

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 当收到 401 错误时,尝试刷新 Token
instance.interceptors.response.use(
response => response,
async error => {
if (error.response.status === 401) {
try {
const newToken = await refreshAccessToken(); // 调用刷新 Token 接口
localStorage.setItem('token', newToken);
error.config.headers.Authorization = `Bearer ${newToken}`;
return instance(error.config); // 重新发送请求
} catch (refreshError) {
console.error('刷新 Token 失败', refreshError);
return Promise.reject(refreshError);
}
}
return Promise.reject(error);
}
);

fetch学习笔记

Fetch发送POST请求

Fetch 发送 POST 请求需要配置 method、headers和body
比如设置method为POST,headers指定Content-Type为 JSON,body用JSON.stringify转换数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
fetch("https://api.example.com/data", {
method: "POST",
headers: {
"Content-Type": "application/json"
'Authorization': 'Bearer your_token'
},
body: JSON.stringify({
username: 'Alice',
password: '123456'
})
})
.then(response => {
if (!response.ok) throw new Error("HTTP error");
return response.json();
})
.then(data => console.log(data))
.catch(error => console.error(error));

用typescript发送网络请求

JavaScript 与 TypeScript 在网络请求中的差异

  1. 类型检查

    • JavaScript:动态类型,无需显式声明变量类型,但容易因类型错误导致运行时问题。
    • TypeScript:静态类型,编译时检查类型,减少错误。例如,定义请求头时,TS 可提示字段类型
      1
      2
      3
      4
      const headers: { [key: string]: string } = {
      'Content-Type': 'application/json',
      'Authorization': 'Bearer token'
      };
  2. Axios与Fetch的兼容性 (新知识点)
    Axios 和 Fetch 的代码在JS和TS中均可直接使用,但TS会提供更好的开发体验(如自动补全、类型提示)
    Axios在TS中可结合类型定义文件(如 @types/axios),增强类型安全 (新知识点)

ts中用axios和fetch发送post请求

  1. 使用 Axios

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    // TypeScript
    interface User {
    username: string;
    password: string;
    }
    axios.post<User>('https://api.example.com/submit', {
    username: 'Alice',
    password: '123456'
    }, {
    headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer your_token'
    }
    })
    .then(response => console.log(response.data))
    .catch(error => console.error(error));
  2. 使用fetch

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    fetch('https://api.example.com/submit', {
    method: 'POST',
    headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer your_token'
    },
    body: JSON.stringify({
    username: 'Alice',
    password: '123456'
    })
    })
    .then(response => response.json() as Promise<{ success: boolean }>)
    .then(data => console.log(data))
    .catch(error => console.error(error));

ajax相关网络请求问题

AJAX、fetch与axios的关系

AJAX是一种技术概念,指在不重新加载整个页面的情况下与服务器交换数据并更新部分网页的技术
Axios和Fetch是AJAX的具体实现
Fetch是现代浏览器实现AJAX的方式之一,AJAX是广义的技术概念

  • AJAX实现方式:
    • 原始实现:XMLHttpRequest (XHR)对象
    • 现代实现:fetch API
    • 第三方库:axios、jQuery.ajax等

代码示例

AJAX(原生 XMLHttpRequest)

1
2
3
4
5
6
7
8
9
10
11
12
13
const xhr = new XMLHttpRequest();
xhr.open("GET", "https://api.example.com/data");
xhr.onload = () => {
if (xhr.status === 200) {
console.log(JSON.parse(xhr.responseText));
} else {
console.error("请求失败");
}
};
xhr.onerror = () => {
console.error("网络错误");
};
xhr.send();

Axios

1
2
3
axios.get("https://api.example.com/data")
.then(response => console.log(response.data))
.catch(error => console.error(error));

Fetch

1
2
3
4
5
6
7
fetch("https://api.example.com/data")
.then(response => {
if (!response.ok) throw new Error("HTTP error");
return response.json();
})
.then(data => console.log(data))
.catch(error => console.error(error));

fetch和axios比较

fetch是浏览器原生API,而axios是第三方库。

比较它们的兼容性、自动错误处理、拦截器支持、取消请求等特性:
axios自动处理HTTP错误状态码,而fetch需要手动检查响应状态。此外,axios支持拦截器,适合需要统一处理请求和响应的场景,而fetch更轻量,适合简单用例

fetch和axios比较
fetch:轻量级项目、需要最小化依赖、兼容现代浏览器
axios:复杂项目(如需要拦截器、自动错误处理)、兼容旧浏览器(如 IE11)、自动解析JSON

如何取消 Axios 或 Fetch 的请求

Axios 和 Fetch 都可以通过 AbortController 取消请求。比如,在发起请求时传入 signal,之后调用 controller.abort() 即可终止请求
Axios:使用 CancelToken 或 AbortController

1
2
3
4
5
const controller = new AbortController();
axios.get("/api/data", {
signal: controller.signal
});
controller.abort(); // 取消请求

Fetch:使用 AbortController

1
2
3
4
5
const controller = new AbortController();
axios.get("/api/data", {
signal: controller.signal
});
controller.abort(); // 取消请求

Fetch 和 Axios 是否支持 async/await

两者都支持 async/await,因为它们返回的是 Promise
async/await是JavaScript的语法,只要函数返回Promise,就可以用 await 等待结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// Fetch + async/await
async function fetchData() {
try {
const response = await fetch("https://api.example.com/data");
const data = await response.json();
console.log(data);
} catch (error) {
console.error(error);
}
}

// Axios + async/await
async function fetchData() {
try {
const response = await axios.get("https://api.example.com/data");
console.log(response.data);
} catch (error) {
console.error(error);
}
}

Axios 如何统一处理所有请求的错误

“Axios 的响应拦截器可以统一处理所有请求的错误。
比如在拦截器中打印错误信息,或者跳转到登录页(如 401 错误)

1
2
3
4
5
6
7
8
// 响应拦截器
axios.interceptors.response.use(
response => response,
error => {
console.error("请求失败", error.response?.data || error.message);
return Promise.reject(error);
}
);