迷新白的博客 迷新白的博客
首页
随笔
  • Vuepress
  • Springboot
  • 开发工具
  • 系统工具
读吧
  • 智能浇花系统 (opens new window)
  • 用户中心系统 (opens new window)
  • 关于
  • 友情链接
GitHub (opens new window)

迷新白

愿你平安
首页
随笔
  • Vuepress
  • Springboot
  • 开发工具
  • 系统工具
读吧
  • 智能浇花系统 (opens new window)
  • 用户中心系统 (opens new window)
  • 关于
  • 友情链接
GitHub (opens new window)
  • 用户中心系统

    • 前端初始化
    • 用户中心后端-1
    • 用户中心后端-2
    • 注册模块(后端)
    • 登录模块(后端)
    • 管理模块(后端)
    • Ant Design Pro前端初始化
    • 登录+注册模块(前端)
    • 管理模块+登录状态(前端)
    • 注销模块+校验模块(前后端)
    • 异常处理器(后端优化)
    • 请求响应处理器(前端)
      • 优化内容
      • 全局请求响应拦截器封装
      • 增加用户初始头像
  • 仿Deepseek官网AI聊天网站

  • 尤克里里音月-Flutter(需求分析阶段)

  • 项目
  • 用户中心系统
迷新白
2025-04-22
目录

请求响应处理器(前端)

# 13.请求响应处理器(前端)

前端代码优化,请求响应处理器封装

# 优化内容

  • 对接前端的返回值
  • 全局响应处理
    • 应用场景:需要对接口的通用响应进行统一处理,比如从response中取出data;根据code处理错误
    • 参考封装工具的官方文档

# 全局请求响应拦截器封装

  1. 定义通用返回对象

    • UserCenter\myapp\src\typings.d.tsimage-20250422161159192

    • src/services/ant-design-pro/api.ts封装注册的响应类型image-20250422161532083

    • src/pages/user/Register/index.tsx修改注册功能的判断逻辑

        // 注册
        const res = await register(values);
        if (res.code === 0 && res.data > 0) {
          const defaultLoginSuccessMessage = '注册成功!';
          message.success(defaultLoginSuccessMessage);
          /** 此方法会跳转到 redirect 参数所在的位置 */
          /** 用户注册成功后跳转到登录页 */
          if (!history) return;
          const {query} = history.location;
          // const {redirect} = query as {
          //   redirect: string;
          // };
          history.push({
            pathname: 'user/login',
            query,
          });
          return;
        }else{
          throw new Error(res.description);
        }
      } catch (error: any) {
        const defaultLoginFailureMessage = '注册失败,请重试!';
        message.error(error.message ?? defaultLoginFailureMessage);
      }
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24

      测试成功image-20250422163258343


      image-20250422163414984
    • 封装其他的APIimage-20250422163644315loginimage-20250422163750211searchimage-20250422163843862noticesimage-20250422164000259current

  2. 前端写一个全局响应拦截器

    • 进入src/.umi/plugin-request/request.ts,增加代码

        requestConfig.responseInterceptors = [
          async function (response: Response, options:RequestOptionsInit):Response | Promise<Response> {
            const data = await response.clone().json();
            if (res.code === 0){
              return res.data;
            }
          }
        ]
      
      1
      2
      3
      4
      5
      6
      7
      8

      image-20250422164755794image-20250422165703784

    • 将所有接口中响应的data取出了。继续编写代码image-20250422165834686

  3. request.ts属于.umi,是框架自动生成的,每次启动会被覆盖掉,在.gitignore添加.umi,让编辑器帮我们识别这是项目生成的文件image-20250422170134996

    这里检查了发现没生效

  4. 简单介绍:在Umi中,网络请求由Umi-request完成,它基于 fetch 封装, 兼具 fetch 与 axios 的特点,为开发者提供一个统一的 api 调用方式,简化使用,并提供诸如缓存、 超时、 字符编码处理、 错误处理等常用功能。新建一个请求类,覆盖umi的request方法

    • src文件夹下新建plugins文件夹,plugins文件夹下新建globalRequests.ts,补充代码

      /**
       * request 网络请求工具
       * 更详细的 api 文档: https://github.com/umijs/umi-request
       */
      
      
      
      import {extend} from 'umi-request';
      import {history} from 'umi';
      import {stringify} from "querystring";
      import {message} from "antd";
      
      
      /**
       * 配置request请求时的默认参数
       */
      const request = extend({
        credentials: 'include', // 默认请求是否带上cookie
        // requestType: 'form',
      });
      
      /**
       * 所以请求拦截器
       */
      request.interceptors.request.use((url, options): any => {
        console.log(`do requset url = ${url}`);
        return {
          url,
          options: {
            ...options,
            headers: {
            },
          },
        };
      });
      
      /**
       * 所有响应拦截器
       */
      request.interceptors.response.use(async (response, options): Promise<any> => {
        const res = await response.clone().json();
        if (res.code === 0) {
          return res.data;
        }
        if (res.code === 40100) {
          message.error('请先登录');
          history.replace({
            pathname: '/user/login',
            search: stringify({
              redirect: location.pathname,
            }),
          });
        } else {
          message.error(res.description)
        }
        return res.data;
      });
      
      export default request;
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      54
      55
      56
      57
      58
      59

      在api.ts的引入改成自定义的requestimage-20250422171807046

  5. 测试,未登录时进入管理页,会提示先登录image-20250422173516081

  6. 测试,注册界面image-20250422174726910正常来说 前端应该只会返回该用户名已被注册 但返回了两条 另一条是 Cannot read properties of null (reading 'code')原因在于前端的注册判断逻辑

    src/pages/user/Register/index.tsx中image-20250422174917799

    当 res.data 为 null 时,res.data > 0 将会抛出一个错误。因为无法读取 null 的属性,这就是 "Cannot read properties of null (reading 'code')" 错误的来源。

    修改逻辑,当code为数字时,会注册成功,否则自动执行

        try {
          // 注册
          const res = await register(values);
    
          // 检查响应是否有效
          if (res && typeof res.code === 'number') {
            if (res.code === 0 && res.data > 0) {
              const defaultLoginSuccessMessage = '注册成功!';
              message.success(defaultLoginSuccessMessage);
    
              // 跳转到登录页
              if (!history) return;
              const { query } = history.location;
              history.push({
                pathname: 'user/login',
                query,
              });
    
            } else {
              throw new Error(res.description || '未知错误');
            }
          }
    
        }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24

    这次测试结果符合预期image-20250422175407394

    但又有了新问题,注册一个新账户后,没有任何提示

    并且抛出了一个空白错误image-20250422225009799可以发现右边是返回成功的响应,而前端抛出了一个空白错误

    增加一个输出,看看注册成功后返回的是什么

    console.log('注册返回结果:', res);
    
    1

    结果返回了data

    image-20250422225508836

    那就直接修改逻辑

    if (typeof res === 'number' && res > 0) {
    
    1

    如果是number,判断注册成功

# 增加用户初始头像

在后端的Impl中增加

/* 3.插入数据 */
User user = new User();
user.setUserAccount(userAccount);
user.setUserPassword(encryptPassword);
String AvatarUrl = ("https://pic.code-nav.cn/user_avatar/1897656130643132418/thumbnail/hKKx7cXTxCQsQm0x.png");
user.setAvatarUrl(AvatarUrl);
1
2
3
4
5
6

文字写于:广东

更新时间: 2025/4/25 20:22:48
异常处理器(后端优化)
需求分析

← 异常处理器(后端优化) 需求分析→

最近更新
01
第一次对话完善
04-27
02
保留上下文对话
04-27
03
首页完善(后端)
04-27
更多文章>
Theme by Vdoing | Copyright © 2022-2025 迷新白 | 的博客
sitemap icon by Icons8
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式