• [转] Springboot 解决跨域的四种姿势


    文章来源:https://juejin.cn/post/7000578331485667359  作者:小棋子006 

    姿势1 实现 WebMvcConfigurer#addCorsMappings 的方法

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

    姿势2 重新注入 CorsFilter

    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.cors.CorsConfiguration;
    import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
    import org.springframework.web.filter.CorsFilter;
    
    /**
     * 解决跨域
     */
    @Configuration
    public class CorsFilterConfig {
    
        /**
         * 开启跨域访问拦截器
         *
         * @date 2021/4/29 9:50
         */
        @Bean
        public CorsFilter corsFilter() {
            //创建CorsConfiguration对象后添加配置
            CorsConfiguration corsConfiguration = new CorsConfiguration();
            //设置放行哪些原始域
            corsConfiguration.addAllowedOrigin("*");
            //放行哪些原始请求头部信息
            corsConfiguration.addAllowedHeader("*");
            //放行哪些请求方式
            corsConfiguration.addAllowedMethod("*");
    
            UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
            //2. 添加映射路径
            source.registerCorsConfiguration("/**", corsConfiguration);
            return new CorsFilter(source);
        }
    }

    姿势3 创建一个 filter 解决跨域

    @Slf4j
    @Component
    @WebFilter(urlPatterns = { "/*" }, filterName = "headerFilter")
    public class HeaderFilter implements Filter {
        @Override
        public void doFilter(ServletRequest request, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
            HttpServletResponse response = (HttpServletResponse) resp;
            //解决跨域访问报错
            response.setHeader("Access-Control-Allow-Origin", "*");
            response.setHeader("Access-Control-Allow-Methods", "POST, PUT, GET, OPTIONS, DELETE");
            //设置过期时间
            response.setHeader("Access-Control-Max-Age", "3600");
            response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, client_id, uuid, Authorization");
            // 支持HTTP 1.1.
            response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
            // 支持HTTP 1.0. response.setHeader("Expires", "0");
            response.setHeader("Pragma", "no-cache");
            // 编码
            response.setCharacterEncoding("UTF-8");
            chain.doFilter(request, resp);
        }
    
        @Override
        public void init(FilterConfig filterConfig) {
            log.info("跨域过滤器启动");
        }
    
        @Override
        public void destroy() {
            log.info("跨域过滤器销毁");
        }
    }

    姿势4 使用 CrossOrigin 注解

      可以使用在单个方法上也可以使用在类上

    @Target({ElementType.TYPE, ElementType.METHOD})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface CrossOrigin {
    
        /** @deprecated as of Spring 5.0, in favor of {@link CorsConfiguration#applyPermitDefaultValues} */
        @Deprecated
        String[] DEFAULT_ORIGINS = {"*"};
    
        /** @deprecated as of Spring 5.0, in favor of {@link CorsConfiguration#applyPermitDefaultValues} */
        @Deprecated
        String[] DEFAULT_ALLOWED_HEADERS = {"*"};
    
        /** @deprecated as of Spring 5.0, in favor of {@link CorsConfiguration#applyPermitDefaultValues} */
        @Deprecated
        boolean DEFAULT_ALLOW_CREDENTIALS = false;
    
        /** @deprecated as of Spring 5.0, in favor of {@link CorsConfiguration#applyPermitDefaultValues} */
        @Deprecated
        long DEFAULT_MAX_AGE = 1800;
    
    
        /**
         * Alias for {@link #origins}.
         */
        @AliasFor("origins")
        String[] value() default {};
    
        /**
         * A list of origins for which cross-origin requests are allowed. Please,
         * see {@link CorsConfiguration#setAllowedOrigins(List)} for details.
         * <p>By default all origins are allowed unless {@code originPatterns} is
         * also set in which case {@code originPatterns} is used instead.
         */
        @AliasFor("value")
        String[] origins() default {};
    
        /**
         * Alternative to {@link #origins()} that supports origins declared via
         * wildcard patterns. Please, see
         * @link CorsConfiguration#setAllowedOriginPatterns(List)} for details.
         * <p>By default this is not set.
         * @since 5.3
         */
        String[] originPatterns() default {};
    
        /**
         * The list of request headers that are permitted in actual requests,
         * possibly {@code "*"}  to allow all headers.
         * <p>Allowed headers are listed in the {@code Access-Control-Allow-Headers}
         * response header of preflight requests.
         * <p>A header name is not required to be listed if it is one of:
         * {@code Cache-Control}, {@code Content-Language}, {@code Expires},
         * {@code Last-Modified}, or {@code Pragma} as per the CORS spec.
         * <p>By default all requested headers are allowed.
         */
        String[] allowedHeaders() default {};
    
        /**
         * The List of response headers that the user-agent will allow the client
         * to access on an actual response, other than "simple" headers, i.e.
         * {@code Cache-Control}, {@code Content-Language}, {@code Content-Type},
         * {@code Expires}, {@code Last-Modified}, or {@code Pragma},
         * <p>Exposed headers are listed in the {@code Access-Control-Expose-Headers}
         * response header of actual CORS requests.
         * <p>The special value {@code "*"} allows all headers to be exposed for
         * non-credentialed requests.
         * <p>By default no headers are listed as exposed.
         */
        String[] exposedHeaders() default {};
    
        /**
         * The list of supported HTTP request methods.
         * <p>By default the supported methods are the same as the ones to which a
         * controller method is mapped.
         */
        RequestMethod[] methods() default {};
    
        /**
         * Whether the browser should send credentials, such as cookies along with
         * cross domain requests, to the annotated endpoint. The configured value is
         * set on the {@code Access-Control-Allow-Credentials} response header of
         * preflight requests.
         * <p><strong>NOTE:</strong> Be aware that this option establishes a high
         * level of trust with the configured domains and also increases the surface
         * attack of the web application by exposing sensitive user-specific
         * information such as cookies and CSRF tokens.
         * <p>By default this is not set in which case the
         * {@code Access-Control-Allow-Credentials} header is also not set and
         * credentials are therefore not allowed.
         */
        String allowCredentials() default "";
    
        /**
         * The maximum age (in seconds) of the cache duration for preflight responses.
         * <p>This property controls the value of the {@code Access-Control-Max-Age}
         * response header of preflight requests.
         * <p>Setting this to a reasonable value can reduce the number of preflight
         * request/response interactions required by the browser.
         * A negative value means <em>undefined</em>.
         * <p>By default this is set to {@code 1800} seconds (30 minutes).
         */
        long maxAge() default -1;
    }

      使用方式:

    public class GoodsController {
        @CrossOrigin(origins = "http://localhost:4000")
        @GetMapping("goods-url")
        public Response queryGoodsWithGoodsUrl(@RequestParam String goodsUrl) throws Exception {}
    }

      没错就是 @CrossOrigin 注解,点开注解

    @Target({ ElementType.METHOD, ElementType.TYPE })
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface CrossOrigin {}

      从元注解@Target可以看出,注解可以放在method、class等上面,类似RequestMapping,也就是说,整个controller下面的方法可以都受控制,也可以单个方法受控制。

      也可以得知,这个是最小粒度的cors控制办法了,精确到单个请求级别。

      以上三种方法都可以解决问题,最常用的应该是第一种、第二种,控制在自家几个域名范围下足以,一般没必要搞得太细。

      这四种配置方式都用了的话,谁生效呢,类似css中样式,就近原则,懂了吧。所以在开发新项目时,不需要等联调时候,让前端来找你了,我早就解决了跨域问题。

  • 相关阅读:
    优化网站设计系列文章总结和导读
    jQuery插件实现select下拉框左右选择_交换内容(multiselect2side)
    php代码生成二维码
    微信公众平台开发(83) 生成带参数二维码
    MySQL主从问题
    mysql配置文件my.cnf
    网站UV,与IP、PV
    git基础使用小记
    系统运维
    [译]Profile and debug your ASP.NET MVC app with Glimpse
  • 原文地址:https://www.cnblogs.com/huanshilang/p/15570930.html
Copyright © 2020-2023  润新知