• SpringBoot跨域小结


    前言:公司的SpringBoot项目出于某种原因,经常样处理一些跨域请求。

    一。以前通过查阅相关资料自己写的一个处理跨域的类,如下。

    1.1首先定义一个filter(拦截所有请求,包括跨域请求)

    public class CrossDomainFilter implements Filter {
        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
                throws IOException, ServletException {     
            HttpServletRequest hreq = (HttpServletRequest) request;  //
            HttpServletResponse hresp = (HttpServletResponse) response; 
            //跨域
            hresp.setHeader("Access-Control-Allow-Origin", "*");  //设置相应头
            //跨域 Header
            hresp.setHeader("Access-Control-Allow-Methods", "*");
            hresp.setHeader("Access-Control-Allow-Headers", "Content-Type,XFILENAME,XFILECATEGORY,XFILESIZE,x-requested-with,requesttype");
            //header('Access-Control-Allow-Headers:x-requested-with,content-type,requesttype');
            // 浏览器是会先发一次options请求,如果请求通过,则继续发送正式的post请求
            // 配置options的请求返回
            if (hreq.getMethod().equals("OPTIONS")) {  //如果发现该请求为OPTION,则直接返回(不需要进入系统),并且设置相应信息
                hresp.setStatus(200);
                // hresp.setContentLength(0);
                hresp.getWriter().write("OPTIONS returns OK");
                return;
            }
            // Filter 只是链式处理,请求依然转发到目的地址。
            chain.doFilter(request, response);
        }
    }

    1.2  注册一个配置类(Configuration),把上面定义的filter类注册到上下文环境中

    @Configuration
    public class WebConfiguration {
        @Bean
        public RemoteIpFilter remoteIpFilter() {
            return new RemoteIpFilter();
        }
        @Bean
        public FilterRegistrationBean<CrossDomainFilter> testFilterRegistration() {
            FilterRegistrationBean<CrossDomainFilter> registration = new FilterRegistrationBean<CrossDomainFilter>();
            registration.setFilter(new CrossDomainFilter());
            registration.addUrlPatterns("/*");
            registration.addInitParameter("paramName", "paramValue");
            registration.setName("MyFilter");
            registration.setOrder(1);
            return registration;
        }
    }

    备注:这个配置类主要解决我们编写的filter(CrossDomainFilter )拦截那些请求

    二. SpringBoot自己的解决跨域的Filter(CorsFilter) ,该filter的源码很简单,可直接查看还类的doFilterInternal() 方法,因为该发法在doFilter()方法中会调用(可以理解就是Filter的doFilter()方法)。

     处理过程也是接受到OPTION方法并相应200并返回

    @Configuration
    @EnableAutoConfiguration
    public class CrossOriginconfig {
        @Bean
        public CorsFilter corsFilter() {
            final UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource = new UrlBasedCorsConfigurationSource();
            final CorsConfiguration corsConfiguration = new CorsConfiguration();
            corsConfiguration.setAllowCredentials(true);
            // 设置你要允许的网站域名,如果全允许则设为 *
            corsConfiguration.addAllowedOrigin("*");
            // 如果要限制 HEADER 或 METHOD 请自行更改
            corsConfiguration.addAllowedHeader("*");
            corsConfiguration.addAllowedMethod("*");
            urlBasedCorsConfigurationSource.registerCorsConfiguration("/**", corsConfiguration);
            System.out.println("confi init");
            return new CorsFilter(urlBasedCorsConfigurationSource);
        }
    }

    三:个人对跨域问题的小结

         浏览器在发送请求之前,最先检测到跨域问题,并在发送跨域请求之前先发送了一个类型为OPTIONS的请求(请求地址不变,并且请求头上携带了一些其他信息),该请求必须得到服务器响应(请查CrossDomainFilter ),如果该请求没有得到响应,则浏览器不会发送真正的请求了

    3.1 :浏览器发送的OPTION请求(试探性的请求)

      备注: 有图我们发现请求地址不变(),请求方法为OPTION,并且请求头中携带了一些信息该信息可以表明我是一个跨域请求,并且请求的方式是POST。。

    3.2 :服务器需要对该请求做出相应,(请查CrossDomainFilter )

     1)首先设置相应相应头(告诉浏览器我支持的跨域请求的一些信息)

     2) 设置相应状态为200,并且返回数据(任意数据)

    3.3 :浏览器获得到了OPTION请求的相应(服务器接受跨域),故放心发送真正的请求,如下

    1)对比OPTION请求,请求地址没变^_^

    2)对比请求方式该请求为POST.  并且POST请求在OPTIN中已经告诉服务器了(Access-Control-Request-Method)。

    3)对比OPTION请求的头,该请求并没有Access-Control-Allow-****的相关参数。

  • 相关阅读:
    sqlserver跨数据库查询数据
    sqlserver调用钉钉方法
    SQL Server判断对象是否存在
    再学一次C#(基本类型篇)
    .net core部署到centos官方文档的一点小问题
    C#字符串和byte之间的互相转化(转载出自:https://www.cnblogs.com/liangxiaoking/p/5958456.html)
    30分钟通过Kong实现.NET网关
    Envoy实现.NET架构的网关(五)集成Redis实现限流
    Envoy实现.NET架构的网关(四)集成IdentityServer4实现OAuth2认证
    Envoy实现.NET架构的网关(三)代理GRPC
  • 原文地址:https://www.cnblogs.com/jinliang374003909/p/10417296.html
Copyright © 2020-2023  润新知