如何提高网站的安全性,河南洛阳网站建设,seo技术服务外包,做视频网站资金多少#x1f3f7;️个人主页#xff1a;牵着猫散步的鼠鼠 #x1f3f7;️系列专栏#xff1a;Java全栈-专栏 #x1f3f7;️个人学习笔记#xff0c;若有缺误#xff0c;欢迎评论区指正 目录
前言
解决跨域问题方案
1.Spring Boot 中解决跨域
1.1 通过注解跨域
1.2 通… ️个人主页牵着猫散步的鼠鼠 ️系列专栏Java全栈-专栏 ️个人学习笔记若有缺误欢迎评论区指正 目录
前言
解决跨域问题方案
1.Spring Boot 中解决跨域
1.1 通过注解跨域
1.2 通过配置文件跨域
1.3 通过 CorsFilter 跨域
1.4 通过 Response 跨域
1.5 通过 ResponseBodyAdvice 跨域
2.Nginx 中解决跨域
3.网关中解决跨域
3.1 配置文件中设置跨域
3.2 添加 CorsWebFilter 来解决跨域问题
小结 前言
跨域问题是浏览器为了保护用户的信息安全实施了同源策略Same-Origin Policy即只允许页面请求同源相同协议、域名和端口的资源当 JavaScript 发起的请求跨越了同源策略即请求的目标与当前页面的域名、端口、协议不一致时浏览器会阻止请求的发送或接收。
解决跨域问题方案
跨域问题可以从以下方面解决
应用层面解决例如 Spring Boot 项目中解决跨域问题。反向代理解决例如 Nginx 中解决跨域问题。网关中解决例如 Spring Cloud Gateway 中解决跨域问题。
而这 3 类解决方案总共包含了 8 种解决方案我们一起来看。
1.Spring Boot 中解决跨域
在 Spring Boot 中跨域问题有以下 5 种解决方案
使用 CrossOrigin 注解实现跨域【局域类跨域】通过配置文件实现跨域【全局跨域】通过 CorsFilter 对象实现跨域【全局跨域】通过 Response 对象实现跨域【局域方法跨域】通过实现 ResponseBodyAdvice 实现跨域【全局跨域】
接下来详细来看。
1.1 通过注解跨域
使用 CrossOrigin 注解可以轻松的实现跨域此注解既可以修饰类也可以修饰方法。当修饰类时表示此类中的所有接口都可以跨域当修饰方法时表示此方法可以跨域它的实现如下
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
RestController
CrossOrigin(origins *) //origins可以指定请求来源*代表全部
public class TestController {RequestMapping(/test)public HashMapString, Object test() {return new HashMapString, Object() {{put(state, 200);put(data, success);put(msg, );}};}
}以上代码的执行结果如下图所示 从上图中可以看出前端项目访问另一个后端项目成功了也就说明它解决了跨域问题。
优缺点分析
此方式虽然虽然实现跨域比较简单但细心的朋友也能发现使用此方式只能实现局部跨域当一个项目中存在多个类的话使用此方式就会比较麻烦需要给所有类上都添加此注解。
1.2 通过配置文件跨域
通过设置配置文件的方式就可以实现全局跨域了它的实现步骤如下
创建一个新配置文件。添加 Configuration 注解实现 WebMvcConfigurer 接口。重写 addCorsMappings 方法设置允许跨域的代码。
具体实现代码如下
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 {Overridepublic void addCorsMappings(CorsRegistry registry) {registry.addMapping(/**) // 所有接口.allowCredentials(true) // 是否发送 Cookie.allowedOriginPatterns(*) // 支持域.allowedMethods(new String[]{GET, POST, PUT, DELETE}) // 支持方法.allowedHeaders(*).exposedHeaders(*);}
}1.3 通过 CorsFilter 跨域
此实现方式和上一种实现方式类似它也可以实现全局跨域它的具体实现代码如下
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 {Beanpublic CorsFilter corsFilter() {// 1.创建 CORS 配置对象CorsConfiguration config new CorsConfiguration();// 支持域config.addAllowedOriginPattern(*);// 是否发送 Cookieconfig.setAllowCredentials(true);// 支持请求方式config.addAllowedMethod(*);// 允许的原始请求头部信息config.addAllowedHeader(*);// 暴露的头部信息config.addExposedHeader(*);// 2.添加地址映射UrlBasedCorsConfigurationSource corsConfigurationSource new UrlBasedCorsConfigurationSource();corsConfigurationSource.registerCorsConfiguration(/**, config);// 3.返回 CorsFilter 对象return new CorsFilter(corsConfigurationSource);}
}1.4 通过 Response 跨域
此方式是解决跨域问题最原始的方式但它可以支持任意的 Spring Boot 版本早期的 Spring Boot 版本也是支持的。但此方式也是局部跨域它应用的范围最小设置的是方法级别的跨域它的具体实现代码如下
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
RestController
public class TestController {RequestMapping(/test)public HashMapString, Object test(HttpServletResponse response) {// 设置跨域response.setHeader(Access-Control-Allow-Origin, *);return new HashMapString, Object() {{put(state, 200);put(data, success);put(msg, );}};}
}1.5 通过 ResponseBodyAdvice 跨域
通过重写 ResponseBodyAdvice 接口中的 beforeBodyWrite返回之前重写方法我们可以对所有的接口进行跨域设置此方法是基于AOP切面实现的它的具体实现代码如下
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 表示重写*/Overridepublic boolean supports(MethodParameter returnType, Class converterType) {return true;}/*** 方法返回之前调用此方法*/Overridepublic Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType,Class selectedConverterType, ServerHttpRequest request,ServerHttpResponse response) {// 设置跨域response.getHeaders().set(Access-Control-Allow-Origin, *);return body;}
}此实现方式也是全局跨域它对整个项目中的所有接口有效。
2.Nginx 中解决跨域
在 Nginx 服务器的配置文件中添加以下代码
server {listen 80;server_name your_domain.com;location /api {# 允许跨域请求的域名* 表示允许所有域名访问add_header Access-Control-Allow-Origin *;# 允许跨域请求的方法add_header Access-Control-Allow-Methods GET, POST, OPTIONS;# 允许跨域请求的自定义 Headeradd_header Access-Control-Allow-Headers Origin, X-Requested-With, Content-Type, Accept;# 允许跨域请求的 Credential如果需要传递Cookie就需要开启此项add_header Access-Control-Allow-Credentials true;# 预检请求的存活时间即 Options 请求的响应缓存时间add_header Access-Control-Max-Age 3600;# 处理预检请求if ($request_method OPTIONS) {return 204;}}# 其他配置...
}上述示例中location /api 代表配置针对 /api 路径的请求进行跨域设置。可以根据具体需要修改 location 的值和其他相关参数。配置中的 add_header 指令用于设置响应头部常用的响应头部包括以下这些
Access-Control-Allow-Origin用于指定允许跨域的域名可以设置为 * 表示允许所有域名访问。Access-Control-Allow-Methods用于指定允许的跨域请求的方法例如 GET、POST、OPTIONS 等。Access-Control-Allow-Headers用于指定允许的跨域请求的自定义 Header。Access-Control-Allow-Credentials用于指定是否允许跨域请求发送和接收 Cookie。Access-Control-Max-Age用于设置预检请求OPTIONS 请求的响应缓存时间。
3.网关中解决跨域
Spring Cloud Gateway 中解决跨域问题可以通过以下两种方式实现
通过在配置文件中配置跨域实现。通过在框架中添加 CorsWebFilter 来解决跨域问题。
3.1 配置文件中设置跨域
在 application.yml 或 application.properties 中添加以下配置
spring:cloud:gateway:globalcors:corsConfigurations:[/**]: # 这里的/**表示对所有路由生效可以根据需要调整为特定路径allowedOrigins: * # 允许所有的源地址也可以指定具体的域名allowedMethods: # 允许的 HTTP 方法类型- GET- POST- PUT- DELETE- OPTIONSallowedHeaders: * # 允许所有的请求头也可以指定具体的请求头allowCredentials: true # 是否允许携带凭证cookiesmaxAge: 3600 # CORS预检请求的有效期秒其中
allowedOrigins: 设置允许访问的来源域名列表* 表示允许任何源。allowedMethods: 指定哪些HTTP方法可以被用于跨域请求。allowedHeaders: 客户端发送的请求头列表* 表示允许任何请求头。allowCredentials: 当设为 true 时允许浏览器在发起跨域请求时携带认证信息例如 cookies。maxAge: 预检请求的结果可以在客户端缓存的最大时间。
通过这样的配置Spring Cloud Gateway 网关将自动处理所有经过它的跨域请求并添加相应的响应头从而允许前端应用执行跨域请求。
3.2 添加 CorsWebFilter 来解决跨域问题
在 Spring-Framework 从 5.3 版本之前使用以下代码可以让 Spring Cloud Gateway 网关允许跨域
Configuration
public class GlobalCorsConfig {Beanpublic CorsWebFilter corsWebFilter() {CorsConfiguration config new CorsConfiguration();// 这里仅为了说明问题配置为放行所有域名生产环境请对此进行修改config.addAllowedOrigin(*);// 放行的请求头config.addAllowedHeader(*);// 放行的请求类型有 GET, POST, PUT, DELETE, OPTIONSconfig.addAllowedMethod(*); // 暴露头部信息config.addExposedHeader(*); // 是否允许发送 Cookieconfig.setAllowCredentials(true); UrlBasedCorsConfigurationSource source new UrlBasedCorsConfigurationSource();source.registerCorsConfiguration(/**, config);return new CorsWebFilter(source);}
}而 Spring-Framework 5.3 版本之后关于 CORS 跨域配置类 CorsConfiguration 中将 addAllowedOrigin 方法名修改为 addAllowedOriginPattern因此配置了变成了以下这样
Configuration
public class GlobalCorsConfig {Beanpublic CorsWebFilter corsWebFilter() {CorsConfiguration config new CorsConfiguration();// 这里仅为了说明问题配置为放行所有域名生产环境请对此进行修改config.addAllowedOriginPattern(*);// 放行的请求头config.addAllowedHeader(*);// 放行的请求类型有 GET, POST, PUT, DELETE, OPTIONSconfig.addAllowedMethod(*); // 暴露头部信息config.addExposedHeader(*); // 是否允许发送 Cookieconfig.setAllowCredentials(true); UrlBasedCorsConfigurationSource source new UrlBasedCorsConfigurationSource();source.registerCorsConfiguration(/**, config);return new CorsWebFilter(source);}
}小结
跨域问题可以在网关层、反向代理层或应用层来解决而它们的使用优先级是网关层 代理层 应用层。因为越靠前覆盖范围就越大解决跨域问题就越容易。当前具体使用哪种方案是要根据项目的实际情况来判定的。