首页>>后端>>java->springcors解决跨域(spring跨域问题cors)

springcors解决跨域(spring跨域问题cors)

时间:2023-11-29 本站 点击:0

SpringBoot进阶之处理跨域问题(CORS)

大家好,一直以来我都本着 用最通俗的话理解核心的知识点, 我认为所有的难点都离不开 「基础知识」 的铺垫

「大佬可以绕过 ~」

如果你是一路看过来的,很高兴你能够耐心看完。之前带大家学了 Springboot 基础部分,对基本的使用有了初步的认识, 接下来的几期内容将会带大家进阶使用,会先讲解基础 中间件 的使用和一些场景的应用,或许这些技术你听说过,没看过也没关系,我会带大家一步一步的入门,耐心看完你一定会有 收获 ~

上期带大家学习了 Springboot 中如何集成 MyBatis分页插件PageHelper 以及它的一个基本使用, 本期将带大家学习 SpringBoot 中如何处理跨域问题的,同样的,我们集成到 Springboot 中。最近github可能会被墙,所以我把源码放到了国内gitee上,本节我们依然使用上期的代码

同样的,为了照顾小白同学,依然先说一下啥是跨域。说到跨域问题,如果你是 前端 同学,肯定不会陌生, 你有可能调接口调着调着,发现请求发布出去,控制台会报 CORS 错误, 这时候你会找后台老大哥给你处理一下。然而现在前端工程中,一般都会有 proxy代理 ,这样也能解决问题,这只是本地调试,但上线还会有问题, 除非你发布的时候你们是同一个 域 下。

好,说了这么多,大概明白跨域是如何产生了,就是说前端调用的后端接口不属于同一个 域(域名或端口不同) ,就会产生跨域问题,也就是说你的应用访问了该应用域名或端口之外的域名或端口,这里给大家总结一下,产生跨域的三个条件:

解决思路大致可以分为以下几方面:

从源头浏览器解决,解除跨域机制,用户自己设置浏览器,这不大现实,好, pass

发送 JSONP 请求替代XHR请求,并不能适用所有的请求方式, 不推荐

之前我们提到前端本地工程开启 Proxy ,那么服务端可不可进行代理呢?答案是可以的,怎么做?可以通过 nginx 进行代理,给大家简单演示一下:

nginx 是当今比较火的 web 服务器,常用于服务代理, 等教大家部署的时候会讲一下

这也是本节要讲的内容,我们先不直接的给大家展示代码,先说一下它的原理。

一般我们下载的浏览器比如 Chrome ,它都是自行默认开启 跨域限制 的,那我们如何判断我们发出去的请求是一个 跨域请求 呢,打开浏览器开发者工具,在请求的请求头中就可以发现,如果不是一个跨域请求,它只有 Host ,如果是一个 跨域请求 它会多一个 Origin ,告诉浏览器我俩请求的地方不一样

跨源资源共享(CORS) 是一种基于 HTTP头 的机制,该机制通过允许服务器标示除了它自己以外的其它 origin(域,协议和端口 ),这样浏览器就可以访问加载这些资源。跨源资源共享还通过一种机制来检查服务器是否会允许要发送的真实请求,该机制通过浏览器发起一个到服务器托管的跨源资源的 预检(OPTION) 请求。在预检中,浏览器发送的头中标示有HTTP方法和真实请求中会用到的头,那么具体是怎么设置 头 的呢?

服务端通过设置如上,就可以进行跨域访问了。好,有了基本的理论之后,我们一起看一下在 Springboot 中如何解决的:

是不是很简单~ 它的实现机制主要是通过请求 拦截器 实现的,你慢慢会发现,随着学习的深入,你会遇到各种 拦截器 技术

本期到这里就结束了,总结一下,本节主要带大家认识了什么是 跨域 ,以及解决思路,最后教大家 Sprinboot 中是如何配置跨域访问的,源码已更新,大家可以自行试一下

SpringMvc CORS跨域设置

基于安全的考虑, W3C 规范规定浏览器禁止访问不同域(origin)的资源,目前绝大部分浏览器遵循这一规范,从而衍生出了跨域资源共享 ( CORS )问题,相比于 IFRAME 或 JSONP , CORS 更全面并且更安全, Spring Mvc 为我们提供了一套多粒度的CORS解决方案。

关于 CORS 的介绍,主要参考文章 《Cross-Origin Resource Sharing (CORS)》

CORS 的工作原理是添加新的 HTTP headers 来让服务器描述哪些源的请求可以访问该资源,对于可能对服务器造成不好影响的请求,规范规定浏览器需要先发送“预检”请求(也就是 OPTION 请求),在预检请求通过后再发送实际的请求,服务器还可以通知客户端是否应该随请求发送“凭据”(例如 Cookie 和 HTTP 身份验证),更详细的介绍可以参考上面的文章,本文主要讨论 Spring Mvc 对 CORS 的支持。

需要注意的是:

不需要发送”预检“请求

可以看见 @CrossOrigin 注解可以标注在类或者方法上,其中几个常量如 DEFAULT_ORIGINS 已经在Spring 5.0弃用,取而代之的是 CorsConfiguration#applyPermitDefaultValues 方法。

标注在类上,该类的所有方法均会生效

同时也可以类和方法结合使用

@CrossOrigin 注解比较适用于较细粒度的跨域控制,对于全局的跨域控制, Spring Mvc 提供了 Global Configuration 配置。

Spring Mvc 对于全局的 CORS 比较简单,分为两个方案

创建 WebConfig 类实现 WebMvcConfigurer 接口,通过 CorsRegistry 设置跨域信息

通过 CorsConfiguration 设置跨域信息,并将 CorsConfiguration 通过 CorsFilter 构造函数传递进去

Spring Mvc 对于 CORS 可以说是非常方便,本文主要是想让各位开发者对跨域有个整体的了解,各个参数代表的含义,而不是在所有项目中都一概而论的设置为“*”,要在自身项目的实际需求以及安全性上多做思考,防止生产事故。

SpringBoot CORS 跨域 @CrossOrigin

跨源资源共享(Cross-origin resource sharing, CORS)是由大多数浏览器实现的W3C规范,它允许您以灵活的方式指定哪种跨域请求被授权,而不是使用一些不太安全、功能不太强大的方法,比如IFRAME或JSONP。

从4.2开始,Spring MVC已支持CORS。

在Spring Boot中使用带有@CrossOrigin注释的controller方法CORS配置,不需要任何特定的配置。

@CrossOrigin注解可以在类上使用,也可以在方法上使用,如:

常用的属性有2个,分别是origins和maxAge,下面分别解释下:

如果只在方法上或者类上使用@CrossOrigin注解,则默认该映射接受所有的网站发送过来的请求、接受所有类型的http请求和接受所有的不同内容的头部信息(Header),如:

@CrossOrigin可以同时在类上、方法上同时使用,来控制不同网站访问不同的映射,如:

remove方法可以被所有网站的访问,retrieve方法只接受 网站发送的请求。

全局CORS配置可以通过注册一个WebMvcConfigurer bean并使用自定义的addcorsmapping (CorsRegistry)方法来定义,如:

Spring MVC 的跨域解决方案

一句话:同一个ip、同一个网络协议、同一个端口,三者都满足就是同一个域,否则就是跨域。

基于两个方面:

a. web应用本身是部署在不同的服务器上

b.基于开发的角度 --- 前后端分离

web应用本身是部署在不同的服务器上,对应的域名也就有所不同

比如百度。

主域名:

二级域名:, ,

需要在不同的域之间,通过ajax方式互相请求,是非常常见的需求。

Spring 4中增加了对jsonp的原生支持,只需要ControllerAdvice就可以开启,方法如下:

首先新建一个Advice类,我们叫做“JsonpAdvice”,然后在里面定义接收jsonp请求的参数key:

@ControllerAdvice("cn.isy.web.sso.web")指定作用的包名

supper("callback")指定的是url中callback:

注意:

我们还可以重写AbstractJsonpResponseBodyAdvice中的feforeBodyWriteInternal方法:

做到实现url携带callback就返回jsonp格式,没有就返回正常格式

img

controller中

controller中的代码正常编写就OK,不用修改任何东西。

只要保证在cn.isy.web.sso.web包下即可!

jquery ajax

注意:必须使用jsonp的方式提交请求!

有关cors的介绍可以去详细看一下,这里就不作重复了:

CORS详解

跨资源共享CORS详解

主要配置

使用注解CrossOrigin

在controller类上添加CrossOrigin注解表示当前类中的所有入口函数都

可以实现跨域。也可以指定某个conroller中具体的方法。

img

了解一下这个注解的内容:

img

jquery ajax的写法

注意:这里不用使用jsonp的方式请求普通的ajax即可!,因为浏览器自己可以去做!

CORS全局配置

自己试了试没有成功!

资料

解释cors的原理不错

让自己变得更优秀才可以有更多资源

搜索微信号(ID:芋道源码),可以获得各种 Java 源码解析。

并且,回复【书籍】后,可以领取笔者推荐的各种 Java 从入门到架构的书籍。

使用CORS解决跨域问题

跨域是指跨域名的访问,以下情况都属于跨域:

如果 域名和端口都相同,但是请求路径不同 ,不属于跨域,如:

跨域不一定会有跨域问题。

因为跨域问题是浏览器对于ajax请求的一种安全限制: 一个页面发起的ajax请求,只能是于当前页同域名的路径 ,这能有效的阻止跨站攻击。

因此: 跨域问题 是针对ajax的一种限制 。

但是这却给我们的开发带来了不变,而且在实际生成环境中,肯定会有很多台服务器之间交互,地址和端口都可能不同,怎么办?

目前比较常用的跨域解决方案有3种:

我们这里会采用cors的跨域方案。

CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)。

它允许浏览器向跨源服务器,发出 XMLHttpRequest 请求,从而克服了AJAX只能 同源 使用的限制。

CORS需要浏览器和服务器同时支持。目前,所有浏览器都支持该功能,IE浏览器不能低于IE10。

浏览器会将ajax请求分为两类,其处理方案略有差异:简单请求、特殊请求。

只要同时满足以下两大条件,就属于简单请求。:

(1) 请求方法是以下三种方法之一:

(2)HTTP的头信息不超出以下几种字段:

当浏览器发现发现的ajax请求是简单请求时,会在请求头中携带一个字段: Origin .

Origin中会指出当前请求属于哪个域(协议+域名+端口)。服务会根据这个值决定是否允许其跨域。

如果服务器允许跨域,需要在返回的响应头中携带下面信息:

注意:

如果跨域请求要想操作cookie,需要满足3个条件:

不符合简单请求的条件,会被浏览器判定为特殊请求,,例如请求方式为PUT。

特殊请求会在正式通信之前,增加一次HTTP查询请求,称为"预检"请求(preflight)。

浏览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些HTTP动词和头信息字段。只有得到肯定答复,浏览器才会发出正式的 XMLHttpRequest 请求,否则就报错。

一个“预检”请求的样板:

与简单请求相比,除了Origin以外,多了两个头:

服务的收到预检请求,如果许可跨域,会发出响应:

除了 Access-Control-Allow-Origin 和 Access-Control-Allow-Credentials 以外,这里又额外多出3个头:

如果浏览器得到上述响应,则认定为可以跨域,后续就跟简单请求的处理是一样的了。

虽然原理比较复杂,但是前面说过:

事实上,SpringMVC已经帮我们写好了CORS的跨域过滤器:CorsFilter ,内部已经实现了刚才所讲的判定逻辑,我们直接用就好了。

在 Application 下编写一个配置类,并且注册CorsFilter:

结构:

放到Application下即可。

4.5.4.重启测试:

访问正常:

Springboot实现跨域请求

        为了保证浏览器的安全,不同源的客户端脚本在没有明确授权的情况下, 不能读写对方资源.这叫做同源, 同源策略是浏览器的安全基石.

        如果一个请求地址里面协议, 域名和端口号都相同,就属于同源.

        在同源策略下,非同源的网站之间发送AJAX请求,如有需要,可通过降域或其他技术实现.

     cors(Crosss-OriginResource Sharing) ,CORS可以在不破坏既有规则的情况下,通过后端服务器实现

CORS接口, 从而实现跨域通行,CORS将请求分为两类:简单请求和非简单请求,分别对跨域通信提供了支持.

       2.1: 简单请求

           在CROS之前, 发送HTTP请求时在头信息中不能包含任何自定义的字段,且HTTP信息不能超过以下几个字段:

            Accept

            Accept-Language

            Content-Language

            Last-Even-ID

            Content-Type(仅限于[application/x-www-form-urlencoded /multipart/form-data/text/plain]类型)

            对于简单的请求,CORS的策略是在请求头中增加一个Origin字段服务器收到请求后,根据该字段

判断是否允许该请求访问.

            如果允许就在Http头信息中添加Access-Control-Allow-Origin字段,并返回正确的结果.

            如果不允许, 就不在Http头信息中添加Access-Controll-Allow-Origin字段

             另外: 可选,还有Access-Control-Allow-Credentials: 可选,用户是否发送,处理cookie

                      可选 ,Access-Control-Expose-Headers :可以让用户拿到的字段,有几个字段,有几个字段无论设置与否都可以拿到的,包括Cache-Control  Content-Lanaguage  Content-Type  . Expires. Last-Modiified . Pragma 

        2.2非简单请求

        浏览器会在真实请求发出前增加一次OPTION请求,称为预检请求.预检请求将真实请求信息,包括请求方法,自定义头字段 , 源信息添加到HTTP头信息字段中,询问服务器是否允许这样的操作.

        例如:一个GET请求:

        OPTIONS: /test HTTP/1.1

        Origin:

        Access-Control-Request-Method:Get

        Access-Control-Request-Headers:X-Custom-Header

        Host:

        与CORS相关的字段有:

        请求使用的HTTP方法Access-Control-Request-Method

        请求中包含的自定义头字段Access-Control-Request-Headers.

         服务器收到请求时,需要分别对Origin   Access-Control-Request-Method , 

Access-Control-Request-Headers 进行验证,验证通过后, 会在返回HTTP 头信息中添加;

Access-Control-Allow-Origin:

#真实请求允许的方法

Access-Control-Allow-Method:GET , POST , PUT , DELETE

#服务器允许使用的字段

Access-Control-Allow-Headers: X-Custom-Header

#是否允许用户发送,处理cookie

Access-Control-Allow-Credentials:true

#预检请求的有效期,单位为秒.有效期内,不会重复发送预检请求.

Access-Control-Max-Age:1728000

当预检请求通过后, 浏览器才会发送真实请求到服务器.这样就实现了跨域资源的的请求访问.


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:/java/763.html