跨域的基本概念
背景原因
出于浏览器的同源策略限制。同源策略(Sameoriginpolicy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。
概念
当一个请求url的协议、域名、端口三者之间任意一个与当前页面url不同即为跨域
解决跨域
我们准备的请求url是:localhost:8001/Axios 响应的结果就是简单的字符串
@ResponseBody
@GetMapping("/Axios")
public String axios(){
return "hello,world";
}
前端
vue代理服务器proxy跨域:通过请求本地的服务器,然后本地的服务器再去请求远程的服务器(后端部署接口的服务器),最后本地服务器再将请求回来的数据返回给浏览器(本地服务器和浏览器之前不存在跨域)
简单的代理。打开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',
})
后端
添加映射路径和具体的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("*");
}
};
ruoyi-framework中的com.ruoyi.framework.config.ResourcesConfig 类中通过定义CorsFilter来实现
@Configuration
public class ResourcesConfig implements WebMvcConfigurer
{
@Autowired
private RepeatSubmitInterceptor repeatSubmitInterceptor;
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry)
{
/** 本地文件上传路径 */
registry.addResourceHandler(Constants.RESOURCE_PREFIX + "/**")
.addResourceLocations("file:" + BioinfoConfig.getProfile() + "/");
/** swagger配置 */
registry.addResourceHandler("/swagger-ui/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/springfox-swagger-ui/");
}
/**
* 自定义拦截规则
*/
@Override
public void addInterceptors(InterceptorRegistry registry)
{
registry.addInterceptor(repeatSubmitInterceptor).addPathPatterns("/**");
}
/**
* 跨域配置
*/
@Bean
public CorsFilter corsFilter()
{
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
// 设置访问源地址
config.addAllowedOriginPattern("*");
// config.addAllowedOrigin("*");
// 设置访问源请求头
config.addAllowedHeader("*");
// 设置访问源请求方法
config.addAllowedMethod("*");
// 有效期 1800秒
config.setMaxAge(1800L);
// 添加映射路径,拦截一切请求
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", config);
// 返回新的CorsFilter
return new CorsFilter(source);
}
}
添加过滤器
@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 {...}