注明:本文章以前端基于Axios解决和以springboot为基础后端解决方案
首先我们先了解一下跨域
- 为什么会出现跨域:出于浏览器的同源策略限制。同源策略(Sameoriginpolicy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。
- 什么跨域:当一个请求url的协议、域名、端口三者之间任意一个与当前页面url不同即为跨域
我们简单的了解了跨域后直接上正片:怎么解决跨域?
方案一:前端代理解决跨域
- vue代理服务器proxy跨域:通过请求本地的服务器,然后本地的服务器再去请求远程的服务器(后端部署接口的服务器),最后本地服务器再将请求回来的数据返回给浏览器(本地服务器和浏览器之前不存在跨域)
废话上说上代码
我们准备的请求url是:localhost:8001/Axios 响应的结果就是简单的字符串
@ResponseBody
@GetMapping("/Axios")
public String axios(){
return "hello,world";
}
如何在vue里面优雅的解决跨域,路由冲突问题?
简单的代理:打开vue-cil中config中index.js找到代理字段 ,把所有的接口,同意规范为一个入口'api/*',在一定程度上会解决冲突
proxyTable: {
'/api/*': { //统一前缀
targrt:'http://localhost:8001'
}
<template>
<div>
<div >
<div>{{values}}</div>
</div>
</div>
</template>
<script>
export default {
name:'frontout',
data() {
return {
values:''
}
},
mounted() {
this.axios({
url:'/api/Axios',
method:'get',
})
.then(response=>(this.values=response.data))
.catch(function(error){
console.log(error);
})
},
}
</script>
简单的代理已经可以解决单url请求跨域了
当然单一的匹配并不是我们想要的结果 ,我们就可以使用一下方式来解决这个问题:
proxyTable: {
'/api/**':{ //注意是双星
target: "http://localhost:8001",
changeOrigin: true, //如果设置成true:发送请求头中host会设置成target·
pathRewrite: {
'^/api':'/'
}
}
同样会出现每次都要配置/api,当然对各位前端老手来说太简单了,全局默认Url(main.js中)
import Axios from 'axios'
import VueAxios from 'vue-axios'
Vue.use(VueAxios, Axios)
axios.defaults.baseURL='api'
mounted() {
this.axios({
url:'/Axios',
method:'get',
})
简洁明了
方案二:后端解决跨域(4种)
一.添加映射路径和具体的CORS配置路径
@Configuration
public class GlobalCorsConfig {
@Bean
public CorsFilter corsFilter() {
//1. 添加 CORS配置信息
CorsConfiguration config = new CorsConfiguration();
//放行哪些原始域
config.addAllowedOrigin("*");
//放行哪些请求方式
config.addAllowedMethod("*");
//放行哪些原始请求头部信息
config.addAllowedHeader("*");
//暴露哪些头部信息
config.addExposedHeader("*");
//2. 添加映射路径
UrlBasedCorsConfigurationSource corsConfigurationSource = new UrlBasedCorsConfigurationSource();
corsConfigurationSource.registerCorsConfiguration("/**",config);
//3. 返回新的CorsFilter
return new CorsFilter(corsConfigurationSource);
}
}
二.重写WebMvcConfigurer中addCorsMappings方法(全局跨域)
@Bean
public WebMvcConfigurer MyWebMvcConfigurer(){
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
//放行哪些原始域
.allowedOrigins("*")
.allowedMethods(new String[]{"GET", "POST", "PUT", "DELETE"})
.allowedHeaders("*")
.exposedHeaders("*");
}
};
三.添加过滤器
@Component
public class CrosFiter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
Filter.super.init(filterConfig);
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) servletResponse;
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "x-requested-with,content-type");
filterChain.doFilter(servletRequest, servletResponse);
}
@Override
public void destroy() {
Filter.super.destroy();
}
}
四.添加注解
@CrossOrigin
//@CrossOrigin(value = "http://localhost:8001") //单独作用在url上
@GetMapping("/Axios")
public String axios(){
return "hello,world";
}
也可以添加在类上
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface CrossOrigin {...}
个人还是推荐大家使用前端代理解决跨域