剧场模式
首页前后端分离Ant DesignUmiJS & TypeScript & Ant Design Pro v4 从零开始实战教程

UmiJS & TypeScript & Ant Design Pro v4 从零开始实战教程 #32 重构代码,封装 request

求知小风 · 元婴发布于新课程
0

https://github.com/umijs/umi-request

service.ts

import request from '@/utils/request';
import { UserRegisterParams, CaptchaParams } from './new';

const PREFIX = `/api/v1`;

export async function fakeRegister(params: UserRegisterParams) {
  return request(`${PREFIX}/users`, {
    method: 'POST',
    data: params,
  });
}

export async function fakeCaptcha(params: CaptchaParams) {
  return request(`${PREFIX}/sms_code`, {
    params: params,
  });
}

request.ts

/**
 * request 网络请求工具
 * 更详细的 api 文档: https://github.com/umijs/umi-request
 */
import { extend } from 'umi-request';
// import { notification } from 'antd';

// const codeMessage = {
//   200: '服务器成功返回请求的数据。',
//   201: '新建或修改数据成功。',
//   202: '一个请求已经进入后台排队(异步任务)。',
//   204: '删除数据成功。',
//   400: '发出的请求有错误,服务器没有进行新建或修改数据的操作。',
//   401: '用户没有权限(令牌、用户名、密码错误)。',
//   403: '用户得到授权,但是访问是被禁止的。',
//   404: '发出的请求针对的是不存在的记录,服务器没有进行操作。',
//   406: '请求的格式不可得。',
//   410: '请求的资源被永久删除,且不会再得到的。',
//   422: '当创建一个对象时,发生一个验证错误。',
//   500: '服务器发生错误,请检查服务器。',
//   502: '网关错误。',
//   503: '服务不可用,服务器暂时过载或维护。',
//   504: '网关超时。',
// };

/**
 * 异常处理程序
 */
// const errorHandler = (error: { response: Response }): Response => {
//   const { response } = error;
//   if (response && response.status) {
//     const errorText = codeMessage[response.status] || response.statusText;
//     const { status, url } = response;

//     notification.error({
//       message: `请求错误 ${status}: ${url}`,
//       description: errorText,
//     });
//   }
//   return response;
// };

export const DOMAIN =
  process.env.NODE_ENV === 'production' ? `http://staging.qiuzhi99.com` : `http://localhost:5000`;

/**
 * 配置request请求时的默认参数
 */
const request = extend({
  // errorHandler, // 默认错误处理
  credentials: 'same-origin', // 默认请求是否带上cookie
  prefix: `${DOMAIN}`,
});

export default request;

model.ts

import { AnyAction, Reducer } from 'redux';

import { EffectsCommandMap } from 'dva';
import { fakeRegister, fakeCaptcha } from './service';
import uuidv4 from 'uuid/v4';
import { DOMAIN } from '@/utils/request';

export interface StateType {
  success?: boolean;
  currentAuthority?: 'user' | 'guest' | 'admin';
  errors?: any;
  image?: string;
  response?: any;
}

export type Effect = (
  action: AnyAction,
  effects: EffectsCommandMap & { select: <T>(func: (state: StateType) => T) => T },
) => void;

export interface ModelType {
  namespace: string;
  state: StateType;
  effects: {
    submit: Effect;
    getCaptcha: Effect;
    onGetCaptchaImage: Effect;
  };
  reducers: {
    registerHandle: Reducer<StateType>;
    errorsHandle: Reducer<StateType>;
    setCaptchaImage: Reducer<StateType>;
    clearErrors: Reducer<StateType>;
  };
}

const Model: ModelType = {
  namespace: 'userRegister',

  state: {
    success: false,
    errors: {},
    response: {},
    image: `${DOMAIN}/rucaptcha`,
  },

  effects: {
    *submit({ payload }, { call, put }) {
      try {
        const response = yield call(fakeRegister, payload);
        yield put({
          type: 'registerHandle',
          payload: response,
        });
        yield put({
          type: 'clearErrors',
        });

        localStorage.setItem('token', response.response.auth_token);
      } catch (e) {
        yield put({
          type: 'errorsHandle',
          payload: e.data.errors,
        });

        yield put({
          type: 'onGetCaptchaImage',
        });
      }
    },
    *onGetCaptchaImage({}, { put }) {
      yield put({
        type: 'setCaptchaImage',
      });
    },

    *getCaptcha({ payload }, { call }) {
      yield call(fakeCaptcha, payload);
    },
  },

  reducers: {
    registerHandle(state, { payload }) {
      return {
        ...state,
        success: payload.success,
        response: payload.response,
      };
    },
    errorsHandle(state, { payload }) {
      return {
        ...state,
        errors: payload,
      };
    },

    clearErrors(state, {}) {
      return {
        ...state,
        errors: {},
      };
    },

    setCaptchaImage(state, {}) {
      const randomString = uuidv4();
      return {
        ...state,
        image: `${DOMAIN}/rucaptcha?a=${randomString}`,
      };
    },
  },
};

export default Model;
26 条回复
  • Jaylene · 真仙
    Jaylene · 真仙 #1

    老师 我想问下为啥我process.env是个空对象呢?里面没有NODE_ENV属性啊,什么原因呢?

  • 求知小风 · 元婴

    windows?

  • 求知小风 · 元婴

    不应该,也应该是有内容的呀,默认就有这个的

  • Jaylene · 真仙
    Jaylene · 真仙 #4

    是的,win10

  • Jaylene · 真仙
    Jaylene · 真仙 #5

    这是我输出的process对象,

  • 求知小风 · 元婴

    可能系统差异吧,不行的话,你就在 package.json 文件里加上那个变量 ,可能 windows 还要用 cross-env,你去了解下

  • 求知小风 · 元婴

    umi dev 前面加上 cross-env NODE_ENV=development

  • Jaylene · 真仙
    Jaylene · 真仙 #8


    这三个命令都能正常运行,但是process对象并没有发生变化。。。

  • 求知小风 · 元婴

    这么诡异啊,是不是有可能终端或node 版本之类的问题,终端你可以试试 cmder

  • Jaylene · 真仙
    Jaylene · 真仙 #10

    我用umi另外又创建了一个项目,这次没有选antd pro,选的app,但是项目里面这个process.env同样还是空对象

  • Jaylene · 真仙
    Jaylene · 真仙 #11


    我感觉我真的遇到诡异的事情了,按您说的,我把vscode select default shell改成CMD后,项目运行起来,终端没有任何错误消息,但是浏览器页面报错,就是上图这个,我另外再启动了一个之前一样的powershell就能正常运行了,这期间我并没有更改任何代码

  • Jaylene · 真仙
    Jaylene · 真仙 #12

    只能用powershell运行,cmd报错

  • 求知小风 · 元婴
    求知小风 · 元婴 #13

    推荐你用 cmder ,我看别人用过,感觉还行,或者 git 自带的那个 shell

  • 求知小风 · 元婴
    求知小风 · 元婴 #14

    有机会还是弄一台 linux 或 mac ,比较适合开发的 _^

  • Jaylene · 真仙
    Jaylene · 真仙 #15

    老师 我有新进展啦,我在config/plugin.config.js中能够看到process.env中的所有变量,我console.log它是输出在终端的,不是在浏览器的,而我在src/model/global.js中console.log它是输出在浏览器控制台的,但是是.env是空对象,我怎么才能在所有js文件中获取到它呢

  • 求知小风 · 元婴
    求知小风 · 元婴 #16

    config 有个定义环境变量的地方,你了解下,在 config 目录 里

  • Jaylene · 真仙
    Jaylene · 真仙 #17

    老是 我找到原因啦…………其实本身就是有这个process.env的,我至始至终都只是在输出process这个对象,并没有访问process.env,其实输出process.env是有{NEDE_ENV: development}的。
    但是我还是不明白为什么直接访问process时在浏览器中显示他的env属性为{},这是什么原因呢?

  • Jaylene · 真仙
    Jaylene · 真仙 #18

    或许您可以尝试一下看跟我是不是一样的

  • 求知小风 · 元婴
    求知小风 · 元婴 #19

    那就可以了,应该是一样的

  • 张琳 · 道祖
    张琳 · 道祖 #20

    请教个问题:在config中设置了proxy代理,那么又在request中设置了prefix,那么开发环境中的请求会走代理的那个域名还是prefix设置的这个呢?生产环境又是怎样呢?如果测试环境分成好几个比如:sit、uat、pre、又该怎样动态设置呢?

  • 求知小风 · 元婴
    求知小风 · 元婴 #21

    只要有设置 request 的 prefix ,都会走 request.ts 的内容的

  • 求知小风 · 元婴
    求知小风 · 元婴 #22

    如果测试环境分好几个,你就在 package.json 里用 环境变量区别开来,然后 request.ts 里分别读环境变量区分开来就好

  • afr751116 · 大罗
    afr751116 · 大罗 #23

    请问我在request.ts中配置好了地址如图片中是可以正常访问的


    但是为什么我在config.ts中启用代理配置就不对呢?是不是我哪个填错了?

  • 求知小风 · 元婴
    求知小风 · 元婴 #24

    在 request 里用的话,就不用配 proxy 里了,你要配的那个 pathRewrite 也可以不用

  • 求知小风 · 元婴
    求知小风 · 元婴 #25
  • afr751116 · 大罗
    afr751116 · 大罗 #26

    好的,感谢,我看下原理

官方服务号
随机课程
TypeScript + Express + MongoDB 基于角色的权限控制原理与实战

TypeScript + Express + MongoDB 基于角色的权限控制原理与实战

17 个视频2 小时 17 分钟高级

Pro¥ 169.00¥ 135.20

TypeScript已完结新课程

课程目录

1FreeUmiJS & TypeScript & Ant Design Pro v4 从零开始实战教程 #1 开始玩起来

2FreeUmiJS & TypeScript & Ant Design Pro v4 从零开始实战教程 #2 了解项目源码并尝试修改

3FreeUmiJS & TypeScript & Ant Design Pro v4 从零开始实战教程 #3 继续了解项目源码并修改代码

4FreeUmiJS & TypeScript & Ant Design Pro v4 从零开始实战教程 #4 如何修改 footer 及其原理

5FreeUmiJS & TypeScript & Ant Design Pro v4 从零开始实战教程 #5 关于 footer 和 layout

6ProUmiJS & TypeScript & Ant Design Pro v4 从零开始实战教程 #6 如何好好利用 ant-design-pro-layout

7ProUmiJS & TypeScript & Ant Design Pro v4 从零开始实战教程 #7 如何下载和使用区块

8ProUmiJS & TypeScript & Ant Design Pro v4 从零开始实战教程 #8 为什么下载区块后会添加菜单

9ProUmiJS & TypeScript & Ant Design Pro v4 从零开始实战教程 #9 umi-plugin-pro-block-ts

10ProUmiJS & TypeScript & Ant Design Pro v4 从零开始实战教程 #10 删除国际化 i18n part 1

11ProUmiJS & TypeScript & Ant Design Pro v4 从零开始实战教程 #11 删除国际化 i18n part 2

12ProUmiJS & TypeScript & Ant Design Pro v4 从零开始实战教程 #12 用户注册的 block

13ProUmiJS & TypeScript & Ant Design Pro v4 从零开始实战教程 #13 让用户注册工作起来

14ProUmiJS & TypeScript & Ant Design Pro v4 从零开始实战教程 #14 注册的流程理解

15ProUmiJS & TypeScript & Ant Design Pro v4 从零开始实战教程 #15 准备好 API

16ProUmiJS & TypeScript & Ant Design Pro v4 从零开始实战教程 #16 对接好后端的注册功能

17ProUmiJS & TypeScript & Ant Design Pro v4 从零开始实战教程 #17 表单的前端验证与后端验证

18ProUmiJS & TypeScript & Ant Design Pro v4 从零开始实战教程 #18 后端的数据验证与前端的结合

19ProUmiJS & TypeScript & Ant Design Pro v4 从零开始实战教程 #19 自己写一个真实项目的注册页面 - 手机验证码 - 图形验证码

20ProUmiJS & TypeScript & Ant Design Pro v4 从零开始实战教程 #20 注册表单

21ProUmiJS & TypeScript & Ant Design Pro v4 从零开始实战教程 #21 表单与 TypeScript

22ProUmiJS & TypeScript & Ant Design Pro v4 从零开始实战教程 #22 注册表单 - connect - dispatch

23ProUmiJS & TypeScript & Ant Design Pro v4 从零开始实战教程 #23 实现注册功能并显示验证出错信息

24ProUmiJS & TypeScript & Ant Design Pro v4 从零开始实战教程 #24 详解注册页面手机验证码

25ProUmiJS & TypeScript & Ant Design Pro v4 从零开始实战教程 #25 注册页面手机验证码处理完成

26ProUmiJS & TypeScript & Ant Design Pro v4 从零开始实战教程 #26 手机验证码的原理(后端)

27ProUmiJS & TypeScript & Ant Design Pro v4 从零开始实战教程 #27 注册页面显示图形验证码

28ProUmiJS & TypeScript & Ant Design Pro v4 从零开始实战教程 #28 注册页面图形验证码的原理

29ProUmiJS & TypeScript & Ant Design Pro v4 从零开始实战教程 #29 注册页面提交失败时图形验证码重新刷新

30FreeUmiJS & TypeScript & Ant Design Pro v4 从零开始实战教程 #30 注册页面成功跳转

31ProUmiJS & TypeScript & Ant Design Pro v4 从零开始实战教程 #31 用 localStorage 存储 jwt

FreeUmiJS & TypeScript & Ant Design Pro v4 从零开始实战教程 #32 重构代码,封装 request

33ProUmiJS & TypeScript & Ant Design Pro v4 从零开始实战教程 #33 登录页面

34ProUmiJS & TypeScript & Ant Design Pro v4 从零开始实战教程 #34 完成登录

35ProUmiJS & TypeScript & Ant Design Pro v4 从零开始实战教程 #35 登录权限验证 - 发送请求带上头信息

36ProUmiJS & TypeScript & Ant Design Pro v4 从零开始实战教程 #36 登录权限验证 - umi-request 异常处理程序

37ProUmiJS & TypeScript & Ant Design Pro v4 从零开始实战教程 #37 解决 umi-request 的 extend 关于 headers 的问题

38ProUmiJS & TypeScript & Ant Design Pro v4 从零开始实战教程 #38 显示个人用户信息

39ProUmiJS & TypeScript & Ant Design Pro v4 从零开始实战教程 #39 菜单权限控制显示

40ProUmiJS & TypeScript & Ant Design Pro v4 从零开始实战教程 #40 通过修改 getAuthority 方法利用 jwt 显示正确的菜单权限

41ProUmiJS & TypeScript & Ant Design Pro v4 从零开始实战教程 #41 刷新当前权限

42ProUmiJS & TypeScript & Ant Design Pro v4 从零开始实战教程 #42 其他的权限方法 - 从远程服务器获取菜单

43ProUmiJS & TypeScript & Ant Design Pro v4 从零开始实战教程 #43 权限验证的安全性(准备进入下一阶段)

44ProUmiJS & TypeScript & Ant Design Pro v4 从零开始实战教程 #44 实战 - 视频管理

45ProUmiJS & TypeScript & Ant Design Pro v4 从零开始实战教程 #45 实战 - 视频管理 - 视频列表

46ProUmiJS & TypeScript & Ant Design Pro v4 从零开始实战教程 #46 实战 - 视频管理 - 视频列表 - 发送请求获得远程的数据

47ProUmiJS & TypeScript & Ant Design Pro v4 从零开始实战教程 #47 实战 - 视频管理 - 视频列表 - 显示列表数据

48ProUmiJS & TypeScript & Ant Design Pro v4 从零开始实战教程 #48 实战 - 视频管理 - 视频列表 - 修复列表数据

49ProUmiJS & TypeScript & Ant Design Pro v4 从零开始实战教程 #49 实战 - 视频管理 - 视频列表 - 搜索列表

50ProUmiJS & TypeScript & Ant Design Pro v4 从零开始实战教程 #50 实战 - 视频管理 - 搜索 - 使用 qs 处理 umi-request 提交参数的问题

51ProUmiJS & TypeScript & Ant Design Pro v4 从零开始实战教程 #51 实战 - 视频管理 - 搜索 - 处理 moment 的时间问题

52ProUmiJS & TypeScript & Ant Design Pro v4 从零开始实战教程 #52 实战 - 视频管理 - 完成分页

53ProUmiJS & TypeScript & Ant Design Pro v4 从零开始实战教程 #53 实战 - 视频管理 - 添加视频

54ProUmiJS & TypeScript & Ant Design Pro v4 从零开始实战教程 #54 实战 - 视频管理 - 添加视频 - 发送请求

55ProUmiJS & TypeScript & Ant Design Pro v4 从零开始实战教程 #55 实战 - 视频管理 - 添加视频 - 处理完成

56ProUmiJS & TypeScript & Ant Design Pro v4 从零开始实战教程 #56 实战 - 视频管理 - 错误处理

57ProUmiJS & TypeScript & Ant Design Pro v4 从零开始实战教程 #57 实战 - 视频管理 - 详情页面

58ProUmiJS & TypeScript & Ant Design Pro v4 从零开始实战教程 #58 实战 - 视频管理 - 完成详情页面

59ProUmiJS & TypeScript & Ant Design Pro v4 从零开始实战教程 #59 实战 - 视频管理 - 删除视频

60ProUmiJS & TypeScript & Ant Design Pro v4 从零开始实战教程 #60 实战 - 视频管理 - 添加视频

61ProUmiJS & TypeScript & Ant Design Pro v4 从零开始实战教程 #61 实战 - 视频管理 - 添加视频 part 2

62ProUmiJS & TypeScript & Ant Design Pro v4 从零开始实战教程 #62 实战 - 视频管理 - 添加视频 part 3

63ProUmiJS & TypeScript & Ant Design Pro v4 从零开始实战教程 #63 完结

学员(172)
无痕 · 元婴吴长煌 · 合体姜达 · 元婴默默 · 合体飞 · 太乙弗然 · 元婴宏 · 道祖爱优美 · 元婴小辉 · 元婴Dcdc · 大乘飘临 · 练虚管管 · 金仙
最新动态
无痕 · 元婴学习到了0:00
吴长煌 · 合体学习到了5:14
姜达 · 元婴学习到了3:30
默默 · 合体学习到了5:07
飞 · 太乙学习到了0:00
统计信息
    学员: 17786
    视频数量: 1049
    帖子数量: 427

© 汕尾市求知科技有限公司 | 粤ICP备19038915号 | 关注我们 | 在线学员:116

Top