经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » JS/JS库/框架 » React » 查看文章
react 高效高质量搭建后台系统 系列 —— 请求数据
来源:cnblogs  作者:彭加李  时间:2023/1/6 8:54:26  对本文有异议

其他章节请看:

react 高效高质量搭建后台系统 系列

请求数据

后续要做登录模块(主页),需要先和后端约定JSON数据格式,将 axios 进行封装,实现本地的数据模拟 mockjs

Tip:spug 中后端返回 json 通常有 data 和 error两个 key。就像这样:{data: [,…], error: ""}

axios

spug 中的 axios

spug 中对 axios 的封装主要在 http.js 文件中。核心是请求拦截器返回拦截器。源码如下:

  1. // spug\src\libs\http.js
  2. // 引入 axios
  3. import http from 'axios'
  4. // 对 history 包最简单的封装,用于下面执行 `history.push`来切换 Url
  5. import history from './history'
  6. // X_TOKEN 登录标识,登录成功后后端返回,存在 localStorage 中
  7. import { X_TOKEN } from './functools';
  8. // 用户错误提示
  9. import { message } from 'antd';
  10. // response处理
  11. function handleResponse(response) {
  12. let result;
  13. // 返回失败。例如 401、404
  14. if (response.status === 401) {
  15. result = '会话过期,请重新登录';
  16. if (history.location.pathname !== '/') {
  17. // 重新登录,登录成功后再回到当前页(from)
  18. history.push('/', {from: history.location})
  19. } else {
  20. return Promise.reject()
  21. }
  22. // 返回成功。例如 200
  23. } else if (response.status === 200) {
  24. // 后端携带错误信息
  25. // 后端返回 json 通常有 data 和 error两个 key。就像这样:{data: [,…], error: ""}
  26. if (response.data.error) {
  27. result = response.data.error
  28. } else if (response.data.hasOwnProperty('data')) {
  29. return Promise.resolve(response.data.data)
  30. // 返回二进制数据
  31. } else if (response.headers['content-type'] === 'application/octet-stream') {
  32. return Promise.resolve(response)
  33. // 不是内部(url 不是以 /api/ 开头)
  34. } else if (!response.config.isInternal) {
  35. return Promise.resolve(response.data)
  36. } else {
  37. result = '无效的数据格式'
  38. }
  39. } else {
  40. result = `请求失败: ${response.status} ${response.statusText}`
  41. }
  42. // 报错
  43. message.error(result);
  44. return Promise.reject(result)
  45. }
  46. // 请求拦截器
  47. http.interceptors.request.use(request => {
  48. request.isInternal = request.url.startsWith('/api/');
  49. // 对内部 url 增加 X-Token 标识。初次登陆 X-Token 为 null
  50. if (request.isInternal) {
  51. request.headers['X-Token'] = X_TOKEN
  52. }
  53. // 请求超时设置为 30 秒
  54. request.timeout = request.timeout || 30000;
  55. return request;
  56. });
  57. // 返回拦截器
  58. http.interceptors.response.use(response => {
  59. return handleResponse(response)
  60. }, error => {
  61. if (error.response) {
  62. return handleResponse(error.response)
  63. }
  64. const result = '请求异常: ' + error.message;
  65. message.error(result);
  66. return Promise.reject(result)
  67. });
  68. export default http;

用法大致就像这样(请看 Dashboard 模块中的 store.js):

  1. import http from 'libs/http';
  2. http.get('/api/cicd/gitlab/')
  3. .then(res => this.gitlabList = res)

myspug 引入 axios

创建 myspug\src\libs\http.js 文件,内容和 spug 相同

创建 history.js 文件,内容和 spug 相同

  1. // myspug\src\libs\history.js
  2. import {createBrowserHistory} from 'history';
  3. export default createBrowserHistory()

创建 functools.js,目前只需要导出 X_TOKEN 即可。spug 中的 functools.js 涉及权限,后续我们可能会用上。

  1. // myspug\src\libs\functools.js
  2. export let X_TOKEN;

疑惑:在研究 react 路由时,我们自己实现了一个路由,使用 history 时发现它会导致浏览器 url 的变化,我们会通过 history.listen 来监听地址变化,而在 spug 官网中执行 history.push 不仅可以切换url,而且路由也发生了变化,但笔者没有在源码中找到 history.listen 的相关代码

mock

详细介绍请看 这里

spug 默认没有 mockjs,笔者将其加入 myspug 中,方便后续前端开发。

Tip: 内网可以使用 docker 方式快速搭建 yapi(高效、易用、功能强大的可视化接口管理平台)

大致步骤如下:

  • 安装 mockjs 包,上文我们已经安装完毕
  • 新建 src/mock/index.js
  • 最后在 src/index.js 中引入 mock

最后在 App.js 中测试:

  1. // myspug\src\App.js
  2. // import http from 'libs/http';
  3. import http from '@/libs/http';
  4. export default function App() {
  5. http.post('/api/account/login/', {})
  6. .then(data => console.log('data', data))
  7. return (
  8. <div className="App">...</div >
  9. );
  10. }

控制台输出:

  1. data {id: 1, access_token: '5bb076db06fd4001b85d12e44ab96c56', nickname: '管理员', is_supper: true, has_real_ip: true, …}

:spug 中引入 http 直接是 import http from 'libs/http';,在 vscode 中按住 ctrl 并将鼠标移至 libs/http 能进入该文件,而笔者的 myspug 却报错,提示./lib/http。找不到原因,只能求其次,通过增加别名 @ 来避免相对符号 ../../../

  1. // config-overrides.js
  2. const { override, fixBabelImports,addWebpackAlias } = require('customize-cra');
  3. const path = require('path')
  4. module.exports = override(
  5. ...,
  6. addWebpackAlias({
  7. '@': path.resolve(__dirname, './src')
  8. })
  9. );

扩展

修改默认启动端口 3000

由于 create-react-app 启动端口默认是 3000,笔者为了方便研究,需要同时启动 spug 和 myspug 两个项目,这里将 spug 的端口改为 3010

  1. // package.json
  2. "scripts": {
  3. - "start": "react-app-rewired start",
  4. + "start": "set PORT=3010 && react-app-rewired start",

其他章节请看:

react 高效高质量搭建后台系统 系列

原文链接:https://www.cnblogs.com/pengjiali/p/17025037.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号