原文链接:https://blog.csdn.net/xcbeyond/article/details/84453832

1、前言

最近在项目中,调用Eureka REST接口时,出现了CORS跨越问题(Cross-origin resource sharing),在此与大家进行分享,避免多走些弯路。

项目前端(http://localhost:9000)通过Ajax方式调用Eureka REST 接口(http://localhost:8761/eureka/apps)时,却没有任何反应,则通过F12查看日志发现出现“Access-Control-Allow-Origin“类 异常,详细如下:

…… http://localhost:8761/eureka/apps. Origin http://localhost:9000 is not allowed by Access-Control-Allow-Origin……

通过google,发现是由于CORS跨越问题造成的,解决办法无非有两种方式:响应头添加参数和添加过滤器,下面就详细说说CORS跨越问题的起因与详细解决办法。
2、CORS

CORS,常被大家称之为跨越问题,准确的叫法是跨域资源共享(CORS,Cross-origin resource sharing),是W3C标准,是一种机制,它使用额外的HTTP头来告诉浏览器 让运行在一个 origin (domain) 上的Web应用被准许访问来自不同源服务器上的指定的资源。当一个资源从与该资源本身所在的服务器不同的域或端口请求一个资源时,资源会发起一个跨域 HTTP 请求。

http://localhost:9000请求http://localhost:8761/eureka/apps就是违背了上述原则,即:请求服务器不同端口的另一个资源,出于安全原因,浏览器限制发起的跨源HTTP请求,则会出现本文开头提到的现象及异常。

例如,XMLHttpRequest和Fetch API遵循同源策略, 这意味着使用这些API的Web应用程序只能从加载应用程序的同一个域请求HTTP资源,除非使用CORS头。

跨域资源共享( CORS )机制允许 Web 应用服务器进行跨域访问控制,从而使跨域数据传输得以安全进行。浏览器支持在 API 容器中(例如 XMLHttpRequest 或 Fetch )使用 CORS,以降低跨域 HTTP 请求所带来的风险。
什么情况下存在跨域问题

本文提到的由 XMLHttpRequest 或 Fetch 发起的跨域 HTTP 请求。
    Web 字体 (CSS 中通过 @font-face 使用跨域字体资源),,因此,网站就可以发布 TrueType 字体资源,并只允许已授权网站进行跨站调用。
    WebGL 贴图。
    使用 drawImage 将 Images/video 画面绘制到 canvas
    样式表(使用 CSSOM)。

面对CORS的限制,将如何解决呢

世间万物完事,有因必有果,有果必有因。当然CORS的限制,官方也是给出了解决办法的。

CORS标准新增了一组 HTTP 头字段(Access-Control-Allow-Origin),允许服务器声明哪些源通过浏览器有权限访问哪些资源。另外,规范要求,对那些可能对服务器数据产生副作用的 HTTP 请求方法(特别是 GET以外的 HTTP 请求,或者搭配某些 MIME 类型的 POST请求),浏览器必须首先使用 OPTIONS 方法发起一个预检请求(preflight request),从而获知服务端是否允许该跨域请求。服务器确认允许之后,才发起实际的 HTTP 请求。在预检请求的返回中,服务器端也可以通知客户端,是否需要携带身份凭证(包括Cookies 和 HTTP 认证相关数据)。

CORS请求失败会产生错误,但是为了安全,在JavaScript代码层面是无法获知到底具体是哪里出了问题。你只能查看浏览器的控制台以得知具体是哪里出现了错误。

如果有兴趣了解该机制剖析的可以参考https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
3、解决办法

在查阅大量资源,并了解过CORS机制后,解决办法实质必定会围绕Access-Control-Allow-Origin头。

解决办法如下:
添加响应头

在被请求资源中添加响应头信息"Access-Control-Allow-Origin:*
过滤器

在本项目中添加如下过滤器:

/**
     * 解决跨域问题
     */
    public class AccessControlAllowOriginFilter implements Filter {
     
        public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
            HttpServletResponse response = (HttpServletResponse) res;
            response.setHeader("Access-Control-Allow-Origin", "*");
            response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
            response.setHeader("Access-Control-Allow-Credentials", "true");
     
         chain.doFilter(req, response);
       }
     
       public void init(FilterConfig filterConfig) {
     
       }
     
       public void destroy() {
     
       }
     
    }

注解方式

在Spring Boot中拥有大量的注解,针对跨域问题,也提供了对应的注解@CrossOrigin,使用方法如下:

import java.util.HashMap;
     
    import org.springframework.web.bind.annotation.CrossOrigin;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.RestController;
     
    /**
     * @author xcbeyond
     */
    @RestController
    @RequestMapping(value = "/api", method = RequestMethod.POST)
    public class DemoController {
            
        @CrossOrigin(origins = "*")
        @RequestMapping(value = "/get")
        public String get() {
            ……
        }
    }

个人比较推荐使用上述的三种方式之一,其他方式请自己百度、谷歌吧

[转]跨域问题(CORS / Access-Control-Allow-Origin)的更多相关文章

  1. 跨域资源共享(CORS)问题解决方案

    CORS:Cross-Origin Resource Sharing(跨域资源共享) CORS被浏览器支持的版本情况如下:Chrome 3+.IE 8+.Firefox 3.5+.Opera 12+. ...

  2. rest_framework 跨域和CORS

      跨域和CORS   本节目录 一 跨域 二 CORS 三 xxx 四 xxx 五 xxx 六 xxx 七 xxx 八 xxx 一 跨域 同源策略(Same origin policy)是一种约定, ...

  3. day 92 跨域和CORS

      跨域和CORS   本节目录 一 跨域 二 CORS 三 xxx 四 xxx 五 xxx 六 xxx 七 xxx 八 xxx 一 跨域 同源策略(Same origin policy)是一种约定, ...

  4. 百万年薪python之路 -- 请求跨域和CORS协议详解

    楔子 什么是同源策略 同源策略,它是由Netscape提出的一个著名的安全策略.现在所有支持JavaScript 的浏览器都会使用这个策略.所谓同源是指,域名,协议,端口相同.当一个浏览器的两个tab ...

  5. day 90 跨域和CORS

    跨域和CORS   本节目录 一 跨域 二 CORS 三 xxx 四 xxx 五 xxx 六 xxx 七 xxx 八 xxx 一 跨域 同源策略(Same origin policy)是一种约定,它是 ...

  6. asp.net core webapi之跨域(Cors)访问

    这里说的跨域是指通过js在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据,或者通过js获取页面中不同域的框架中(iframe)的数据.只要协议.域名.端口有任何一个不同,都被当作 ...

  7. 跨域资源共享CORS与JSONP

    同源策略限制: 同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果没有同源策略,攻击者可以通过JavaScript获取你的邮件以及其他敏感信息,比如说 ...

  8. Nginx配置跨域请求 CORS

    当出现403跨域错误的时候 No 'Access-Control-Allow-Origin' header is present on the requested resource,需要给Nginx服 ...

  9. 跨域问题-cors

    什么是跨域如大家所知,出于安全考虑,浏览器会限制脚本中发起的跨站请求.比如,使用 XMLHttpRequest 对象发起 HTTP 请求就必须遵守同源策略(same-origin policy). 具 ...

  10. springmvc springboot 跨域问题(CORS)

    官方文档:http://docs.spring.io/spring/docs/current/spring-framework-reference/html/cors.html springmvc s ...

随机推荐

  1. Django之DRF源码分析(四)---频率认证组件

    核心源码 def check_throttles(self, request): """ Check if request should be throttled. Ra ...

  2. 《linux就该这么学》课堂笔记09 存储结构、磁盘划分

    Linux一切都是文件 "/"为根目录(万物起始)  **挂载后要想永久生效,需要修改开机启动项 vim /etc/fstab  

  3. sourceinsight sublimetext主题色配置

    1.sourceinsight发布了4.0版本,全面支持了utf-8编码,这里sourinsight 颜色基本完全按照sublime默认的monokia主题来进行调色,效果如下图所示. 2.配色文件和 ...

  4. 后台返回的base64的图片格式,前端如何转为普通的图片格式

    在上一篇的博客当中,写了前端如何将普通的图片格式转为base64的图片,今天开发的时候遇到了后台返回的图片格式是base64的,我这边需要把base64的图片格式转为普通的,搜了一下js的方法,感觉很 ...

  5. 2019年杭电多校第三场 1011题Squrirrel(HDU6613+树DP)

    题目链接 传送门 题意 给你一棵无根树,要你寻找一个根节点使得在将一条边权变为\(0\)后,离树根最远的点到根节点的距离最小. 思路 本题和求树的直径很像,不过要记得的东西有点多,且状态也很多. \( ...

  6. git分布式版本控制系统的概述和安装

    Git历史 同生活中的许多伟大赛事一样,Git诞生于一个极富纷争大举创新的年代.Linux内核开源项目有着为数众广的参与者.绝大多数的Linux内核维护工作都花在了提交补丁和保存归档的繁琐事务上(19 ...

  7. eclipse解决中文字体太小问题(转载)

    最近新装了Win7,打开eclipse3.7中文字体很小,简直难以辨认.在网上搜索发现这是由于Eclipse 3.7 用的字体是 Consolas,显示中文的时候默认太小了.   解决方式有两种:一. ...

  8. spring mvc @RequestMapping method 不写的话,默认GET、POST都支持,根据前端方式自动适应

    @RequestMapping(value="/") method 不写的话,默认GET.POST都支持,根据前端方式自动适应.

  9. cmds在线重定义增加列

    --输出信息采用缩排或换行格式化 EXEC DBMS_METADATA.set_transform_param(DBMS_METADATA.session_transform, 'PRETTY', T ...

  10. Spring AOP(面向切面编程)

    AOP能够将那些与业务无关,却为业务模块所共同调用的逻辑或责任(例如事务处理.日志管理.权限控制等)封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可拓展性和可维护性. 简单例子: ...