SpringBoot 项目处理跨域的四种技巧

开发 前端
CORS 是一个 W3C 标准,全称是"跨域资源共享"(Cross-origin  resource  sharing), 它需要浏览器和服务器同时支持他,允许浏览器向跨源服务器发送XMLHttpRequest请求,从而克服 AJAX 只能同源使用的限制。

上周帮一家公司优化代码时,顺手把跨域的问题解决了, 这篇文章,我们聊聊 SpringBoot 项目处理跨域的四种技巧 。

图片图片

一、什么是跨域

我们先看下一个典型的网站的地址:

图片图片

同源是指:协议、域名、端口号完全相同。

下表给出了与 URL http://www.training.com/dir/page.html 的源进行对比的示例 :

图片图片

当用户通过浏览器访问应用(http://admin.training.com)时,调用接口的域名非同源域名(http://api.training.com),这是显而易见的跨域场景。

二、理解 CORS

CORS 是一个 W3C 标准,全称是"跨域资源共享"(Cross-origin  resource  sharing), 它需要浏览器和服务器同时支持他,允许浏览器向跨源服务器发送XMLHttpRequest请求,从而克服 AJAX 只能同源使用的限制。

跨域资源共享标准新增了一组 HTTP 首部字段,允许服务器声明哪些源站通过浏览器有权限访问哪些资源。

规范要求,对那些可能对服务器数据产生副作用的 HTTP 请求方法(特别是 GET 以外的 HTTP 请求,或者搭配某些 MIME 类型的 POST 请求),浏览器必须首先使用 OPTIONS 方法发起一个预检请求(preflight request),从而获知服务端是否允许该跨域请求。

服务器确认允许之后,才发起实际的 HTTP 请求。在预检请求的返回中,服务器端也可以通知客户端,是否需要携带身份凭证(包括 Cookies 和 HTTP 认证相关数据)。

图片图片

1.简单请求

简单请求模式,浏览器直接发送跨域请求,并在请求头中携带 Origin 的头,表明这是一个跨域的请求。 服务器端接到请求后,会根据自己的跨域规则,通过 Access-Control-Allow-Origin 和 Access-Control-Allow-Methods 响应头,来返回验证结果。

图片图片

2.预检请求

浏览器在发现页面发出的请求非简单请求,并不会立即执行对应的请求代码,而是会触发预先请求模式。预先请求模式会先发送preflight request(预先验证请求),preflight request是一个 OPTION 请求,用于询问要被跨域访问的服务器,是否允许当前域名下的页面发送跨域的请求。在得到服务器的跨域授权后才能发送真正的 HTTP 请求。

图片图片

三、Nginx 配置

图片图片

我们不用配置 SpringBoot 项目,在反向代理层 Nginx 直接配置 CORS ,典型配置如下图:

图片图片

四、配置类实现 addCorsMapping 接口

SpringBoot 中新增一个配置类 CorsConfig.java,继承 WebMvcConfigurerAdapter 或者实现WebMvcConfigurer 接口,项目启动后,会自动读取配置。

图片图片

五、CorsFilter 过滤器模式

下图是 SpringMvc 模式里,过滤器,拦截器,控制器的执行顺序。

图片图片

CorsFilter 过滤器模式的优点是:优先级高,可以规避代码中业务拦截器异常导致 adCorsMappings 方法失效的问题。

我们需要定义一个 corsFilter 方法,@Bean 注解表示此方法返回一个Spring Bean,该 Bean 将由Spring 容器管理。

corsFilter() 方法定义了一个 FilterRegistrationBean,这个 bean 是用来注册 CorsFilter 的,后者用于处理 CORS 请求。

图片图片

六、网关模式

在微服务架构体系中,网关是非常核心的组件。 API 网关可以做鉴权,限流,灰度等,同时可以配置 CORS 。内部服务端不用特别关注跨域这个问题。

图片图片

因此假如是 SpringCloud 体系,我们只需要配置 SpringCloud gateway 的跨域即可。

责任编辑:武晓燕 来源: 勇哥Java实战
相关推荐

2024-05-22 19:10:18

跨域Web开发

2017-02-28 14:28:37

数据跨库分页架构

2010-07-28 22:35:25

ADSL掉线

2020-08-10 00:30:55

备份密码iPhone移动安全

2022-10-09 18:16:01

Flowable设置ReceiveTas

2024-12-02 14:30:20

2021-02-21 21:20:24

SpringBoot异步网络

2017-09-01 11:59:59

Android

2011-11-24 16:34:39

Java

2017-07-06 15:40:19

DevOps核心能力

2019-10-24 07:42:28

Java引用GC

2012-09-11 09:55:26

编程HTML5编程能力

2011-03-16 09:05:53

NATiptables

2023-08-10 11:39:54

RabbitMQSpring交换机

2021-10-24 08:37:18

网络监控网络架构网络

2021-12-01 23:05:27

物联网计算数据

2020-06-12 08:28:29

JavaScript开发技术

2013-06-14 15:24:57

Android开发移动开发数据存储方式

2018-12-05 16:25:14

2023-02-10 11:13:42

网络功耗无线网络设备
点赞
收藏

51CTO技术栈公众号