个人技术博客——axios使用总结

222200406李滨 2024-12-16 02:44:35
这个作业属于哪个课程https://bbs.csdn.net/forums/FZU_university
这个作业要求在哪里https://bbs.csdn.net/topics/619480401
这个作业的目标个人技术博客
其他参考文献

目录

  • 个人技术博客——axios使用总结
  • 技术概述
  • Axios 是什么?
  • 使用场景:
  • 学习该技术的原因:
  • 技术难点:
  • 技术详述
  • 1. Axios的配置和初始化
  • 2. 发送 GET 请求
  • 3. 发送 POST 请求
  • 4. 流程图
  • 5. 细分点描述
  • 技术使用中遇到的问题和解决过程
  • 问题 1:跨域问题
  • 问题 2:接口返回格式不统一
  • 问题 3:错误处理复杂
  • 总结


个人技术博客——axios使用总结

技术概述

Axios 是什么?

Axios 是一个支持 Promise 的 HTTP 客户端,适用于浏览器和 Node.js 环境。它的功能包括拦截请求和响应、转换请求和响应数据、取消请求以及支持并发请求等。

使用场景:

Axios 常用于前端与后端的 API 通信,如 CRUD 操作、表单提交等。在 Fulifuli 项目中,我们利用 Axios 完成用户信息获取、视频数据加载、评论功能交互等操作。

学习该技术的原因:

  • Axios 拥有丰富的功能且使用简单,适合 Vue 前端开发。
  • 提供了请求拦截器和响应拦截器,便于统一处理请求逻辑。
  • 能处理跨域、文件上传等问题,功能强大。

技术难点:

  1. 接口数据格式不统一: 后端返回的数据格式不一致,导致前端解析异常。
  2. 跨域问题: 浏览器的同源策略限制了跨域请求。
  3. 复杂的错误处理: 项目中存在大量接口调用,需要对不同的错误类型提供对应的反馈机制。

技术详述

axios的流程图

img

1. Axios的配置和初始化

首先,我们创建一个 Axios 实例,并配置基础 URL 和拦截器,以便在请求和响应时统一处理某些操作。

import axios from 'axios';

// 创建Axios实例
const apiClient = axios.create({
  baseURL: 'https://api.fulifuli.com',
  timeout: 10000, // 请求超时时间
});

// 请求拦截器
apiClient.interceptors.request.use(config => {
  const token = localStorage.getItem('access_token');
  if (token) {
    config.headers['Access-Token'] = token;
  }
  return config;
}, error => {
  return Promise.reject(error);
});

// 响应拦截器
apiClient.interceptors.response.use(response => {
  return response;
}, error => {
  // 统一处理响应错误
  if (error.response && error.response.data.code !== undefined) {
    console.error(error.response.data.msg);
  }
  return Promise.reject(error);
});

2. 发送 GET 请求

我们使用 Axios 发送 GET 请求来获取视频列表。根据用户的登录状态,我们调用不同的 API 端点。

async function fetchVideoFeed() {
  let response;
  const userStore = useUserStore(); // 假设这是 Vuex 中的用户状态管理
  const fullParams = props.type !== 'home' ? `${params}&category=${transform(props.type)}` : params;

  if (userStore.user.is_logged_in) {
    response = await apiClient.get(`/api/v1/video/custom/feed?${fullParams}`, {
      headers: {
        'Access-Token': localStorage.getItem('access_token'),
      },
    });
  } else {
    response = await apiClient.get(`/api/v1/video/feed?${fullParams}`);
  }

  // 处理响应数据
  if (response.data.code === 0) {
    const newVideos = response.data.data.items;
    if (newVideos.length === 0) {
      console.log('No new videos found, resetting offset to 0...');
      offset.value = 0;
      loadMoreVideos();
    } else {
      videos.value.push(...newVideos);
      visibleVideos.value = fillDefaultVideos(videos.value.slice(0, visibleVideos.value.length + pageSize), visibleVideos.value.length + pageSize);
      offset.value += pageSize;
    }
  } else {
    console.error('Failed to fetch video feed:', response.data.msg);
  }
}

img

3. 发送 POST 请求

我们使用 Axios 发送 POST 请求来执行点赞和关注操作。

async function likeVideo(videoData, atype) {
  try {
    const response = await apiClient.post(
      '/api/v1/interact/like/video/action',
      {
        video_id: videoData.id,
        action_type: atype,
      },
      {
        headers: {
          'Access-Token': localStorage.getItem('access_token'),
        },
      },
    );

    if (response.data.code === 0) {
      videoData.is_liked = atype === 1;
      videoData.like_count = atype === 1 ? videoData.like_count + 1 : videoData.like_count - 1;
    } else {
      console.error(response.data.msg);
    }
  } catch (error) {
    console.error('请求出错:', error);
  }
}

async function toggleFollow(videoData) {
  try {
    const actionType = isFollowing.value ? 0 : 1;
    const toUserId = videoData.user.id;

    const response = await apiClient.post(
      '/api/v1/relation/follow/action',
      {
        to_user_id: toUserId,
        action_type: actionType,
      },
      {
        headers: {
          'Access-Token': localStorage.getItem('access_token'),
        },
      },
    );

    if (response.data.code === 0) {
      isFollowing.value = actionType === 1;
      ElMessage.success(isFollowing.value ? '已关注' : '已取关');
    } else {
      console.error('关注操作失败:', response.data.msg);
      ElMessage.error(response.data.msg);
    }
  } catch (error) {
    console.error('请求出错:', error);
    ElMessage.error('网络请求失败');
  }
}

img

4. 流程图

以下是使用 Axios 发送 GET 和 POST 请求的流程图:

[用户操作] --> [Axios请求拦截器] --> [后端API]
[后端API响应] --> [Axios响应拦截器] --> [用户界面更新]

在这个流程中,请求拦截器负责添加认证头部,响应拦截器负责处理错误和统一的错误处理逻辑。这样的设计使得代码更加模块化,易于维护。

5. 细分点描述

  • 请求拦截器: 在发送请求之前,检查本地存储中的 token,并将其添加到请求头部。
  • 响应拦截器: 在接收到响应后,检查响应状态码,并进行错误处理。
  • GET 请求: 根据用户登录状态选择不同的 API 端点,并处理响应数据。
  • POST 请求: 发送点赞和关注请求,并根据响应更新 UI 状态。

技术使用中遇到的问题和解决过程

问题 1:跨域问题

描述:
在本地开发时,前端访问后端接口时遇到了跨域问题,浏览器报错:Access-Control-Allow-Origin 不允许前端域名。

解决方案:

  1. 后端配置 CORS: 后端使用跨域中间件支持特定来源。
  2. 开发环境代理: 在 Vue 的 vite.config.js 中配置代理,将请求转发到后端地址:
// https://vite.dev/config/
export default defineConfig({
  server: {
    proxy: {
      '/api': {
        target: 'http://1.94.121.141',
        changeOrigin: true,
      },
    },
  },
});

问题 2:接口返回格式不统一

描述:
有些接口返回的字段为 {code, message, data},有些直接返回数据,导致前端解析困难。

解决方案:
通过 Axios 的响应拦截器,将所有返回值格式化为统一结构:

service.interceptors.response.use(
  (response) => response.data.data || response.data,
  (error) => Promise.reject(error)
);

问题 3:错误处理复杂

描述:
不同接口的错误需要不同处理逻辑(如用户登录失效、请求超时等)。

解决方案:
在 Axios 的拦截器中,根据错误类型返回统一处理代码:

apiClient.interceptors.response.use(response => response, error => {
  if (error.response.status === 401) {
    // 登录失效处理
  }
  if (error.response.status === 500) {
    // 服务器错误处理
  }
  return Promise.reject(error);
});

总结

通过封装 Axios,我们实现了以下技术目标:

  1. 统一管理前端的 API 请求逻辑,提高代码的可维护性。
  2. 减少重复代码,降低了开发复杂度。
  3. 通过拦截器解决了跨域问题和数据格式不一致的问题。

在团队开发中,这种封装极大提升了接口联调的效率,特别是在 Fulifuli 这样一个功能复杂的项目中,保证了前后端协作的顺畅。


...全文
663 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

239

社区成员

发帖
与我相关
我的任务
社区管理员
  • FZU_SE_teacherW
  • 202501福大-软件工程实践-W班
  • D's Honey
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧