个人技术博客——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 这样一个功能复杂的项目中,保证了前后端协作的顺畅。


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

239

社区成员

发帖
与我相关
我的任务
社区管理员
  • FZU_SE_teacherW
  • 助教赖晋松
  • D's Honey
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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