目录
方法三 使用Spring Security的WebSecurityConfigurerAdapter配置跨域请求:
先说说自己的理解吧,感谢wudumengyan同学的解惑,
http:// www.xxx.com :8080
当浏览一个网页http:// www.xxx.com:8080/index时,例如点击了一个按钮,该网页发一个请求,只要该请求的地址与上面网址三个有一个不对应(协议、域名、端口号),那就是跨域了,这不是网站的问题,也不是项目的问题,而是浏览器的问题,浏览器的同源策略阻止访问。同源策略,其实就是 协议
,主机
, 端口
都相同的,才可以互相访问。
再来说 这个跨域请求是在哪个阶段被拦截了呢?
1.A客户端 发出请求,
2.B服务端 收到请求,
3.B服务端返回响应信息,
4.A收到相应信息。
答案是3 到4之间,A的请求是能正常的发出去的,B服务端后端也正常的响应了, B服务端返回响应信息之后,浏览器是把响应给拦截了。
一般出现在什么地方呢?比如我们前后端分离项目中,前端端口是8088,后端端口是8089 ,访问前端页面的时候发请求到后端就会跨域,还有我们浏览csdn,突然有个广告点了一下跳到了京东页面,也算跨域。
下面是转载的同源策略和跨域的专业解释什么是跨域以及如何解决?通俗易懂带你彻底搞定 - 知乎
一、同源策略
同源策略是一个重要的安全策略,它用于限制一个Origin的文档或者它加载的脚本如何能与另一个源的资源进行交互。它能帮助阻隔恶意文档,减少可能被攻击的媒介。
Origin:指web文档的来源,Web 内容的来源取决于访问的URL的方案 (协议),主机 (域名) 和端口定义。只有当方案,主机和端口都匹配时,两个对象具有相同的起源。
二、跨域
关于URL是否同源,根据上图中的①②③进行判断即可,只要有一点不同,就达到跨域的条件。顺带一提,即便是向域名对应的ip进行资源请求,仍然会跨域。
IE的特殊性:Internet Explorer 的同源策略有两点差异,一是IE未将端口号纳入同源策略的检查,其次是两个高度互信的域名也不受同源策略的检查。
常见的跨域情景:
浏览器内常见的跨域报错:
跨域出现的场景:
一般常见于开发阶段,本地启动项目后,当前页面域名和后台服务器域名不相同,导致跨域。在项目上线后,会通过统一域名、后端配置域名白名单等方式避免跨域。
跨域问题的本质 ,就是浏览器拦截了响应,所以后端只需要在响应头中添加相应的字段,就可以解决跨域问题
解决方式有以下几种:
方法一.在后端定义一个工具类CorsConfig
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
@Configuration
public class CorsConfig {
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.addAllowedOrigin("*"); // 1 设置访问源地址
corsConfiguration.addAllowedHeader("*"); // 2 设置访问源请求头
corsConfiguration.addAllowedMethod("*"); // 3 设置访问源请求方法
corsConfiguration.setMaxAge(1800L);
source.registerCorsConfiguration("/**", corsConfiguration); // 4 对接口配置跨域设置
return new CorsFilter(source);
}
}
方法二. @CrossOrigin 注解
在controller上加上@CrossOrigin 注解或者@CrossOrigin(origins = “http://localhost:8081”),优点是粒度更细,某URL是否跨域可以分开配置,缺点是,如果整个项目都要跨域,则每个controller都需要添加注解
-
CorsFilter过滤器:在Spring Boot中可以通过自定义一个CorsFilter过滤器来配置跨域请求。在该过滤器中设置允许的请求源(
Access-Control-Allow-Origin
)、允许的请求方法(Access-Control-Allow-Methods
)和允许的请求头部(Access-Control-Allow-Headers
)等信息。‘ -
@CrossOrigin注解:在Spring Boot的Controller层的具体方法上添加@CrossOrigin注解,用于指定允许跨域请求的来源、方法和头部信息。
@RestController
@RequestMapping(path = "/user")
@CrossOrigin // 解决跨域问题
public class UserController {
//......
}
方法三 使用Spring Security的WebSecurityConfigurerAdapter配置跨域请求:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors(); // 启用跨域配置
// 其他安全配置...
}
}
方法四:实现 WebMvcConfigurer
-
@Configuration @SuppressWarnings("SpringJavaAutowiredFieldsWarningInspection") public class AppConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") // 拦截所有的请求 .allowedOrigins("http://www.abc.com") // 可跨域的域名,可以为 * .allowCredentials(true) .allowedMethods("*") // 允许跨域的方法,可以单独配置 .allowedHeaders("*"); // 允许跨域的请求头,可以单独配置 } }
方法五,使用nginx:
@Configuration
@SuppressWarnings("SpringJavaAutowiredFieldsWarningInspection")
public class AppConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**") // 拦截所有的请求
.allowedOrigins("http://www.abc.com") // 可跨域的域名,可以为 *
.allowCredentials(true)
.allowedMethods("*") // 允许跨域的方法,可以单独配置
.allowedHeaders("*"); // 允许跨域的请求头,可以单独配置
}
}