欢迎光临
我们一直在努力

从接口文档到前端调用:Axios 封装与实战全流程详解

文章目录

  • 从接口文档到前端调用:Axios 封装与实战全流程详解
  • 1.如何看接口文档?
    • 1.1 GET
    • 1.2 POST
  • 2.为什么要封装请求拦截器和响应拦截器?如何封装?
    • 2.1 封装axios实例
    • 2.2 封装拦截器
    • 2.3 拦截器实践
  • 3.如何在实际的项目中使用axios
    • 3.1 GET
    • 3.2 POST
    • 3.3. DELETE
    • 3.4 PUT
    • 3.5 PATCH

从接口文档到前端调用:Axios 封装与实战全流程详解

1.如何看接口文档?

在一个接口文档中,有很多的请求类型(也叫 HTTP 方法 / 动作)

  • GET
  • POST
  • PUT
  • PATCH
  • DELETE

这里仅以 GET 和 POST 做讲解,其他的请求类型,都类似

1.1 GET

注意:GET 跟 URL 息息相关

来看一个具体的例子:

image-20250923214014227

image-20250923214311140

首先,接口都会有一个 baseUrl,作为获取数据的地址,使用不同的接口时,又会有不同的路径,比如这个就是/my/cate/info

第一部分:请求参数(Request Parameters)

Query 参数和 Header 参数

Query 参数和 Header 参数

query 跟 url 息息相关

header 跟身份验证相关,就是说,想让这个请求发送给接口,必须满足一些条件,header 就像一把钥匙

文档中这两部分都必须传对,否则接口要么报错,要么不给你数据。

  • Query 参数
    • 出现在 URL 上。

    • 在这个接口里:

      GET /my/cate/info?id=1284

      这里的 id=1284 就是 文章分类的 id,告诉后台我要取哪一个分类的详情。

    • 所以:Query 参数就是用来指定查询条件的。

  • Header 参数
    • 放在 HTTP 请求的 请求头里。
    • 这里要求的参数是:
      • Authorization: Bearer <token>

    Authorization:英语中授权的意思

    • 作用:用来验证用户身份(你是否已经登录)。
    • 也就是说:
      • 如果没有这个 token → 后台会返回 401 身份认证失败。
      • 有正确 token → 才能拿到分类详情。

    第二部分:响应(Response)

    {
    "code": 0,
    "message": "获取文章分类成功!",
    "data": {
    "id": 1070,
    "cate_name": "科技",
    "cate_alias": "keji"
    }
    }

    • code:业务状态码。
      • 0 表示成功,1 表示异常。
    • message:提示消息(给人看的,比如“成功/失败原因”)。
    • data:真正的业务数据,这里是文章分类的详情对象。
      • id:分类 ID。
      • cate_name:分类名称(比如 “科技”)。
      • cate_alias:分类别名(比如 “keji”)。

    这部分就是告诉你:调用成功以后,后台会返回什么样的数据结构,你前端代码里就可以用这些字段来展示页面。

    1.2 POST

    看如下例子:返回响应部分不做介绍,POST 请求方法没有 Query 参数,而是 Body 参数

    image-20250923223600710

    image-20250923223635191

    Body 参数(请求体)

    这是 POST 接口的重点,和 GET 很不同:

    • 位置:请求报文的 body 部分,不在 URL 上。
    • 格式:这里文档写了 application/json,说明 body 要用 JSON 格式。
    • 作用:用来传递 新增数据的内容。

    在文档里,它定义了两个字段:

  • cate_name (string)
    • 文章分类名字,比如“娱乐”、“科技”。
    • 必填,长度限制:1–10 个非空字符。
  • cate_alias (string)
    • 文章分类别名,比如“yule”、“keji”。
    • 必填,长度限制:1–15 个大小写字母和数字组合。
  • 示例 JSON:

    {
    "cate_name": "娱乐",
    "cate_alias": "yule"
    }

    为什么 GET 没有 Body,而 POST 要用 Body?

    GET:只是获取数据,不修改,所以参数少,放 URL 上即可。

    POST:要创建一条新数据,通常包含多个字段(标题、别名、内容……),如果写在 URL 会很长很乱,所以必须放到 Body 里,结构化成 JSON。

    2.为什么要封装请求拦截器和响应拦截器?如何封装?

    简单来说,实际开发过程中,不能每一次都手动的在请求头中加入授权的 token,而请求拦截器,会拦截请求将每个授权的 token 加入到本次的请求头当中.

    统一封装 axios 请求模板: 官方文档:https://www.axios-http.cn/docs/interceptors

    import axios from 'axios'

    const baseURL = 'http://big-event-vue-api-t.itheima.net'

    const instance = axios.create({
    // 1. 基础地址,超时时间(配置项)
    })

    //请求拦截器
    instance.interceptors.request.use(
    (config) => {
    // 2. 携带token,将 token 值赋给请求头
    return config
    },
    (err) => Promise.reject(err)
    )

    //响应拦截器
    instance.interceptors.response.use(
    //http 返回 200 成功
    (res) => {
    // 3. 正确拿到了业务数据

    // 4. 业务逻辑错误,例如限制密码字母大写
    return res
    },
    (err) => {
    // 5. 处理http 返回401错误
    return Promise.reject(err)
    }
    )

    export default instance

    • 将封装写在 src/utils/request.js
    • 首先,创建一个 axios 实例
    • 其次,写出请求拦截器和响应拦截器

    2.1 封装axios实例

    (1)统一配置

    • 每个接口都要用到的公共参数,比如:
      • baseURL(基础路径)
      • timeout(超时时间)
      • headers(请求头,常常要放 token)
    • 如果不封装,每次 axios.get() / axios.post() 都要手动写,很麻烦。
    • 封装后 → 写一次,所有请求自动带上。

    timeout:请求超过 x 毫秒还没响应,就自动报错,进入 .catch()

    请求中几乎所有接口都需要,而且不会频繁变化 的东西,适合直接写在 axios.create() 的 headers 里,所以 token 不应该写在这里,token 应写在拦截器中

    (2)更好的可维护性

    • 以后如果 baseURL 要改(比如从测试环境 → 正式环境),只需要改 request.js 这一处。
    • 如果不封装,你得在项目里到处找 URL,一个个修改,容易遗漏。

    (3)添加请求/响应拦截器

    (4)支持多实例

    有些项目里:

    • 一部分接口走 https://api.example.com
    • 另一部分接口走 https://upload.example.com 就可以创建两个不同的 axios 实例,互不影响。

    封装axios实例代码如下:

    import axios from 'axios'
    const baseURL = 'http://big-event-vue-api-t.itheima.net'

    const instance = axios.create({
    baseURL,
    timeout: 100000
    })

    2.2 封装拦截器

    官方文档中的拦截器

    // 添加请求拦截器
    axios.interceptors.request.use(function (config) {
    // 在发送请求之前做些什么
    return config;
    }, function (error) {
    // 对请求错误做些什么
    return Promise.reject(error);
    });

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

    分析:

    request 拦截器的代码是一样的,关键在于拿到的对象不一样,一个是 config,一个是 response

    • config 对象
      • axios 会先把你传入的参数转成一个“配置对象”,这个配置对象就是 config 对象
    • response 对象
      • 浏览器原生的 XHR 或 fetch 会产生一个响应结果,axios 会把这个结果“包装”成一个对象

    注意:

    • 这里的 axios.替换成你对应的 axios 实例
    • function(config) 也可以替换成对应的箭头函数()=>{}

    2.3 拦截器实践

    请求拦截器:使用 pinia 存储的 token,将 token 值赋给请求头

    instance.interceptors.request.use(
    (config) => {
    const userStore = useUserStore()
    if (userStore.token) {
    config.headers.Authorization = userStore.token
    }
    return config
    },
    (err) => Promise.reject(err)

    响应拦截器:

    • 成功拿到响应,直接返回,没拿到服务异常

    • 若错误,根据错误类型提示或跳转路由

    instance.interceptors.response.use(
    (res) => {
    if (res.data.code === 0) {
    return res
    }
    ElMessage({ message: res.data.message || '服务异常', type: 'error' })
    return Promise.reject(res.data)
    },
    (err) => {
    ElMessage({ message: err.response.data.message || '服务异常', type: 'error' })
    console.log(err)
    if (err.response?.status === 401) {
    router.push('/login')
    }
    return Promise.reject(err)
    }
    )

    导出

    export default instance
    export { baseURL }

    3.如何在实际的项目中使用axios

    3.1 GET

    无需请求参数的 GET

    image-20250924164434281

    在 src/api 下创建自定义的 js 文件,如 article.js.存放跟文章相关的 api

    src/api/article.js

    • 导入封装好的方法

    import request from '@/utils/request'

    • 实现 api

    //获取文章分类
    export const artGetChannelsService=()=>request.get('/my/cate/list')

    • 在具体的.vue 文件中使用

      • 导入该方法

        import { artGetChannelsService} from '@/api/article'

      • 使用该方法

        const res =await artGetChannelsService()

    需要请求参数的 GET

    image-20250924172104336

    API 封装:

    // 获取文章分类详情 ?id=xxx
    export const artGetChannelDetailService = (id) => {
    return request.get('/my/cate/info', {
    params: { id } // => /my/cate/info?id=1284
    })
    }

    为什么写 params 呢?

    因为能拼到 url 后面

    在 .vue 里使用:

    import { artGetChannelDetailService } from '@/api/article'

    const id = route.query.id // 比如路由里带着 ?id=1284
    await artGetChannelDetailService(id)

    3.2 POST

    以这个为例:

    image-20250924165547534

    • 导入封装好的方法

    import request from '@/utils/request'

    • 实现 api

    //添加文章分类
    export const artAddChannelService=(data)=>request.post('/my/cate/add',data)


    • 在具体的.vue 文件中使用

      • 导入该方法

        import { artAddChannelService} from '@/api/article'

      • 使用该方法,此时注意了,POST 是需要我们传参的

        //定义表单数据
        const formModel=ref({
        cate_name:'',
        cate_alias:''
        })

        await artAddChannelService(formModel.value)

    3.3. DELETE

    Delete 也是需要一个请求参数,写法跟带参数的 GET 一样

    API 封装:

    // 删除文章分类
    export const artDelChannelService = (id) =>
    request.delete('/my/cate/del', {
    params: { id }
    })

    3.4 PUT

    put 跟 post 写法一样,除了 request 方法是 put

    API 封装:

    export const artEditChannelService =(data)=> request.put('/my/cate/info',data)

    在实际写法中,也可以不用形参 data,直接传对象,比如

    //更新个人信息
    export const userUpdateInfoService = ({ id, nickname, email }) =>
    request.put('/my/userinfo', { id, nickname, email })

    3.5 PATCH

    image-20250924202437284

    API 封装:

    跟 post 一样

    //上传头像
    export const userUploadAvatarService = (avatar) => request.patch('/my/update/avatar', { avatar })

    赞(0)
    未经允许不得转载:171主机测评 » 从接口文档到前端调用:Axios 封装与实战全流程详解
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址