项目中关于axios拦截器以及get和post请求的封装

本文介绍了axios在前端项目中的应用,重点讲解了如何进行拦截器的设置以及GET和POST请求的封装,提供了官方样例代码链接,适合前端开发者参考学习。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

写在前面

坚持,记笔记 😀, 加油!

一、axios 介绍

axios 是一个轻量的 HTTP 客户端,它基于 XMLHttpRequest 服务来执行 HTTP 请求,支持丰富的配置,支持 Promise,支持浏览器端和 Node.js 端。

二、axios 拦截器以及 get 和 post 请求的封装

关于axios拦截器(Interceptors)的设置代码官方给出了一份样式代码,可见axiosgithub 仓库地址

import axios from "axios";
import {
   
    getToken } from "./localStorage";

const BASE_URL = "https://127.0.0.1:8000/api";

const instance = axios.create({
   
   
  baseURL: BASE_URL,
  tim
<think>我们参考引用的内容,特别是引用[1]引用[2],来构建一个统一的Axios封装方案。目标是在Vue项目封装Axios,使得GETPOST请求的传值方式在调用时看起来一致(比如都通过一个`params`对象传递参数),但在内部根据请求方法自动处理参数位置(GET在URL查询字符串,POST请求体)。但是请注意,实际上,GET请求的参数确实应该放在URL的查询参数中,而POST请求的参数应该放在请求体中。我们的封装目的是让调用者在写代码时不用关心这个区别,而是由封装层自动处理。步骤:1.创建一个Axios实例,配置基础URL可能的超时时间等。2.请求拦截器:可以在请求前统一处理,例如设置loading状态、添加token等。3.响应拦截器:处理响应数据,例如根据状态码统一处理错误、关闭loading等。4.封装getpost方法,使其调用方式统一(比如都接受两个参数:urlparams)。在get方法中,我们将params传递给Axios的params配置;在post方法中,将params作为请求体发送。然而,为了彻底统一调用方式,我们可以将所有的请求都通过一个统一的request方法进行封装,然后根据不同的method来分发。下面是一个示例,我们将创建:-一个request函数,接受method、url、params等参数。-然后对外提供getpost方法,这两个方法内部调用request函数,并传入对应的method。这样,调用者可以这样使用:-service.get(url,params)-service.post(url,params)而内部,request函数会根据method判断:对于GET,将params拼接到URL的查询参数上;对于POST,将params放入请求体。但是注意:GET请求是没有请求体的,所以当为GET方法时,参数必须放在URL中。而POST可以同时有查询参数请求体吗?实际上是可以的,但我们通常将主要数据放在请求体。为了灵活,我们也可以允许GET请求时,如果传了请求体参数则忽略(或者报错),但这样不好。所以我们规定:-GET请求:参数只作为查询参数-POST请求:参数作为请求体(如果需要同时传递查询参数请求体,则需要在封装时做特殊处理,但这里为了简化,我们不提供这种复杂情况,如果需要,可以在url中手动添加查询参数)所以我们的封装目标是:-调用者使用get方法时,第二个参数(params)会被转换成查询字符串附加到url后。-调用者使用post方法时,第二个参数(params)会作为请求体发送(JSON格式)。此外,我们还会在请求拦截器中统一添加一些头部(比如Content-Type:application/json)身份验证信息(如token)。示例代码:```javascript//创建axios实例importaxiosfrom'axios';constservice=axios.create({baseURL:process.env.VUE_APP_BASE_API,//环境变量中的基础URLtimeout:5000//请求超时时间});//请求拦截器service.interceptors.request.use(config=>{//在发送请求之前做些什么//例如,如果有token,则添加到请求头consttoken=localStorage.getItem('token');if(token){config.headers['Authorization']=`Bearer${token}`;}//如果是POST请求,且请求体是对象,则转换为JSON字符串(实际上axios会自动转换,但我们可以确保头部的Content-Type正确)if(config.method==='post'&&config.data){config.headers['Content-Type']='application/json';}returnconfig;},error=>{//对请求错误做些什么console.log(error);returnPromise.reject(error);});//响应拦截器service.interceptors.response.use(response=>{//对响应数据做点什么//例如,根据后端返回的code进行统一处理constres=response.data;if(res.code===200){returnres.data;//我们只返回数据部分}else{//不是200的情况,可以统一处理错误returnPromise.reject(newError(res.msg||'Error'));}},error=>{//对响应错误做点什么console.log('err'+error);returnPromise.reject(error);});//封装request函数functionrequest(method,url,data){if(method.toLowerCase()==='get'){returnservice.request({url,method:'get',params:data//GET请求的参数放在params});}elseif(method.toLowerCase()==='post'){returnservice.request({url,method:'post',data//POST请求的参数放在data(请求体)});}}//封装单独的getpost方法exportfunctionget(url,params){returnrequest('get',url,params);}exportfunctionpost(url,data){returnrequest('post',url,data);}exportdefaultservice;```然后在Vue组件中使用:```javascriptimport{get,post}from'./request';//使用get请求get('/user/list',{page:1,pageSize:10}).then(res=>{console.log(res);}).catch(err=>{console.error(err);});//使用post请求post('/user/login',{username:'admin',password:'123456'}).then(res=>{console.log(res);}).catch(err=>{console.error(err);});```这样,调用者使用getpost方法时,传参的方式都是传递一个对象作为第二个参数,但内部会根据方法自动处理参数的位置。注意:-上面的响应拦截器直接返回了`response.data.data`,这取决于你后端返回的数据结构。如果后端返回的是`{code:200,msg:'成功',data:...}`,那么这样处理可以。但如果结构不同,请相应调整。-在请求拦截器中,我们为POST请求设置了Content-Type为application/json,这样axios就会自动将JavaScript对象转换为JSON字符串。对于GET请求,不需要设置请求体,所以不需要设置Content-Type(axios默认对GET请求不会设置Content-Type,浏览器也不会发送请求体)。另外,引用[3]提到了在main.ts中引入并初始化,我们可以将上面的封装模块化,然后在main.ts中引入并初始化(例如设置基础URL等)。但上面的封装已经将baseURL写在了创建实例的地方,所以可以根据需要调整。例如,我们可以在创建实例时不设置baseURL,然后在main.ts中通过环境变量设置:```javascript//在request.js中constservice=axios.create();//在main.ts中importservicefrom'./request';service.defaults.baseURL=process.env.VUE_APP_BASE_API;```或者按照引用[3]的做法,导出一个初始化函数,在main.ts中调用:```javascript//在request.js中letservice;exportfunctioninstanceInit(){service=axios.create({baseURL:process.env.VUE_APP_BASE_API,timeout:5000});//...然后加上拦截器等}exportfunctionget(url,params){//...使用service发送请求}```但是,为了避免复杂,我们通常直接在一个文件中创建好实例并导出,然后在main.ts中引入(可能只是为全局设置请求拦截器,如添加token)即可,无需调用初始化函数。以上示例代码仅供参考,具体实现需要根据项目需求调整。</think> 以下是在 Vue 中封装 Axios 以统一 GET POST 请求传值方式的实现方案: ### 统一封装Axios 实例 ```javascript // utils/request.js import axios from 'axios' // 创建实例 const service = axios.create({ baseURL: process.env.VUE_APP_BASE_API, timeout: 10000 }) // 请求拦截器(统一处理传参) service.interceptors.request.use(config => { // 统一添加 token config.headers['Authorization'] = localStorage.getItem('token') || '' // 统一参数处理 if (config.method === 'get') { config.params = config.data // 将 GET 参数赋值给 params } else if (['post', 'put'].includes(config.method)) { config.data = config.data // POST 请求直接使用 data } return config }, error => { return Promise.reject(error) }) // 响应拦截器(统一错误处理) service.interceptors.response.use( response => { const res = response.data if (res.code !== 200) { // 统一错误提示 return Promise.reject(new Error(res.message || 'Error')) } return res }, error => { // 统一网络错误处理 return Promise.reject(error) } ) // 统一请求方法封装 export function request(config) { return service(config) } ``` ### 在 Vue 组件中使用 ```vue <script> import { request } from '@/utils/request' export default { methods: { // GET 请求示例 async fetchData() { try { // 统一传参方式:使用 data 对象 const response = await request({ method: 'get', url: '/api/data', data: { // 统一使用 data 传参 page: 1, size: 20 } }) console.log('GET 响应:', response) } catch (error) { console.error('GET 错误:', error) } }, // POST 请求示例 async submitForm() { try { // 同样使用 data 传参 const response = await request({ method: 'post', url: '/api/submit', data: { // 统一传参接口 username: 'admin', password: '123456' } }) console.log('POST 响应:', response) } catch (error) { console.error('POST 错误:', error) } } } } </script> ``` ### 封装关键点说明 1. **统一传参接口**: - GET POST 均使用 `data` 属性传递参数 - 在请求拦截器中自动转换: - GET:将 `data` 转换为 URL 查询参数 (`config.params`) - POST:保持 `data` 作为请求体传递 2. **拦截器实现的功能**: - 自动添加认证 token - 统一错误处理逻辑 - 响应数据标准化处理 - 支持 loading 状态管理(可在拦截器中扩展) 3. **优势**: - 调用方式统一简化 - 避免 GET/POST 传参差异带来的错误 - 集中管理通用逻辑(认证、错误处理等) - 支持全局超时基础路径配置 在 Vue3 项目中使用时,建议在 `main.js` 初始化请求实例并挂载到全局属性(参考引用[3]的实现方式)[^3]。此封装方案已处理 GET 参数位置(URL 查询字符串)与 POST 参数位置(请求体)的自动转换问题(参考引用[2]的参数位置差异)[^2]。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值