这两天在尝试做vue2+ssm的学习,遇到跨域请求的问题,下面简单写下使用axios的跨域请求问题处理方法
后台我配置了跨域过滤器:
package com.chaofan.www.core.filter; /** * Created by junko on 2017/4/16. */ import org.springframework.web.filter.OncePerRequestFilter; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; public class CorsFilter extends OncePerRequestFilter { @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { response.addHeader("Access-Control-Allow-Origin", "*"); //允许所有网址发来的请求 response.addHeader("Access-Control-Allow-Methods", "REQUEST,GET,POST,PUT,DELETE,PATCH,HEAD");//允许的请求方法 response.addHeader("Access-Control-Allow-Headers", "Content-Type"); //,X-Requested-With,auth_token response.addHeader("Access-Control-Max-Age", "1800");//30 min filterChain.doFilter(request, response); } }
在web.xml中配置该过滤器:
<!--跨域过滤器--> <filter> <filter-name>cros</filter-name> <filter-class>com.chaofan.www.core.filter.CorsFilter</filter-class> </filter> <filter-mapping> <filter-name>cros</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
前台使用axios封装ajax请求,在main.js中的配置如下:
import axios from 'axios' import qs from 'qs'
let axiosIns = axios.create({}); if (process.env.NODE_ENV == 'development') { axiosIns.defaults.baseURL = 'http://localhost'; } else if (process.env.NODE_ENV == 'debug') { axiosIns.defaults.baseURL = '***'; } else if (process.env.NODE_ENV == 'production') { axiosIns.defaults.baseURL = '***'; } axiosIns.defaults.headers.post['X-Requested-With'] = 'XMLHttpRequest'; axiosIns.defaults.headers.get['X-Requested-With'] = 'XMLHttpRequest'; axiosIns.defaults.responseType = 'json'; axiosIns.defaults.transformRequest = [function (data) { //数据序列化 return qs.stringify(data); } ]; axiosIns.defaults.validateStatus = function (status) { return true; }; axiosIns.interceptors.request.use(function (config) { //配置config config.headers.Accept = 'application/json'; // config.headers.System = 'vue'; // let token = Vue.localStorage.get('token'); // if(token){ // config.headers.Token = token; // }else{ config.headers.auth_token = "auth_token" // } return config; }); axiosIns.interceptors.response.use(function (response) { let status = response.status; if (status === 200) { return Promise.resolve(response); } else { return Promise.reject(response); } }); let ajaxMethod = ['get', 'post']; let api = {}; ajaxMethod.forEach((method) => { //数组取值的两种方式 api[method] = function (uri, data, config) { return new Promise(function (resolve, reject) { Indicator.open({ text: '请等待', spinnerType: 'fading-circle' }); axiosIns[method](uri, data, config).then((response) => { Indicator.close(); resolve(response); }).catch((e) => { Indicator.close(); if(e.status){ if (e.status === 404) { Toast({ position: 'bottom', message: '资源不存在,请重试', iconClass: 'icon-error', duration:10000 }); return; } } Toast({ position: 'bottom', message: "网络异常,请重试", iconClass: 'icon-error' }); }) }) } }); Vue.prototype.$axios = api;
然后在vue文件里调用:
this.$axios.get('http://localhost:9090/api/user/login?account='+this.account+'&password='+this.password).then(function (response) {
省略部分代码
这里可以看到,我的vue项目运行在localhost的8080端口,java后端运行在localhost的9090端口,执行请求控制台报错如图:
意思是说,请求头中的“auth_token”不被后端的服务器的Access-Control-Allow-Header所允许,这个“auth_token”是我自定义设置的,如图:
既然服务器不允许,那我就去改后台的Access-Control-Allow-Header值让它允许就行了:
再次请求:
这时候报了X-Requested-With不被允许了,我就再把它加到后台的Access-Control-Allow-Header中:
再次请求:
这时就没报错了,也就可以跨域了。
你也许明白了,只要控制台报了类似上面两个的错误时,就修改后台的Access-Control-Allow-Header的值就行了。
注意:如果你没有像我给请求头添加自定义的域(如:auth_token)的话,那么只会出现X-Requested-With不被允许