当前位置: 首页 > news >正文

前端面试六之axios

一、axios简介

        Axios 是一个基于 Promise 的 HTTP 客户端,用于浏览器和 Node.js 环境。在浏览器端,Axios 的底层实现是基于原生的 XMLHttpRequest(XHR)。它对 XHR 进行了封装,增加了 Promise 支持、自动转换 JSON 数据、请求和响应拦截器等功能。在 Node.js 环境中,Axios 使用 http 模块来发起请求。

1.1XHR、Fetch API 和 Axios 的区别

1. XMLHttpRequest (XHR)
  • 定义:XHR 是一个较旧的 API,用于在浏览器中发起网络请求。

  • 工作原理:基于事件驱动,通过监听 onreadystatechange 事件来处理请求状态变化。

  • 优点

    • 兼容性好,支持较旧的浏览器。

    • 提供了丰富的 API,可以实现复杂的网络请求操作。

  • 缺点

    • 基于回调,容易导致回调地狱,代码难以维护。

    • 无法中止请求。

    • 需要手动设置请求头和解析响应。

  • 使用场景:适用于需要兼容旧浏览器的场景。

 Fetch API
  • 定义:Fetch 是一个现代的、基于 Promise 的网络请求接口,用于替代 XHR。

  • 工作原理:基于 Promise,使用 Promise 对象来处理异步请求。

  • 优点

    • 语法简洁,使用 Promise 避免了回调地狱。

    • 支持中止请求(通过 AbortController)。

    • 更好的错误处理。

    • 支持流式传输,适用于大文件上传和下载。

  • 缺点

    • 兼容性较差,在一些较老的浏览器中不支持。

    • 响应处理需要手动调用 .json().text() 等方法。

    • 默认不接受跨域请求,需要通过 CORS 配置。

  • 使用场景:适用于现代 Web 开发,不需要考虑较旧浏览器版本的场景。

3. Axios
  • 定义:Axios 是一个基于 Promise 的 HTTP 客户端,用于浏览器和 Node.js 环境。

  • 工作原理:本质上是对 XHR 的封装,在浏览器端使用 XHR,在 Node.js 中使用 http 模块。

  • 优点

    • 基于 Promise,支持 async/await

    • 自动转换 JSON 数据。

    • 支持请求和响应拦截器。

    • 能够取消请求。

  • 缺点

    • 需要额外引入库。

    • 在一些极端情况下(如超时控制)可能不如原生 Fetch 灵活。

  • 使用场景:适用于需要更丰富的功能(如拦截器、自动数据转换)的场景。

  1.2axios基于 Promise

Axios 的请求返回的是一个 Promise 对象,这使得它能够很方便地进行异步操作的处理。例如,你可以使用 .then() 方法来处理请求成功的情况,使用 .catch() 方法来处理请求失败的情况。比如:

axios.get('/user').then(response => {console.log(response.data); // 处理成功响应}).catch(error => {console.error(error); // 处理错误});

二、演示get和post

<template><div><h1>Axios GET 和 POST 示例</h1><button @click="fetchData">获取数据 (GET)</button><button @click="postData">提交数据 (POST)</button><div v-if="data"><h2>获取的数据:</h2><pre>{{ data }}</pre></div><div v-if="postDataResponse"><h2>POST 请求的响应:</h2><pre>{{ postDataResponse }}</pre></div></div>
</template><script>
import axios from 'axios';export default {data() {return {data: null, // 用于存储 GET 请求的响应数据postDataResponse: null, // 用于存储 POST 请求的响应数据};},methods: {// 发起 GET 请求fetchData() {axios.get('https://jsonplaceholder.typicode.com/posts/1').then(response => {this.data = response.data; // 将响应数据存储到 data 中}).catch(error => {console.error('GET 请求失败:', error);});},// 发起 POST 请求postData() {const postData = {title: 'foo',body: 'bar',userId: 1,};axios.post('https://jsonplaceholder.typicode.com/posts', postData).then(response => {this.postDataResponse = response.data; // 将响应数据存储到 postDataResponse 中}).catch(error => {console.error('POST 请求失败:', error);});},},
};
</script><style>
/* 添加一些简单的样式 */
button {margin-right: 10px;
}
</style>
(1)GET 请求
  • 使用 axios.get 方法发起 GET 请求。

  • 请求的 URL 是 https://jsonplaceholder.typicode.com/posts/1,这是一个公共的测试 API,返回一个模拟的帖子数据。

  • 请求成功后,将响应数据存储到 data 属性中,并在页面上显示。

(2)POST 请求
  • 使用 axios.post 方法发起 POST 请求。

  • 请求的 URL 是 https://jsonplaceholder.typicode.com/posts,同样是一个公共的测试 API。

  • 请求体是一个包含 titlebodyuserId 的对象。

  • 请求成功后,将响应数据存储到 postDataResponse 属性中,并在页面上显示。

使用 async/await

methods: {async fetchData() {try {const response = await axios.get('https://jsonplaceholder.typicode.com/posts/1');this.data = response.data;} catch (error) {console.error('GET 请求失败:', error);}},async postData() {const postData = {title: 'foo',body: 'bar',userId: 1,};try {const response = await axios.post('https://jsonplaceholder.typicode.com/posts', postData);this.postDataResponse = response.data;} catch (error) {console.error('POST 请求失败:', error);}},
},

 三、发送带有请求头和查询参数的请求

<template><div><h1>Axios 请求头和查询参数示例</h1><button @click="fetchWithHeadersAndParams">发送请求</button><div v-if="response"><h2>响应数据:</h2><pre>{{ response }}</pre></div></div>
</template><script>
import axios from 'axios';export default {data() {return {response: null, // 用于存储响应数据};},methods: {// 发送带有请求头和查询参数的 GET 请求fetchWithHeadersAndParams() {// 定义请求头const headers = {'Authorization': 'Bearer your_token_here','Custom-Header': 'CustomValue',};// 定义查询参数const params = {userId: 1,limit: 10,status: 'active',};// 发起请求axios.get('https://jsonplaceholder.typicode.com/posts', {headers: headers, // 添加请求头params: params,  // 添加查询参数}).then(response => {this.response = response.data; // 将响应数据存储到 response 中}).catch(error => {console.error('请求失败:', error);this.response = { error: error.message }; // 如果失败,存储错误信息});},},
};
</script><style>
button {margin-right: 10px;
}
</style>
(1)请求头
  • axios.get 方法中,通过 headers 属性传递自定义请求头。

  • 示例中添加了 AuthorizationCustom-Header 两个请求头。

(2)查询参数
  • axios.get 方法中,通过 params 属性传递查询参数。

  • 查询参数会自动被 Axios 转换为 URL 的查询字符串。例如,params 对象 { userId: 1, limit: 10 } 会被转换为 ?userId=1&limit=10

(3)完整的请求 URL

假设请求头和查询参数都设置好后,最终的请求 URL 会类似于:

https://jsonplaceholder.typicode.com/posts?userId=1&limit=10&status=active

 使用 async/await

methods: {async fetchWithHeadersAndParams() {const headers = {'Authorization': 'Bearer your_token_here','Custom-Header': 'CustomValue',};const params = {userId: 1,limit: 10,status: 'active',};try {const response = await axios.get('https://jsonplaceholder.typicode.com/posts', {headers: headers,params: params,});this.response = response.data;} catch (error) {console.error('请求失败:', error);this.response = { error: error.message };}},
},

四、发送不同格式的请求体

在 Vue 项目中使用 Axios 发送请求时,可以通过配置请求体的格式来满足不同的需求。以下是三种常见的请求体格式的示例:application/x-www-form-urlencodedmultipart/form-dataapplication/json

<template><div><h1>Axios 请求体格式示例</h1><button @click="sendUrlEncoded">发送 URL 编码数据</button><button @click="sendMultipart">发送 Multipart 数据</button><button @click="sendJson">发送 JSON 数据</button><div v-if="response"><h2>响应数据:</h2><pre>{{ response }}</pre></div></div>
</template><script>
import axios from 'axios';export default {data() {return {response: null, // 用于存储响应数据};},methods: {// 发送 URL 编码数据sendUrlEncoded() {const data = new URLSearchParams();data.append('username', 'kimi');data.append('password', '123456');axios.post('https://jsonplaceholder.typicode.com/posts', data).then(response => {this.response = response.data;}).catch(error => {console.error('请求失败:', error);this.response = { error: error.message };});},// 发送 Multipart 数据sendMultipart() {const formData = new FormData();formData.append('file', new Blob(['Hello World'], { type: 'text/plain' }), 'example.txt');formData.append('description', 'This is a test file');axios.post('https://jsonplaceholder.typicode.com/posts', formData, {headers: {'Content-Type': 'multipart/form-data',},}).then(response => {this.response = response.data;}).catch(error => {console.error('请求失败:', error);this.response = { error: error.message };});},// 发送 JSON 数据sendJson() {const data = {title: 'foo',body: 'bar',userId: 1,};axios.post('https://jsonplaceholder.typicode.com/posts', data).then(response => {this.response = response.data;}).catch(error => {console.error('请求失败:', error);this.response = { error: error.message };});},},
};
</script><style>
button {margin-right: 10px;
}
</style>
(1)发送 URL 编码数据
  • 使用 URLSearchParams 构造请求体。

  • Axios 会自动将 URLSearchParams 转换为 application/x-www-form-urlencoded 格式。

  • 示例代码:

    const data = new URLSearchParams();
    data.append('username', 'kimi');
    data.append('password', '123456');axios.post('https://jsonplaceholder.typicode.com/posts', data);
    (2)发送 Multipart 数据
  • 使用 FormData 构造请求体。

  • 需要手动设置请求头 Content-Typemultipart/form-data

  • 示例代码:

    const formData = new FormData();
    formData.append('file', new Blob(['Hello World'], { type: 'text/plain' }), 'example.txt');
    formData.append('description', 'This is a test file');axios.post('https://jsonplaceholder.typicode.com/posts', formData, {headers: {'Content-Type': 'multipart/form-data',},
    });
    (3)发送 JSON 数据
  • 直接发送一个 JavaScript 对象。

  • Axios 会自动将对象序列化为 JSON 格式,并设置请求头 Content-Typeapplication/json

  • 示例代码:

    const data = {title: 'foo',body: 'bar',userId: 1,
    };axios.post('https://jsonplaceholder.typicode.com/posts', data);

    五、axios默认配置项

以下是一些常用的 Axios 默认配置项: 

配置项描述
baseURL基础 URL,请求时会自动拼接
headers请求头,可以设置通用头或特定方法的头
timeout请求超时时间(单位为毫秒)
withCredentials是否允许跨域请求携带凭证(如 cookies)
responseType响应数据类型(如 jsontextarraybuffer 等)
validateStatus定义哪些状态码被视为成功响应
transformRequest请求发送前的数据转换函数
transformResponse响应数据的转换函数

以下是一个完整的示例,展示如何设置全局默认配置和自定义实例默认配置:

// 设置全局默认配置
axios.defaults.baseURL = 'https://api.example.com';
axios.defaults.headers.common['Authorization'] = 'Bearer your_token_here';
axios.defaults.timeout = 3000;// 创建自定义实例
const customInstance = axios.create({baseURL: 'https://api.custom.com',headers: {'Content-Type': 'application/json'}
});// 修改实例的默认配置
customInstance.defaults.timeout = 5000;// 使用全局配置发起请求
axios.get('/user').then(response => {console.log(response.data);
});// 使用自定义实例发起请求
customInstance.get('/custom-user').then(response => {console.log(response.data);
});

1. 全局默认配置

Axios 允许通过 axios.defaults 设置全局默认配置,这些配置将应用于所有通过 axios 发起的请求。以下是一些常见的全局默认配置:

基础 URL (baseURL):为所有请求设置一个基础 URL,请求的 URL 会自动拼接在 baseURL 后面。

axios.defaults.baseURL = 'https://api.example.com';

请求头 (headers):设置通用的请求头或特定方法的请求头。

axios.defaults.headers.common['Authorization'] = 'Bearer your_token_here';
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';

超时时间 (timeout):设置请求的超时时间(单位为毫秒),超过该时间未响应则请求会被中断。

axios.defaults.timeout = 2500; // 2.5 秒

验证状态码 (validateStatus):定义哪些 HTTP 状态码被视为成功响应。

axios.defaults.validateStatus = function (status) {return status >= 200 && status < 300; // 默认值
};

2. 自定义实例默认配置

除了全局配置,Axios 还允许创建自定义实例,并为每个实例设置默认配置。这在项目中需要使用多个不同配置的 Axios 实例时非常有用:

const instance = axios.create({baseURL: 'https://api.example.com',timeout: 3000,headers: {'Authorization': 'Bearer your_token_here'}
});// 修改实例的默认配置
instance.defaults.headers.common['Custom-Header'] = 'CustomValue';

3. 配置的优先级

Axios 的配置会按优先级合并,优先级从低到高依次为:

  1. 库默认值:在 lib/defaults.js 中定义的默认值。

  2. 实例的 defaults 属性:通过 axios.create() 创建的实例的默认配置。

  3. 请求的 config 参数:在每次请求中传递的配置参数。

    const instance = axios.create({timeout: 2500 // 实例默认超时时间
    });instance.get('/longRequest', {timeout: 5000 // 该请求的超时时间覆盖实例默认值
    });

    六、axios响应数据的格式和状态码

在使用 Axios 发起 HTTP 请求时,响应数据的格式和状态码是两个非常重要的部分。Axios 提供了丰富的响应数据结构,同时允许你根据状态码来处理不同的响应情况。 

1. Axios 响应格式

当 Axios 发起请求并收到响应时,它会返回一个响应对象,该对象包含以下属性:

  • data:响应体的内容。Axios 会根据 Content-Type 自动解析响应体。如果是 application/json,它会被解析为 JavaScript 对象。

  • status:HTTP 状态码(如 200404500 等)。

  • statusText:HTTP 状态消息(如 OKNot FoundInternal Server Error 等)。

  • headers:响应头,是一个对象,包含服务器返回的所有响应头。

  • config:请求的配置对象,包含了请求时传递的配置信息。

  • request:原生的请求对象(在浏览器中是 XMLHttpRequest,在 Node.js 中是 http.ClientRequest)。

示例:响应格式

以下是一个示例,展示如何处理 Axios 的响应数据:

import axios from 'axios';axios.get('https://jsonplaceholder.typicode.com/posts/1').then(response => {console.log('响应数据:', response.data); // 响应体内容console.log('状态码:', response.status); // HTTP 状态码console.log('状态消息:', response.statusText); // HTTP 状态消息console.log('响应头:', response.headers); // 响应头console.log('请求配置:', response.config); // 请求配置}).catch(error => {console.error('请求失败:', error);});

2. 状态码处理

HTTP 状态码是服务器对请求的响应状态的描述。常见的状态码包括:

  • 2xx:成功

    • 200 OK:请求成功。

    • 201 Created:请求成功,且服务器创建了新资源。

    • 204 No Content:请求成功,但没有返回内容。

  • 3xx:重定向

    • 301 Moved Permanently:请求的资源已永久移动到新位置。

    • 302 Found:请求的资源临时移动到新位置。

  • 4xx:客户端错误

    • 400 Bad Request:请求格式错误。

    • 401 Unauthorized:未授权,需要认证。

    • 403 Forbidden:禁止访问。

    • 404 Not Found:请求的资源不存在。

  • 5xx:服务器错误

    • 500 Internal Server Error:服务器内部错误。

    • 502 Bad Gateway:网关错误。

    • 503 Service Unavailable:服务不可用。

示例:根据状态码处理响应

以下是一个示例,展示如何根据状态码处理不同的响应情况:

import axios from 'axios';axios.get('https://jsonplaceholder.typicode.com/posts/1').then(response => {console.log('响应数据:', response.data);// 根据状态码处理响应switch (response.status) {case 200:console.log('请求成功:', response.data);break;case 404:console.error('资源未找到');break;case 500:console.error('服务器内部错误');break;default:console.log('其他状态码:', response.status);}}).catch(error => {console.error('请求失败:', error);// 处理错误响应if (error.response) {console.error('状态码:', error.response.status);console.error('状态消息:', error.response.statusText);} else if (error.request) {console.error('请求已发送,但未收到响应');} else {console.error('请求配置错误:', error.message);}});

3. 自定义状态码处理

你可以通过 validateStatus 配置项自定义哪些状态码被视为成功响应。默认情况下,只有 2xx 状态码被视为成功,但你可以修改这个行为:

import axios from 'axios';axios.get('https://jsonplaceholder.typicode.com/posts/1', {validateStatus: function (status) {return status >= 200 && status < 400; // 将 2xx 和 3xx 状态码视为成功}
})
.then(response => {console.log('响应数据:', response.data);
})
.catch(error => {console.error('请求失败:', error);
});

七、Axios 的请求拦截器和响应拦截器

Axios 的请求拦截器和响应拦截器是 Axios 提供的强大功能,用于在请求发送之前和响应返回之后对数据进行处理。它们可以用于多种场景,例如统一设置请求头、添加认证信息、处理错误、格式化响应数据等。

1. 请求拦截器

请求拦截器可以在请求发送之前对请求进行处理。你可以通过 axios.interceptors.request.use() 方法添加请求拦截器。

示例:添加请求拦截器

以下是一个示例,展示如何在请求拦截器中统一设置请求头和添加认证信息:

import axios from 'axios';// 添加请求拦截器
axios.interceptors.request.use(config => {// 在发送请求之前做些什么config.headers['Authorization'] = 'Bearer your_token_here'; // 添加认证信息config.headers['Custom-Header'] = 'CustomValue'; // 添加自定义请求头return config;},error => {// 对请求错误做些什么return Promise.reject(error);}
);// 测试请求
axios.get('https://jsonplaceholder.typicode.com/posts/1').then(response => {console.log('响应数据:', response.data);}).catch(error => {console.error('请求失败:', error);});

2. 响应拦截器

响应拦截器可以在响应返回之后对响应进行处理。你可以通过 axios.interceptors.response.use() 方法添加响应拦截器。

示例:添加响应拦截器

以下是一个示例,展示如何在响应拦截器中统一处理响应数据和错误:

import axios from 'axios';// 添加响应拦截器
axios.interceptors.response.use(response => {// 对响应数据做点什么console.log('响应状态码:', response.status);return response.data; // 只返回响应数据},error => {// 对响应错误做点什么if (error.response) {// 请求已发出,但服务器响应的状态码不在 2xx 范围内console.error('响应状态码:', error.response.status);console.error('响应消息:', error.response.statusText);} else if (error.request) {// 请求已发出,但没有收到响应console.error('请求已发出,但未收到响应');} else {// 在设置请求时发生了一些事情,触发了一个错误console.error('请求配置错误:', error.message);}return Promise.reject(error);}
);// 测试请求
axios.get('https://jsonplaceholder.typicode.com/posts/1').then(response => {console.log('响应数据:', response);}).catch(error => {console.error('请求失败:', error);});

3. 自定义实例的拦截器

除了全局拦截器,你还可以为自定义的 Axios 实例添加拦截器。这在项目中需要使用多个不同配置的 Axios 实例时非常有用。

示例:为自定义实例添加拦截器
import axios from 'axios';// 创建自定义实例
const customInstance = axios.create({baseURL: 'https://api.example.com',timeout: 3000,
});// 为自定义实例添加请求拦截器
customInstance.interceptors.request.use(config => {config.headers['Authorization'] = 'Bearer your_token_here';return config;},error => {return Promise.reject(error);}
);// 为自定义实例添加响应拦截器
customInstance.interceptors.response.use(response => {return response.data; // 只返回响应数据},error => {console.error('请求失败:', error);return Promise.reject(error);}
);// 使用自定义实例发起请求
customInstance.get('/posts/1').then(response => {console.log('响应数据:', response);}).catch(error => {console.error('请求失败:', error);});

4. 移除拦截器

如果需要移除某个拦截器,可以通过返回的 id 来移除它:

import axios from 'axios';// 添加请求拦截器并获取 id
const requestInterceptorId = axios.interceptors.request.use(config => {config.headers['Authorization'] = 'Bearer your_token_here';return config;},error => {return Promise.reject(error);}
);// 移除请求拦截器
axios.interceptors.request.eject(requestInterceptorId);// 添加响应拦截器并获取 id
const responseInterceptorId = axios.interceptors.response.use(response => {return response.data;},error => {return Promise.reject(error);}
);// 移除响应拦截器
axios.interceptors.response.eject(responseInterceptorId);

5. 使用场景

(1)请求拦截器
  • 统一设置请求头:例如,添加认证信息(如 Authorization)、内容类型(如 Content-Type)等。

  • 添加公共参数:例如,为每个请求添加时间戳或用户 ID。

  • 请求取消:通过 CancelTokenAbortController 实现请求取消功能。

(2)响应拦截器
  • 统一处理响应数据:例如,只返回响应体中的数据部分。

  • 统一处理错误:例如,根据状态码显示不同的错误消息。

  • 处理重定向:例如,根据状态码(如 401)跳转到登录页面。

相关文章:

  • 黑马教程强化day2-2
  • markdown文本转换时序图
  • 深入理解 TCP 套接字:Socket 编程入门教程
  • 数组方法_push()/pop()/数组方法_shift()/unshift()
  • 滚动—横向滚动时,如何直接滚动到对应的内容板块
  • `document.domain` API 的废弃与现代 Web 开发的转型
  • 从 8 秒到 1 秒:前端性能优化的 12 个关键操作
  • Maven 构建性能优化深度剖析:原理、策略与实践
  • CKA考试知识点分享(10)---NetworkPolicy
  • 深入浅出:C++深拷贝与浅拷贝
  • Web防火墙深度实战:从漏洞修补到CC攻击防御
  • 重拾前端基础知识:CSS预处理器
  • 基于AI智能体的医疗AI工具库构建路径分析
  • Python爬虫(54)Python数据治理全攻略:从爬虫清洗到NLP情感分析的实战演进
  • 第七章: SEO与渲染方式 三
  • C#接口代码记录
  • 第七章: SEO与渲染方式
  • Scrapy爬虫框架:数据采集的瑞士军刀(附实战避坑指南)!!!
  • ( github actions + workflow 01 ) 实现爬虫自动化,每2小时爬取一次澎湃新闻
  • MyBatis实战指南(七)MyBatis缓存机制
  • 做企业网站需要哪些/可以直接进入网站的正能量
  • 宁波seo服务推广软件/南京seo推广公司
  • 福田做商城网站建设哪家效益快/汕头百度seo公司
  • h5建站网站/怎么做好市场宣传和推广
  • 做网站建设与推广企业/游戏推广员判几年
  • 苹果自带建设网站/成都电脑培训班零基础