解决Vue前后端分离跨域问题

前言

用Vue写了几个页面,发现request传到后端没带上cookies,心想不对劲,Postman明明可以访问啊。再仔细看看,后端已经开放了跨域访问,不需要HttpServletRequest的接口也可以成功请求。一定就是前端请求缺少请求头或是某些参数了。上网查了一下还真是这样,又跳过了一个坑,很开心啦~

前后端跨域设置

Vue

main.js 设置

1
2
3
4
import axios from 'axios'

axios.defaults.withCredentials=true;
Vue.prototype.$http = axios;

请求需带上withCredentials

1
2
3
4
5
6
7
8
9
10
11
12
13
getData() {
this.$axios.get('http://127.0.0.1:8080/xxx/xxxxx',{
headers: {
"Content-Type":"application/json;charset=utf-8"
},
withCredentials : true
}).then( (response) => {
if( response.data.code === '0000'){
this.items = response.data.data.xxx;
console.log(this.items)
}
})
}

SpringMVC

加上一个跨域用Interceptor

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@Component
public class CorsInterceptor implements HandlerInterceptor {

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
Object handler) throws Exception {
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "*");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
response.setHeader("Access-Control-Allow-Credentials","true"); //是否允许浏览器携带用户身份信息(cookie)
return true;
}

@Override
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {

}

@Override
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {

}
}

可能遇到的问题

1
response.setHeader("Access-Control-Allow-Origin", "*");

请求源地址如果写了*很可能会被拒绝访问。

1
Failed to load http://127.0.0.1:8080/zhiliao/login: Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. Origin 'http://127.0.0.1:8000' is therefore not allowed access. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.

如果出现这样的报错,那就得指定地址啦!

1
response.setHeader("Access-Control-Allow-Origin", "http://127.0.0.1:8000");

这里依旧有个小坑:指定地址为http://127.0.0.1:8000的时候前端页面若是localhost是无法访问的。

看看axios官方文档

axios官方配置说明

1
2
3
4
5
6
7
8
9
10
11
12
13
// `timeout` specifies the number of milliseconds before the request times out.
// If the request takes longer than `timeout`, the request will be aborted.
timeout: 1000,

// `withCredentials` indicates whether or not cross-site Access-Control requests
// should be made using credentials
withCredentials: false, // default

// `adapter` allows custom handling of requests which makes testing easier.
// Return a promise and supply a valid response (see lib/adapters/README.md).
adapter: function (config) {
/* ... */
},

配置文件中withCredentials默认是关闭的,手动修改配置文件或在项目中重定义即可。