• Cross-Origin跨域问题


    为什么会跨域,要先了解浏览器的同源策略SOP(Same Orign Policy)  https://segmentfault.com/a/1190000015597029

    同源:

      如果两个页面的协议,端口(如果有指定)和主机都相同,则两个页面具有相同的源。

      协议/主机/端口

    跨源网络访问

      同源策略控制了不同源之间的交互,例如在使用XMLHttpRequest时会受到同源策略的约束。即同源策略限制了从一个源加载的文档或者脚本如何与另一个源的资源进行交互。这是一个用于隔离潜在恶意文件的重要安全机制。

      如果没有同源策略限制的接口请求则容易被CSRF攻击,下面是CSRF攻击的原理:

      

    解决方案:

    CORS

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

    CORS需要浏览器和服务器同时支持。

    1. 所有浏览器都支持该功能,IE浏览器不能低于IE10。
      整个CORS通信过程,都是浏览器自动完成,不需要用户参与。 对于开发者来说,CORS通信与同源的AJAX通信没有差别,代码完全一样。浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。
    2. 实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信。

    即CORS与普通请求代码一样。

    CORS与JSONP相比

    1. JSONP只能实现GET请求,而CORS支持所有类型的HTTP请求。
    2. 使用CORS,开发者可以使用普通的XMLHttpRequest发起请求和获得数据,比起JSONP有更好的错误处理。
    3. JSONP主要被老的浏览器支持,它们往往不支持CORS,而绝大多数现代浏览器都已经支持了CORS。

      

      CORS全称为Cross Origin Resource Sharing(跨域资源共享), 每一个页面需要返回一个名为Access-Control-Allow-Origin的http头来允许外域的站点访问,你可以仅仅暴露有限的资源和有限的外域站点访问。

      我们可以理解为:如果一个请求需要允许跨域访问,则需要在http头中设置Access-Control-Allow-Origin来决定需要允许哪些站点来访问,如要允许www.baidu.com这个站点的请求跨域,则可以设置:

    Access-Control-Allow-Origin:http://www.baidu.com

      

      CROS跨域常用header
      Access-Control-Allow-Origin: 允许哪些ip或域名可以跨域访问
      Access-Control-Max-Age: 表示在多少秒之内不需要重复校验该请求的跨域访问权限
      Access-Control-Allow-Methods: 表示允许跨域请求的HTTP方法,如:GET、POST、PUT、DELETE
      Access-Control-Allow-Headers: 表示访问请求中允许携带哪些Header信息,如:Accept、Accept-Language、Content-  Language、Content-Type

    spring中解决跨域问题的方案:

    1、@CrossOrigin注解

    此注解既可用于方法也可用于类

    示例如下:

    @CrossOrigin(origins = "http://www.zhihu.com")
    @RequestMapping(value = "/allProductions", method = RequestMethod.GET)
    public Result getAllOldProductions() {
    
    }

    @CrossOrigin 注解既可注解在方法上,也可注解在类上。

    2、XML全局配置

    所有跨域请求都可以访问

    <mvc:cors>
        <mvc:mapping path="/**" />
    </mvc:cors>

    更加细粒度的配置:

    <mvc:cors>
    
        <mvc:mapping path="/api/**"
            allowed-origins="https://domain1.com, https://domain2.com"
            allowed-methods="GET, PUT"
            allowed-headers="header1, header2, header3"
            exposed-headers="header1, header2" allow-credentials="true"
            max-age="123" />
    
        <mvc:mapping path="/resources/**"
            allowed-origins="https://domain1.com" />
    
    </mvc:cors>

    Springboot解决跨域问题配置 

    1、使用@CrossOrigin注解,同上

    2、使用CorsFilter进行全局跨域配置

    @Configuration
    public class GlobalCorsConfig {
    
        @Bean
        public CorsFilter corsFilter() {
            CorsConfiguration corsConfig = new CorsConfiguration();
            // 开放哪些ip、端口、域名的访问权限,星号表示开放所有域
            corsConfig.addAllowedOrigin("*");
            // 允许发送cookie信息
            corsConfig.setAllowCredentials(true);
            // 允许get,post方法
            corsConfig.addAllowedMethod(HttpMethod.POST);
            corsConfig.addAllowedMethod(HttpMethod.GET);
            // 允许HTTP请求头中携带哪些header信息
            corsConfig.addAllowedHeader("*");
            // 暴漏哪些头部信息(因为跨域访问默认不能获取全部头部信息)
            corsConfig.addExposedHeader("Content-Type");
    
            // 添加映射路径,“/**”表示对所有的路径实行全局跨域访问权限的设置
            UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
            source.registerCorsConfiguration("/**", corsConfig);
    
            return new CorsFilter(source);
        }
    }

    3、重写WebMvcConfigurer的addCorsMappings方法(全局跨域配置)

    @Bean
        public WebMvcConfigurer crosConfigurer() {
            return new WebMvcConfigurer() {
                @Override
                public void addCorsMappings(CorsRegistry registry) {
                    registry.addMapping("/**") //对哪些映射路径应用跨域配置
                            .allowedOrigins("*") // 允许哪些域名访问
                            .allowCredentials(true)
                            .allowedMethods("GET", "POST")
                            .allowedHeaders("*")
                            .exposedHeaders("Content-Type");
                }
            };
        }

    或者:

    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 GlobalCorsConfig implements WebMvcConfigurer{
    
        @Override
       public void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/**")
                    .allowedOrigins("*")
                    .allowedMethods("HEAD", "GET", "POST", "PUT", "DELETE", "OPTIONS")
                    .allowCredentials(true)
                    .maxAge(3600)
                    .allowedHeaders("*");
        }
    }

    4、过滤器实现

    @Component
    public class CorsFilter implements Filter {
        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
            HttpServletResponse res = (HttpServletResponse) response;
            res.addHeader("Access-Control-Allow-Credentials", "true");
            res.addHeader("Access-Control-Allow-Origin", "*");
            res.addHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT");
            res.addHeader("Access-Control-Allow-Headers", "Content-Type,X-CAF-Authorization-Token,sessionToken,X-TOKEN");
            if (((HttpServletRequest) request).getMethod().equals("OPTIONS")) {
                response.getWriter().println("ok");
                return;
            }
            chain.doFilter(request, response);
        }
    
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
    
        }
    
        @Override
        public void destroy() {
    
        }
    }
  • 相关阅读:
    Eclipse/MyEclip中使用复制粘贴功能很卡
    ActiveMQ使用教程
    ActiveMQ常见消息类型
    推荐12个最好的 JavaScript 图形绘制库
    eclipse 打包springboot成jar
    CentOS 7下ELK(6.2.4)++LogStash+Filebeat+Log4j日志集成环境搭建
    elasticsearch启动常见错误
    使用haproxy实现负载均衡集群
    linux配置mysql5.6 主主复制同步
    力扣No.102 二叉树的层次遍历
  • 原文地址:https://www.cnblogs.com/yangyongjie/p/10768614.html
Copyright © 2020-2023  润新知