前后端分离之跨域和Axios

前后端分离使用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);
    }

你可能感兴趣的:(前后端分离之跨域和Axios)