前后端分离使用axios直接请求后面网关可能遇到的问题:
1、Axios跨域问题
2、Axios获取数据失败spring MVC接收数据失败
下面给出多种姿势解决方案,按实际挑选即可。
一、跨域
1、方案
cli 4.x 可在vue.config.js中修改配置:
可参考官网介绍:https://cli.vuejs.org/zh/config/#devserver-proxy
module.exports = {
devServer: {
proxy: {
'/api': {
target: 'http://api.gateway.com', //目标接口域名
pathRewrite: {
'^/api': '' //重写接口
},
changeOrigin: true, //是否跨域
},
'/foo': {
target: ''
}
}
}
}
cli 4.x除了上面,在直接套用vue-admin-template模板时,可直接修改:
.env.development、.env.production、.env.staging下的VUE_APP_BASE_API
:
# base api
# VUE_APP_BASE_API = '/dev-api'
VUE_APP_BASE_API = 'http://gateway:8888'
2、方案
cli 3.x可在config/index.js加入:
proxyTable: {
'/api': {
target: 'http://api.gateway.com', //目标接口域名
pathRewrite: {
'^/api': '' //重写接口
},
changeOrigin: true, //是否跨域
},
},
3、方案
自定义工具类:request.js
优点是可增加request、response拦截,前后端分离采用这种形式
import axios from 'axios'
// create an axios instance
const service = axios.create({
baseURL: 'http://gateway:8888', // url = base url + request url
// withCredentials: true, // send cookies when cross-domain requests
timeout: 5000 // request timeout
})
export default service
调用如下:
import request from 'request'
// ...
function login(username,password) {
return request({
url: '/api/oauth/user/login',
method: 'post',
{username:username,password:password}
})
}
二、spring MVC接收数据失败
axios默认发送json数据,spring MVC使用如下接收将失败:
@PostMapping("/user/login1")
public ResponseResult login1(String username,String password) {
SsoUser user = userService.getUserInfo(username);
if (user == null || !user.getPassword().equals(password)) {
return new ResponseResult(CodeStatus.FAIL, "账号或密码错误!");
}
return new ResponseResult(CodeStatus.OK, "登录成功", result);
}
2.1 解决方案之改后端
在不改动axios前提下,Spring MVC可使用对象接收,使用@RequestBody
注解:这是前后端分离采用的方案
@PostMapping("/user/login")
public ResponseResult login(@RequestBody LoginParam loginParam) {
SsoUser user = userService.getUserInfo(loginParam.getUsername());
if (user == null || !user.getPassword().equals(loginParam.getPassword())) {
return new ResponseResult(CodeStatus.FAIL, "账号或密码错误!");
}
return new ResponseResult(CodeStatus.OK, "登录成功", result);
}
LoginParam.java
@Data
public class LoginParam implements Serializable {
private String username;
private String password;
}
2.2 解决方案之改Axios
可以直接使用vue自带的ps
import axios from 'axios'
import qs from 'qs'
// ......
axios.post('/api/login',qs.stringify({username:'123',password:'123'}))
.then((response) => {
console.log(response)
})
后台的接收如下:
@PostMapping("/user/login")
public ResponseResult login(String username,String password) {
SsoUser user = userService.getUserInfo(username);
if (user == null || !user.getPassword().equals(password)) {
return new ResponseResult(CodeStatus.FAIL, "账号或密码错误!");
}
return new ResponseResult(CodeStatus.OK, "登录成功", result);
}