`
bugyun
  • 浏览: 557027 次
社区版块
存档分类
最新评论

Spring MVC通过CROS协议解决跨域问题(转)

 
阅读更多

 

转:http://www.imooc.com/article/7719

 

现在接手学校网络中心的一个项目,根据团队成员的实际情况以及开发需要,老师希望做到前后端完全分离。后台使用java提供restful API 作为核心,前台无论PC或者移动端可以共用一个核心。前期解决了哦oauth2,作为授权机制等问题,本以为大业将成。(最近打算详细介绍一下机遇Spring sercurity 实现oauth2的解决方案)结果又出现了一个跨域问题,让我们踩了一个大坑,记录在此,以绝后患。

错误信息如下:

Response to preflight request doesn't pass access control check: 
No 'Access-Control-Allow-Origin' header is present on the requested resource. 
Origin 'null' is therefore not allowed access. 
The response had HTTP status code 403.

什么是跨域

简单的说即为浏览器限制访问A站点下的js代码对B站点下的url进行ajax请求。比如说,前端域名是www.abc.com,那么在当前环境中运行的js代码,出于安全考虑,访问www.xyz.com域名下的资源,是受到限制的。现代浏览器默认都会基于安全原因而阻止跨域的ajax请求,这是现代浏览器中必备的功能,但是往往给开发带来不便。特别是对我这样后台开发人员来讲,这个事情简直神奇。
但跨域的需求却一直都在,为了跨域,勤劳勇敢的程序猿们想出了许许多多的方法,例如,jsonP、代理文件等等。但这些做法增加了许多不必要的维护成本,而且应用场景也有许多限制,例如jsonP并非XHR,所以jsonP只能使用GET传递参数。更详细的资料可以看这里 Web应用跨域访问解决方案汇总

CORS协议

如今的JS大有一统天下的趋势,浏览器已经成了大多应用最好的安身之所。哪怕在移动端也有各种Hybird方案,在本地文件系统的Web页面,也有需要获取外部数据的需求,而这些需求也必然是跨域的。在寻找跨域解决方案时,发现了最优雅解决方案就是HTML5来带了的“Cross-Origin Resource Sharing”的新特性,来赋予开发者权力决定资源是否允许被跨域访问。
CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)。
它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。
为什么说它优雅呢?
整个CORS通信过程,都是浏览器自动完成,不需要用户参与。对于开发者来说,CORS通信与同源的AJAX通信没有差别,代码完全一样。浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。
因此,实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信。
解决这个问题的关键就落在了我这个负责后台的程序猿身上。
看看文档也不是什么难事嘛,就是需要在http头中设置Access-Control-Allow-Origin来决定需要允许哪些站点来访问。关于CROS协议更详细内容参考跨域资源共享 CORS 详解

CROS常见header

CORS具有以下常见的header

Access-Control-Allow-Origin: http://kbiao.me  Access-Control-Max-Age:3628800Access-Control-Allow-Methods: GETPUT, DELETE

Access-Control-Allow-Headers: content-type

"Access-Control-Allow-Origin"表明它允许" http://kbiao.me "发起跨域请求

"Access-Control-Max-Age"表明在3628800秒内,不需要再发送预检验请求,可以缓存该结果(上面的资料上我们知道CROS协议中,一个AJAX请求被分成了第一步的OPTION预检测请求和正式请求)

"Access-Control-Allow-Methods"表明它允许GET、PUT、DELETE的外域请求

"Access-Control-Allow-Headers"表明它允许跨域请求包含content-type头

当然在处理这个问题的时候前端也有不少坑,特别是Chrome浏览器不允许localhost的跨域请求,详细方案见我项目中负责前端解决方案的小伙伴。假装有链接

常规解决方案

知道了问题的原因,也知道了配套的解决办法,现在就让我们来实现解决。思路很简单,当前端要请求跨域资源时候,我们给它加上响应的响应头即可。很显然我们自己定义一个过滤器是最简单不过了。

/**
 * Created by kangb on 2016/5/10.
 */@Componentpublicclass myCORSFilter implementsFilter{@Overridepublicvoid init(FilterConfig filterConfig)throwsServletException{}@Overridepublicvoid doFilter(ServletRequest servletRequest,ServletResponse servletResponse,FilterChain filterChain)throwsIOException,ServletException{HttpServletResponse response =(HttpServletResponse) servletResponse;String origin =(String) servletRequest.getRemoteHost()+":"+servletRequest.getRemotePort();
        response.setHeader("Access-Control-Allow-Origin","*");
        response.setHeader("Access-Control-Allow-Methods","POST, GET, OPTIONS, DELETE");
        response.setHeader("Access-Control-Max-Age","3600");
        response.setHeader("Access-Control-Allow-Headers","x-requested-with,Authorization");
        response.setHeader("Access-Control-Allow-Credentials","true");
        filterChain.doFilter(servletRequest, servletResponse);}@Overridepublicvoid destroy(){}}

@Component 是Spring的注解,关键部分在doFilter中,添加了我们需要的头,option是预检测需要所以需要允许,Authorization是做了oauth2登录响应所必须的,Access-Control-Allow-Credentials表示允许cookies。都是根据自己项目的实际需要配置。
再配置Web.xml使得过滤器生效

<filter><filter-name>cors</filter-name><filter-class>·CLASS_PATH·.myeCORSFilter</filter-class></filter><filter-mapping><filter-name>cors</filter-name><url-pattern>/api/*</url-pattern></filter-mapping>

接下来前端就可以像往常一样使用AJAX请求获得资源了,完全不需要做出什么改变。

SPRING 4中更优雅的办法

SpringMVC4提供了非常方便的实现跨域的方法。在requestMapping中使用注解。
@CrossOrigin(origins = “http://kbiao.me”)
全局实现 .定义类继承WebMvcConfigurerAdapter,设置跨域相关的配置

publicclassCorsConfigurerAdapterextendsWebMvcConfigurerAdapter{@Overridepublicvoid addCorsMappings(CorsRegistry registry){

    registry.addMapping("/api/*").allowedOrigins("*");}}

将该类注入到容器中:

<beanclass="com.tmall.wireless.angel.web.config.CorsConfigurerAdapter"></bean>

更详细的内容参考Spring 官方的hello world案例Enabling Cross Origin Requests for a RESTful Web Service

http://spring.io/guides/gs/rest-service-cors/或者使用git下载示例源码

https://github.com/spring-guides/gs-rest-service-cors.git


作者: K_Biao 
链接:http://www.imooc.com/article/7719
来源:慕课网
本文原创发布于慕课网 ,转载请注明出处,谢谢合作!

分享到:
评论

相关推荐

    使用Spring CROS解决项目中的跨域问题详解

    使用Spring CROS解决项目中的跨域问题详解 在Web开发中,跨域问题是一个常见的烦恼,特别是在前后端分离的项目中。跨域问题的出现是因为浏览器的同源策略限制,导致不同域名之间无法共享资源。为了解决这个问题,...

    详解SpringMVC解决跨域的两种方案

    SpringMVC 跨域解决方案 ...本文介绍了 SpringMVC 跨域解决方案的两种方案,即通过注解的方式和通过配置文件的方式。通过这两种方案,可以解决跨站 HTTP 请求的问题,使得前后端分离的开发方式变得更加便捷和灵活。

    Spring 跨域解决方案官方 demo

    本教程将深入探讨Spring提供的CORS解决方案,通过官方示例(demo)来阐述如何实现这一功能。 首先,我们要明白什么是跨域。跨域是指一个域下的文档或脚本尝试请求另一个域下的资源,这是浏览器的一种安全策略,限制...

    layui-table-cros:layui表格跨域请求

    layui表格跨域请求是网页应用中常见的需求,尤其是在前后端分离的开发模式下。layui是一款优秀的前端组件库,它的表格组件...通过这样的实践,你将能够更好地理解和处理前后端跨域请求的问题,提升你的Web开发技能。

    前后端分离跨域问题

    springboot解决跨域有cros,配置就是那几项。 如果把服务端程序部署在nginx上,在nginx 也可以解决,服务端和nginx只用写一个即可, server { listen 3002; server_name localhost; location /ok { proxy_pass ...

    javascript-cros:跨域的一些问题和方法总结

    跨域的一些问题和方法总结 一直都说想找个大总结的文章关于跨域的处理奈何度娘上的资料太老旧,自己对于新的知识点又不是十分十分有研究。因此一直让懒癌发作下去。奈何最近做了双失青年,因此有了空余的时间去研究...

    前端跨域解决方案

    前端跨域解决方案,jsonp和cros两种解决方式。我们发现,Web页面上调用js文件时不受是否跨域的影响,凡是拥有"src"这个属性的标签都拥有跨域的能力,比如[removed]、、&lt;iframe&gt;。那就是说如果要跨域访问数据,...

    SpringCloud Gateway跨域配置代码实例

    SpringCloud Gateway 提供了强大的跨域配置功能,通过配置可以实现跨域请求的控制。 首先,让我们了解什么是跨域请求。跨域请求是指从一个域名下的页面向另一个域名下的服务器发送请求时,会出现的安全限制问题。...

    CORS 跨域配置和jar文件

    总结,CORS跨域配置是解决前后端跨域问题的关键,而在Java环境中,我们可以通过编写Filter或使用Spring MVC的注解来实现。配合jar文件,可以将这些配置部署到服务器,为Web应用提供跨域支持。理解并正确运用CORS,能...

    跨域cors扩展插件chrome

    标题中的“跨域cors扩展插件chrome”指的是用于解决Web应用程序跨域问题的Chrome浏览器扩展。在Web开发中,由于浏览器的同源策略限制,不同源的资源(比如域名、协议或端口不同)之间无法直接进行交互。CORS(Cross-...

    chrome跨域插件cros(Allow-Control-Allow-Origin).zip

    chrome跨域插件CORS离线下载,解压后有两个压缩包,直接把B压缩包拖放到chrome插件管理页面即可。或者解压A压缩包得到一个crx文件和一个zip文件,把这两个中的任一个拖放到插件管理页面即可。

    Cross Domain-CROS(跨域助手).zip

    Cross Domain will help you to deal with cross domain - CORS problem. This is tool helpful when face with cross domain issue.

    基于axios 解决跨域cookie丢失的问题

    在Web开发中,跨域问题常常困扰着开发者,特别是涉及到登录认证、状态保持等场景时,因为浏览器的同源策略会阻止跨域请求携带cookies。然而,有些情况下我们需要在跨域请求中保持登录状态,这就涉及到如何处理跨域...

    Python Tornado之跨域请求与Options请求方式

    解决跨域问题,Tornado可以通过设置响应头`Access-Control-Allow-*`字段来允许特定的跨域请求。例如,在BaseHandler类中,设置`set_default_headers`方法: ```python class BaseHandler(tornado.web....

    跨域调式chrome插件

    google chrome 安装 CORS插件可直接本地ajax调式远程服务解口,解决跨域问题。

    vue+springboot实现项目的CORS跨域请求

    跨域资源共享CORS(Cross-origin Resource Sharing),是W3C的一个标准,允许浏览器向跨源的服务器发起XMLHttpRequest请求,克服ajax请求只能同源使用的限制。关于CORS的详细解读,可参考阮一峰大神的博客:跨域资源...

    SpringBoot整合websocket实现数据实时推送

    通过呆着读者手写速成版本的websocket入门案例,以项目案例的方式带你...4.前后端分离项目的Cros跨域问题解决 阅读建议: 此资源以案例代入知识点的方式,让你快速上手websocket的相关学习,可针对项目本身向外扩展。

    谷歌跨域插件allow-cors-access-control.zip

    标题中的“谷歌跨域插件allow-cors-access-control.zip”指的是一个用于解决浏览器跨域问题的Chrome插件。跨域资源共享(CORS)是一种机制,它允许Web应用程序从不同的源请求资源,比如JavaScript通过Ajax从非同源的...

Global site tag (gtag.js) - Google Analytics