前言
之前我们提到了token
的全局状态存储,对于后台管理系统而言,业务信息接口带上请求头token是有必要的,故我们在此对http请求工具库axios
做一下封装。当然,首先需要安装。
Http请求工具axios封装
介绍
Axios 是一个基于 promise 网络请求库,作用于
node.js
和浏览器中。 它是 同构的(即同一套代码可以运行在浏览器和node.js中)。在服务端它使用原生 node.jshttp
模块, 而在客户端 (浏览端) 则使用 XMLHttpRequests。
安装axios与antd
css
npm install axios
npm install antd --save
封装axios
src下创建utils文件夹,在其下新建request.js
文件。随后设置请求拦截器,如果请求的是业务接口那么请求头带上token,如果不是的话加入白名单。响应拦截器则需要对返回blob文件流和正常业务数据做判断,文件流直接返回,而业务数据返回data数据。
设置拦截器
src/utils/request.js
javascript
import Axios from 'axios'
import { getToken } from '../utils/auth'
// 用axios的message来提示接口响应状况
import { message } from 'antd'
const BASE_URL = process.env.NODE_ENV==='production'?'':'/api' //请求接口url 如果不配置 则默认访问链接地址
const TIME_OUT = 20000 // 接口超时时间
const instance = Axios.create({
baseURL: BASE_URL,
timeout: TIME_OUT
})
// 不需要token的接口白名单
const whiteList = ['/user/login', '/user/checkCode']
// 添加请求拦截器
instance.interceptors.request.use(
(config) => {
if (config.url && typeof config.url === 'string') {
if (!whiteList.includes(config.url)) {
let Token = getToken()
if (Token && Token.length > 0) {
config.headers && (config.headers['Authorization'] = Token)
}
}
}
return config
},
(error) => {
return Promise.reject(error)
}
)
// 添加响应拦截器
instance.interceptors.response.use(
(response) => {
// 如果返回的类型为二进制文件类型
if (response.config.responseType === 'blob') {
if (response.status !== 200) {
message.error('请求失败' + response.status)
return Promise.reject()
} else if (!response.headers['content-disposition']) {
message.error('暂无接口访问权限')
return Promise.reject()
}
return response
} else {
// 如果接口请求失败
if (response.data.code !== 0) {
let errMsg = response.data.message || '系统错误'
return Promise.reject(errMsg)
}
return response.data
}
},
(error) => {
return Promise.reject(error)
}
)
测试接口服务
所需准备
后端服务及接口文档
接下来要测试接口服务的话,这里就要用到之前给大家提供的node后端服务器
【node后端服务器】:
1.克隆到本地后新建mysql数据库并运行sql目录下的database.sql文件
2.修改model目录下init.js中的数据库信息
2.npm install
安装依赖
3.npm start
启动服务
【接口文档】:提供了接口url信息及所需请求参数
跨域配置
1.安装http-proxy-middleware模块
css
npm i http-proxy-middleware --save
2.src
下新建setupProxy.js
文件(文件名必须一致)
src/setupProxy.js
javascript
const { createProxyMiddleware } = require('http-proxy-middleware')
module.exports = function (app) {
app.use(
'/api',
createProxyMiddleware({
target: 'http://127.0.0.1:9999', // 后台服务地址以及端口号
changeOrigin: true, // 是否开启代理
pathRewrite: {
'/api': '' // 代理前缀重写
}
})
)
}
3.重启项目(必须)
测试接口
完成跨域配置之后,我们就可以在项目中尝试是否能够连通接口。我们把之前Home组件测试redux的代码删掉,开始编写接口方法。
1.引入封装的axios
实例
javascript
import request from '@/utils/request'
2.编写axios
连接接口方法(这里以获取验证码为例)
src/pages/Home/index.jsx
javascript
import React, { useEffect } from 'react'
import request from '@/utils/request'
const Home = () => {
useEffect(() => {
const fetchCode = async () => {
const code = await request({
url: 'http://127.0.0.1:9999/user/checkCode',
method: 'get',
params: {
// 用当前时间戳作为验证码的id
uuid: new Date().getTime()
}
})
console.log(code)
}
fetchCode()
}, [])
return <div>Home</div>
}
export default Home
3.连接成功
封装接口
测试成功后大家应该会发现一个问题,每次编写接口方法都要引入axios
封装文件,然后一步一步地编写方法,显得十分麻烦。所以接下来我们就要对所有的接口进行封装(参考上面的接口文档)。我们用一个对象管理模块对应的api方法然后导出,使用的时候在组件中导入import Api from '...'
,通过Api.xxModule.add()
调用接口方法即可,代码示例:
javascript
// xxApi.js
const apiMap={
xxModule:{
add:xxaddFunc()
get:xxGetFunc()
}
xxModule:{}
}
export default apiMap
xxaddFunc(){}
xxGetFunc(){}
// xx.jsx
import Api from '...'
...
const add=()=>{
const res=await Api.xxModule.add()
console.log(res)
}
然后我们以用户模块的封装为例,总共分为三个模块:登录模块、用户模块和用户中心模块,然后编写对应的接口方法再导出即可。
src/api/user/index.js
javascript
// 导入axios实例
import request from '@/utils/request'
// 导入获取refreshToken的方法
import { getRefreshToken } from '@/utils/auth'
const apiMap = {
// 登录
login: {
get: getCheckCode,
login: userLogin,
refresh: refreshToken
},
// 用户管理
manage: {
add: addUser,
update: updateUser,
del: delUser,
query: listUser,
queryById: getUserById,
reset: updatePwd // 重置密码
},
// 用户中心
center: {
get: getUserInfo,
update: updateUserInfo
}
}
export default apiMap
// 获取图形验证码
function getCheckCode(uuid) {
return request({
url: '/user/checkCode?uuid=' + uuid,
method: 'get'
})
}
// 刷新过期token
function refreshToken() {
...
}
// 添加用户登录请求
function userLogin(form) {
...
}
// 获取用户列表
function listUser(params) {
...
}
...
最后我们修改下上面Home组件写的获取验证码的方法
src/pages/Home/index.jsx
javascript
import React, { useEffect } from 'react'
import userApi from '@/api/user'
const Home = () => {
useEffect(() => {
const fetchCode = async () => {
const code = await userApi.login.get()
console.log(code)
}
fetchCode()
}, [])
return <div>Home</div>
}
export default Home
也能正常响应
代码
上述实现的代码都放在react-antd5-admin,大家可自行查阅