目录
什么是跨域
协议://域名:端口
一个不一样就是跨域
在浏览器的同源策略中,如果两个网页的协议(例如,http 或 https)、端口(例如,80 或 443)或域名(例如,example.com)中有任何一个不同,那么这两个网页就被认为是不同源的。这就意味着,一般情况下,一个网页无法获取或操作另一个源的资源。
这种限制是出于安全考虑。如果没有同源策略,一个恶意网站可能会试图通过脚本来读取或修改另一个网站的数据,这会导致严重的安全问题。
然而,有时我们需要让一个网页可以访问另一个源的资源。这时,我们就需要使用跨源资源共享(CORS)机制。通过设置 HTTP 响应头,服务器可以告诉浏览器,它允许哪些源的网页访问它的资源。
配置文件解决跨域问题
import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class CorsConfig implements WebMvcConfigurer { /** * 开启跨域 */ @Override public void addCorsMappings(CorsRegistry registry) { // 设置允许跨域的路由 registry.addMapping("/**") // 设置允许跨域请求的域名 .allowedOriginPatterns("*") // 是否允许证书(cookies) .allowCredentials(true) // 设置允许的方法 .allowedMethods("*") // 跨域允许时间 .maxAge(3600); } }
注解解决跨域问题
@CrossOrigin("*")
加在方法或类上
拦截器解决跨域问题
@Component public class CorsInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { response.setHeader("Access-Control-Allow-Origin", "*"); response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS"); response.setHeader("Access-Control-Max-Age", "3600"); response.setHeader("Access-Control-Allow-Headers", "authorization, content-type"); return true; } }
过滤器实现
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 MyCorsFilter { @Bean public CorsFilter corsFilter() { // 1.创建 CORS 配置对象 CorsConfiguration config = new CorsConfiguration(); // 支持域 config.addAllowedOriginPattern("*"); // 是否发送 Cookie config.setAllowCredentials(true); // 支持请求方式 config.addAllowedMethod("*"); // 允许的原始请求头部信息 config.addAllowedHeader("*"); // 暴露的头部信息 config.addExposedHeader("*"); // 2.添加地址映射 UrlBasedCorsConfigurationSource corsConfigurationSource = new UrlBasedCorsConfigurationSource(); corsConfigurationSource.registerCorsConfiguration("/**", config); // 3.返回 CorsFilter 对象 return new CorsFilter(corsConfigurationSource); } }
使用ResponseBodyAdvice
import org.springframework.core.MethodParameter; import org.springframework.http.MediaType; import org.springframework.http.server.ServerHttpRequest; import org.springframework.http.server.ServerHttpResponse; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice; @ControllerAdvice public class ResponseAdvice implements ResponseBodyAdvice { /** * 内容是否需要重写(通过此方法可以选择性部分控制器和方法进行重写) * 返回 true 表示重写 */ @Override public boolean supports(MethodParameter returnType, Class converterType) { return true; } /** * 方法返回之前调用此方法 */ @Override public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) { // 设置跨域 response.getHeaders().set("Access-Control-Allow-Origin", "*"); return body; } }