React+TS请求规范
安装:axios
npm install axios
新增请求文件
-
在
src
目录里面新建api
文件夹 -
在
api
文件夹里面新建request.ts
用于发起请求 -
在
api
文件夹里面新建Api.ts
用于管理接口
编写基础请求格式
下方的部分全部都在 request.ts
中编写
引入 axios
import axios from "axios";
定义基础请求URL
const baseURL = "/api"; //此处的/API与跨域有关,请跳转下方跨域部分
定义获取数据的类型约束
因为接口中绝大部分数据都会首先返回下列三个基础数据类型,所以将其提取出来以便更加快捷获取数据
interface IResponeData {
data: any;
errCode: number;
message: string;
}
//fetch定义请求的类型约束
//当不传输值的时候默认请求方法为POST ,默认不携带token
export default function fetch(
url: string,
params: any,
method: string = "POST",
oheaders: object = {},
) {
return new Promise<IResponeData>((resolve, reject) => {
//请求头部分
let headers = Object.assign({}, { "x-auth-token": localStorage.getItem("token"); }, oheaders);
axios({
// 定义发起请求时的基本类型
method: method,
url: baseURL + url,
data: ["POST", "PUT"].includes(method) ? params : null,
params: ["GET"].includes(method) ? params : null,
headers: headers,
})
.then((res: AxiosResponse<any, any>) => {
resolve(res.data)
})
.catch((err: AxiosError) => {
resolve(err.response?.data as IResponeData)
})
})
};
拆开进行分析:
data: ["POST", "PUT"].includes(method) ? params : null,
进行了一个判断,当 此次请求中 的method
含有 ["POST", "PUT"
两值即能携带参数,当没有包括时就意为着请求方式是GET也就不需要携带参数,那么data就会被赋予空值
let headers = Object.assign({}, { "x-auth-token": localStorage.getItem("token"); }, oheaders);
请求头采用了拼接的方式进行了多步拼接起完整的token
,当Key
值相同时则会进行覆盖,而 oheaders 存在的意义就是当
localStorage.getItem("token")
没有拿到token
时,赋值一个空值 (因为key
值同名时后方会覆盖前方)
(复习)Object.assign( )的用法示例
const obj1 = { name: '张三',age: 20}
const obj2 = { address: '广东深圳', hobby: 'code' }
const obj3 = { workingYears: 5}
const obj = Object.assign(obj1, obj2, obj3)
console.log(obj) //{ name: '张三', age: 20, address: '广东深圳', hobby: 'code', workingYears: 5}
axios({ .... })
.then((res: AxiosResponse<any, any>) => {
resolve(res.data)
})
.catch((err: AxiosError) => {
resolve(err.message)
})
当请求发起成功时, .then
就会获取成功时的数据 而 .catch
就会捕获失败的回调
而 AxiosResponse
与 AxiosError
作用即为定义接收回来数据的类型定义
且也需要引入
import axios, { AxiosError, AxiosResponse } from "axios";
拦截器的用途
响应拦截器的作用:在进入 页面 之前先进行业务逻辑处理,当成功时才运行 进入网页
请求拦截器的作用:在发起 请求 之前先进行业务逻辑处理,当成功时才运行 发起请求
拦截器的层级与 axios({ }) 同层级,不要放在axios成功之后
// 添加请求拦截器
axios.interceptors.request.use(function (config) {
// 在发送请求之前做些什么
return config;
},
function (error) {
// 对请求错误做些什么
return Promise.reject(error);
});
// 添加响应拦截器
axios.interceptors.response.use(function (response) {
// 对响应数据做点什么
return response;
}, function (error) {
// 对响应错误做点什么
return Promise.reject(error);
});
模拟:使用响应拦截器解决token失效时的业务处理
实例:弹出提示框且退出登录
axios.interceptors.response.use(
//使用箭头函数进行的返回值封装,基本不需要更改,可直接复制使用
(value: AxiosResponse<any, any>): AxiosResponse<any, any> => {
return value;
},
function (error) {
if (error.response.data.message === "登录已经失效") {
localStorage.removeItem("token");
alert("登录有效已超时,请重新登录")
setTimeout(() => {
router.navigate("/login")
}, 3000);
}
return Promise.reject(error)
})
API的书写规范
Api.ts
import fetch from "./request";
首先先要引入基础请求中的请求定义
GET请求无参实例
export const GETFastDataApi = () => fetch("/4698", {}, "GET")
-
当没有参数时,使用 空对象进行占位
GET请求带参数实例
export const LoginApi = (params: { password: string; username: string ;nickName?: string;}) => fetch("/1024/login", params)
-
params
定义携带参数的数据名称与类型 -
fetch
中需要有URL
与params
进行传参 -
nickName? 的问号 即为当前是 非必填参数
参数拼接进API当中
export const ChangeCatApi = (params: { actionCode: string; }) => fetch("/6666/" + params.actionCode, {}, "GET")
-
params.actionCode 会被拼接进 URL 当中
参数拼接进API当中 且规定类型
export const UpdateCatListApi = (params: {
testNum: string;
testType: "all" | "err" | "done" | "notdone";
actionCode: string;
questionType: "all" | "qa" | "fill" | "one" | "check" | "code" | "many"
}) => fetch("/1314/" + params, "POST")
-
规定值只能是 提供的值
export const ComfirmApi = (params: {
categoryCode: string;
actionCode: string;
userAnswer: string;
actionType: string;
id: string
}) => fetch("/1314/" + params, "PUT")
-
规定值可以是规定类型下的所有
跨域的书写 :使用代理服务器
利用了vite所自带的serve进行跨域的制作并且能更改baseUrl
vite.config.ts 中
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
export default defineConfig({
plugins: [react()],
css: {
..........
},
//配置代理服务器
server: {
proxy: {//使用代理
'/api': {
target: 'https://52coding.cc/yuantiku_api',
changeOrigin: true,//是否改变请求源头
rewrite: (path) => path.replace(/^\/api/, '')
}}
}})
-
当有/api开头的地址是,代理到target地址
-
此时我们会把 '/api' 这个对象引入到 API文件夹下的request.ts当中充当baseUrl
-
proxy : 意为使用代理
页面中调用接口发送请求
引入请求
import { GETFastDataApi } from "../../api/index"
声明一个调用接口的方法
-
利用 async 与 await 来发起请求
-
data 接收到数据且进行类型约束
export default function index({ }: Props) {
const GETFastDataAction = async () => {
let res = await GETFastDataApi()
let data = res.data as IFastData
}
useEffect(() => {
GETFastDataAction()
}, [])
return (.......)
}
发起请求的触发
-
生命周期函数触发
useEffect(() => {
GETFastDataAction()
}, [])
-
点击事件触发
<Button onClick={() =>{ GETFastDataAction() }}>标签:axios,const,请求,参考,TS,React,params,data,string From: https://www.cnblogs.com/Dollom/p/17037749.html
切换考试科目
</Button>