node js版本:18.20.2
react 版本18.3.1
axios 版本1.6.8
这个版本应该是目前使用比较新的版本使用react +axios 搭建项目
我这里只是做一个自己的错误记录如果有小伙伴出现了类似情况请注意
搭建项目的时候呢我是释放了eject 其实antd 项目和自己搭建还是有很大的区别 主体和扩展性自己去搭建的呢 相对来说比较熟悉自己的项目脚手架
配置代理文件:setupProxy.js
const {createProxyMiddleware} = require('http-proxy-middleware');
module.exports = function (app) {
app.use(
createProxyMiddleware('/api/', {
target: process.env.BASE_URL,
changeOrigin: true,
pathRewrite: {
'^/api': '',
},
})
);
};
这里是我的axios配置 注意:这里是有问题的
import {notification} from 'antd';
import axios, {AxiosResponse, AxiosError} from 'axios';
import storageData from '@/utils/storage';
import {YuHaiToken} from '@/utils/config';
const service = axios.create({
baseURL: process.env.REACT_APP_API_URL,
timeout: 1000 * 60 * 3,
});
// 异常拦截处理器
const errorHandler = (error: AxiosError) => {
if (error && error.message && error.message.includes('timeout')) {
notification.error({
message: '请求超时',
description: '请重试',
duration: 0,
});
}
if ((error as any).data) {
const data = (error as any).data;
if (data.code === 403) {
notification.error({
message: '请求错误',
description: data.message,
});
}
}
return Promise.reject(error);
};
// 请求拦截
service.interceptors.request.use((config: any) => {
if (!navigator.onLine) {
notification.error({
message: '网络断开',
description: '请检查网络',
});
}
const token = storageData.get(YuHaiToken);
if (token) {
config.headers = {...config.headers, 'yuhai-token': `${token}`};
}
return config;
}, errorHandler);
// 响应拦截
service.interceptors.response.use((res: AxiosResponse) => {
if (res.data.code === 401) {
notification.error({
message: '提示',
description: '身份已失效,请重新登录',
})
}
return res.data;
}, errorHandler);
export {service as axios};
这样的一个配置就导致两个问题
***Uncaught runtime errors:
×
ERROR
Network Error
AxiosError: Network Error
at XMLHttpRequest.handleError (http://localhost:2000/main.b30c5b7dbc5ac235e98d.hot-update.js:2918:14)
at Axios.request (http://localhost:2000/main.b30c5b7dbc5ac235e98d.hot-update.js:3365:41)
at async jumpPage (http://localhost:2000/main.3f61c992c70a35873d42.hot-update.js:45:5)***
这个很清楚的看出是找不到请求网络地址导致出现跨域问题
请求网址:
http://localhost:8080/userLogin
引荐来源网址政策:
strict-origin-when-cross-origin
network 网络显示跨域了 找不到目标服务器但是发现请求地址不是通过代理地址转发的
前端:请求代码
export async function login(data: any): Promise<any> {
return axios.post('userLogin', data);
}
后端:
项目请求前缀
server:
port: 8080
servlet:
context-path: /
接口代码
@SaIgnore
@ApiOperation("登录")
@PostMapping("userLogin")
public E login(@Valid @RequestBody LoginDTO loginDTO) {
SaTokenInfo loginVO = sysUserService.sysUsersLogin(loginDTO);
return E.success(loginVO);
}
看似没有任何问提但是问题来了:
现在baseURL转发的是目标地址并非使用的项目中的代理地址
代理的概念可以结合Nginx的转发进行理解
源地址-Prot:2000 ——>转发地址-Prot:8080
原地址就不是通过代理地址去转发目标地址的
我们先看看会导致什么问题
post请求不携带参数时请求正常
post请求携带参数时请求出现解析请求头类型错误问题
后端异常:
- Resolved [org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'multipart/form-data;boundary=----WebKitFormBoundaryOTlze3uu0A68QQYZ;charset=UTF-8' not supported]
尝试配置请求头
前端axios配置:
config.headers = {...config.headers, 'Content-Type': 'application/json'};
继续重新请求:
出现跨域问题
尝试配置其他类型
config.headers = {...config.headers, 'Content-Type': 'application/x-www-form-urlencoded'};
好家伙不行
其实到这里才知道问题出在转发什么
baseUrl应该使用源地址的代理api
const service = axios.create({
// API 请求的默认前缀
// 接口原地址
baseURL:'api'
timeout: 1000 * 60 * 3,
});