react 高效高质量搭建后台系统 系列 —— 请求数据
其他章节请看:
请求数据
后续要做登录模块
(主页),需要先和后端约定JSON数据格式,将 axios
进行封装,实现本地的数据模拟 mockjs
。
Tip:spug 中后端返回 json 通常有 data 和 error两个 key。就像这样:{data: [,…], error: ""}
axios
spug 中的 axios
spug 中对 axios 的封装主要在 http.js
文件中。核心是请求拦截器
和返回拦截器
。源码如下:
// spug\src\libs\http.js
// 引入 axios
import http from 'axios'
// 对 history 包最简单的封装,用于下面执行 `history.push`来切换 Url
import history from './history'
// X_TOKEN 登录标识,登录成功后后端返回,存在 localStorage 中
import { X_TOKEN } from './functools';
// 用户错误提示
import { message } from 'antd';
// response处理
function handleResponse(response) {
let result;
// 返回失败。例如 401、404
if (response.status === 401) {
result = '会话过期,请重新登录';
if (history.location.pathname !== '/') {
// 重新登录,登录成功后再回到当前页(from)
history.push('/', {from: history.location})
} else {
return Promise.reject()
}
// 返回成功。例如 200
} else if (response.status === 200) {
// 后端携带错误信息
// 后端返回 json 通常有 data 和 error两个 key。就像这样:{data: [,…], error: ""}
if (response.data.error) {
result = response.data.error
} else if (response.data.hasOwnProperty('data')) {
return Promise.resolve(response.data.data)
// 返回二进制数据
} else if (response.headers['content-type'] === 'application/octet-stream') {
return Promise.resolve(response)
// 不是内部(url 不是以 /api/ 开头)
} else if (!response.config.isInternal) {
return Promise.resolve(response.data)
} else {
result = '无效的数据格式'
}
} else {
result = `请求失败: ${response.status} ${response.statusText}`
}
// 报错
message.error(result);
return Promise.reject(result)
}
// 请求拦截器
http.interceptors.request.use(request => {
request.isInternal = request.url.startsWith('/api/');
// 对内部 url 增加 X-Token 标识。初次登陆 X-Token 为 null
if (request.isInternal) {
request.headers['X-Token'] = X_TOKEN
}
// 请求超时设置为 30 秒
request.timeout = request.timeout || 30000;
return request;
});
// 返回拦截器
http.interceptors.response.use(response => {
return handleResponse(response)
}, error => {
if (error.response) {
return handleResponse(error.response)
}
const result = '请求异常: ' + error.message;
message.error(result);
return Promise.reject(result)
});
export default http;
用法大致就像这样(请看 Dashboard 模块中的 store.js
):
import http from 'libs/http';
http.get('/api/cicd/gitlab/')
.then(res => this.gitlabList = res)
myspug 引入 axios
创建 myspug\src\libs\http.js
文件,内容和 spug 相同
创建 history.js
文件,内容和 spug 相同
// myspug\src\libs\history.js
import {createBrowserHistory} from 'history';
export default createBrowserHistory()
创建 functools.js
,目前只需要导出 X_TOKEN 即可。spug 中的 functools.js 涉及权限,后续我们可能会用上。
// myspug\src\libs\functools.js
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 中测试:
// myspug\src\App.js
// import http from 'libs/http';
import http from '@/libs/http';
export default function App() {
http.post('/api/account/login/', {})
.then(data => console.log('data', data))
return (
<div className="App">...</div >
);
}
控制台输出:
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
。找不到原因,只能求其次,通过增加别名 @ 来避免相对符号 ../../../
// config-overrides.js
const { override, fixBabelImports,addWebpackAlias } = require('customize-cra');
const path = require('path')
module.exports = override(
...,
addWebpackAlias({
'@': path.resolve(__dirname, './src')
})
);
扩展
修改默认启动端口 3000
由于 create-react-app 启动端口默认是 3000,笔者为了方便研究,需要同时启动 spug 和 myspug 两个项目,这里将 spug 的端口改为 3010
。
// package.json
"scripts": {
- "start": "react-app-rewired start",
+ "start": "set PORT=3010 && react-app-rewired start",
其他章节请看:
最新文章
- 用C#实现封装
- nba技能表
- angular学习-入门基础
- Linux Program
- PhpStorm 获取注册码
- ios NSAssert趣谈
- android本地定时通知
- Oracle EBS-SQL (BOM-4):检查期间新增编码总数.sql
- C++ 用libcurl库进行http 网络通讯编程
- jquery的2.0.3版本源码系列(1)总体结构
- [图像类名词解释][ RGB YUV HSV相关解释说明]
- 使用d3.v5实现饼状图
- 不同网段无法加载ArcGIS Server发布服务解决方法
- POSTMAN模拟AJAX请求
- 让你提前认识软件开发(31):数据库脚本中的begin与end
- android 6.0 动态权限
- CF-517B-DP
- tomcat ->; 简介&;部署
- CAS (7) —— Mac下配置CAS 4.x的JPATicketRegistry(服务端)
- 仿照hibernate封装的一个对数据库操作的jdbc工具类
热门文章
- commons-fileupload组件和commons-io组件的详细下载
- Java模拟生产者-消费者问题。生产者不断的往仓库中存放产品,消费者从仓库中消费产品。其中生产者和消费者都可以有若干个。在这里,生产者是一个线程,消费者是一个线程。仓库容量有限,只有库满时生产者不能存
- XAF新手入门 - 类型子系统(Types Info Subsystem)
- 如何在.NET程序崩溃时自动创建Dump?
- 2流高手速成记(之七):基于Dubbo&;Nacos的微服务简要实现
- JAVA的File对象
- C#使用GDI+同时绘制图像和ROI在picturebox上
- perl中ENV的使用
- centos7 uwsgi 加入系统服务
- Kubernetes基础_Service暴露的两种方式