AXIOS

135 阅读6分钟

一、axios基本概念

1.1 定义

定义

Axios,是一个基于Promise的网络请求库,作用于node.js和浏览器中。

在服务端它使用原生node.js http模块,在客户端(浏览器)使用XMLHttpRequest。

Axios是一个基于promise的HTTP库,可以用在浏览器和node.js中。

原理

axios本质上是对原生XHR的封装,只不过是Promise的实现版本,符合最新的ES规范。

注:XHR 注入技术是通过XMLHttpRequest来获取javascript的。

1.4 安装 Axios

npm install axios

也可直接使用cdn,通过script标签引入。

二、axios 主要特点

  • 从浏览器中创建 XMLHttpRequest
  • 从node.js创建 http请求
  • 支持 Promise API
  • 拦截请求和响应
  • 转换请求和响应数据
  • 取消请求
  • 自动转换JSON数据
  • 客户端支持防御CSRF(跨域请求伪造)

三、axios 基本使用(常用语法)

3.1 支持箭头函数

(1)普通函数写法

axios.get('./server/user').then(function(response) {
    console.log(response)
}).catch(function(error) {
    console.log(error)
})

(2)箭头函数写法

axios.get('./server/user').then(response => {
    console.log(response)
}).catch(error => {
    console.log(error)
})

3.2 常见配置项

  • (1)method 创刊请求的方法,默认值get,不区分大小写(也支持axios.get / axios.post 写法)
  • (2)url:请求的服务器 URL
  • (3)baseURL: 自动添加在 url 前面,除非url是绝对值
  • (4)data:请求体用于发送的数据,用于post、put、delete 和 patch 请求方法
  • (5)headers:自定义请求头
  • (6)params:与请求一起发送的 URL参数,是一个对象
  • (7)timeout:指定请求超时毫秒数

示例代码

axios({
    // 请求方式,不区分大小写
    method: 'post',
    
    // 基础url,最终请求的url是,baseURL+url 拼接
    baseURL,
    url: 'ABJ?_=',
    
    //请求超时,单位毫秒,默认0,不超时。 
    timeout: 1000,
    
    //响应数据类型,默认json
    responseType: 'json',

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

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

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

}).then(response => {
    // 正确情况处理
    let res = response ? response.data : '';
    console.log('正常', res);
}).catch(error => {
    // 报错情况处理
    let message = error ? error.message : '';
    console.log('报错', message)
}).then(() => {
    console.log('总是执行');
})

返回体

  • config 配置对象
  • data 响应体内容
  • headers 响应头
  • request 发送请求时创建的底层 XMLHttpRequest 对象
  • status 状态码
  • statusText 状态解析,如 'OK'

返回体.png

3.3 其他常见语法

3.3.1 拦截器(interceptors)

1.请求拦截器(Request Interceptors)
  • 真正发送请求前执行的回调函数
  • 可对请求进行检查或配置进行特定处理
  • 失败的回调函数传递的是 error
  • 成功的回调函数传递的是 config(也必须是)
2.响应拦截器(Reponse Interceptors)
  • 请求得到响应后执行的回调函数
  • 可对响应数据进行特定处理
  • 成功的回调函数传递的是 response
  • 失败的回调函数,传递的默认是 error
3.拦截器代码示例
import axios from 'axios';

const instance = axios.create({
    // 设置 baseURL
    baseURL: 'htts://www.aaa.com/api/server/app',
    // 设置请求超时
    timeout: 2000
});

// 1.添加请求拦截器
instance.interceptors.request.use(
    function(config) {
        // 在发送前做的事情
        // 如,可以添加认证令牌
        // 假设token存在 localStorage 中
        const token = localStorage.getItem('userToken');
        if(token) {
            config.headers.Authorization = `Bearer ${token}`
        }
        // 如果没有返回 config,请求会被拦截器拦截下来,不会发送
        return config;
    },
    function(error) {
        // 请求发送错误时,触发的函数
        // 可以处理错误,比现实错误信息给用户
        return Promise.reject(error)
    }
);

// 2.添加响应拦截器
instance.interceptors.response.use(
    response => {
        // 对响应数据做点什么
        // 例如,检查响应中是否有自定义的错误处理
        if(response.data.error) {
            return Promise.reject(new Error(response.data.error));
        }
        // 重要的是,需要返回响应对象,否则请求链会中断
        return response;
    },
    error => {
        // 对响应错误做点什么
        if(error.response) {
            // 服务器响应了请求,但返回了错误的 HTTP 状态码
            // 可根据不同 status 来处理错误,404 找不到页面,500 服务器内部错误
            console.log(`Error Status: ${error.response.status}`);
            console.log(error.response.data);
            
            // 可以抛出一个错误,以便在请求的 then 链中捕获
            return Promise.reject(error)
        }else if(error.request) {
            // 请求已发出,但没收到响应
            console.log(error.request);
            
            return Promise.reject(error);
        } else {
            // 设置请求时触发了错误
            console.log('Error', error.message);
            
            return Promise.reject(error);
        }
        // 注意:这里也必须返回一个 Promise 对象,否则请求链会中断
    }
);

// 使用实例发送请求
instance.get('./test1').then(
    response => {
        // 正常情况处理
        console.log(response)
    }
).catch(
    error => {
        // 错误情况处理
        console.log(error)
    }
).then(
    // 总是执行
)

export default instance;

3.3.2 转换器

使用 Axios 进行 HTTP 请求时,可能需要对请求的数据或响应的数据进行预处理或后处理。

Axios 提供了请求拦截器和响应拦截器功能,以及通过配置 transformRequest 和 transformResponse 选项来直接转换请求和响应数据。这些功能可以视为“转换器”,它们允许你在数据发送或接收之前对其进行处理。

Axios官方API中没有直接称为 "转换器"(transformers)的功能,但是可以通过拦截器或者直接在请求/响应处理中模拟这一行为。

  • 请求转换器: 用于在发送请求前修改请求数据。例如,将JSON对象序列化为JSON字符串、添加一些通用请求头(或自定义请求头)。
  • 响应转换器: 用于在接收响应后修改响应数据。例如,将响应体json字符串解析为js对象或数组的函数,转换响应数据的格式以符合应用程序的需求。

实际开发中,需要根据API的特定要求和应用程序的需求来编写这些转换逻辑。

请求转换,示例

// 创建一个 Axios 实例  
const axiosInstance = axios.create({
    baseURL: 'https://api.example.com',
    // 其他配置...  
});

// 请求拦截器(请求转换器)  
axiosInstance.interceptors.request.use(
    config => {
        // 假设我们要在发送前将 config.data 转换为 JSON 字符串  
        // 注意:axios 通常会为你做这件事,但这里只是为了演示  
        if (config.data && typeof config.data === 'object') {
            config.data = JSON.stringify(config.data);
            // 设置请求头,告诉服务器我们发送的是 JSON  
            config.headers['Content-Type'] = 'application/json';
        }
        // 你可以在这里添加更多的转换逻辑  
        return config;
    },
    error => {
        // 处理请求错误  
        return Promise.reject(error);
    }
);

// 使用实例发起请求  
axiosInstance.post('/some-endpoint', { foo: 'bar' }).then(response => {
    console.log(response.data);
})
.catch(error => {
    console.error(error);
});

响应转换,示例

// 响应拦截器(响应转换器)  
axiosInstance.interceptors.response.use(
    response => {
        // 假设服务器返回了一个包含 data 属性的对象  
        // 其中 data 是一个 JSON 字符串,我们需要将其解析为 JavaScript 对象  
        // 但通常,axios 已经为你做了这件事  
        // 这里只是为了演示如何对响应数据进行进一步处理  
        if (response.data && typeof response.data === 'string' && response.data.startsWith('{')) {
            try {
                response.data = JSON.parse(response.data); // 实际上,这一步可能是多余的  
            } catch (error) {
                // 处理 JSON 解析错误  
                console.error('Error parsing JSON:', error);
            }
        }
        // 你可以在这里添加更多的转换逻辑  
        return response;
    },
    error => {
        // 处理响应错误  
        // 例如,检查响应状态码,并相应地处理错误  
        if (error.response && error.response.status === 404) {
            // 处理 404 错误  
            console.log('Resource not found');
        }
        return Promise.reject(error);
    }
);

3.3.2 使用async/await语法

使用axios库配合 async/await 语法,可以让我们以同步的书写方式写异步代码,能让代码更加清晰易懂。

// 引入axios
const axios = require('axios');

// 异步函数获取数据
async funtion fetchData() {
    try {
        // 使用axios的get方法请求数据,这里以获取JSONPlaceholder的假数据为例  
        const response = await axios.get('https://jsonplaceholder.typicode.com/todos/1');
        // 响应中获取数据
        const data = response.data;
        
        // 可根菌需要对数据进行其他操作
        console.log(data);
    } catch(error) {
        // 处理请求中 可能发生的错误
        console.log('There was an error!', error)
    }
}

// 调用函数
fetchData();

上述代码:

  • fetchData是一个异步函数,使用了 await 关键字来等待 axios.get 请求完成。
  • await 只能在函数内部使用,会暂停 async 函数的执行,等待 Promise 解决(resolve)或拒绝(reject),然后才继续执行 async 函数并返回解决的值或抛出拒绝的原因。
  • 使用 try...catch 语句来捕获并处理可能发生的任何错误。
  • try..catch 是处理异步操作中可能发生的错误的一种常见方式。

注意:在 axios.get 调用前加上 await,意味着JS会在这里暂停执行,直到 axios.get 调用完成(无论成功还是失败),才会继续执行后面的代码。

3.3.3 取消axios请求

Axios的CancelToken是一个用于取消请求的promise。

import axios from 'axios';

// 创建一个CancelToken源
let CancelTokenSource = axios.CancelToken.source();

// 发起一个GET请求
axios.get('/url', {
    // 将CancelToken作为请求的配置传入
    cancelToken: CancelTokenSource.token
}).then(response => {
    console.log(response);
}).catch(error => {
    // 检查是否事取消请求的错误
    if(axios.isCancel)
})
// 封装取消请求的函数
function cancelRequest(cancelTokenSource) {
    if(cancelTokenSource && cancelTokenSource.cancel) {
        cancelTokenSource.cancel('取消请求');
    }
}

let cancelTokenSource = axios.CancelToken.source();

axios.get('https://jsonplaceholder.typicode.com/todos/1', {
    cancelToken: cancelTokenSource.token
}).catch(thrown => {
    if(axios.isCancel(thrown)) {
        console.log('取消', throwm.message)
    } else {
        // 错误处理
    }
});

// 取消请求
cancelRequest(cancelTokenSource);