SpringBoot 跨域配置方法

方式一:使用过滤器

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 WebConfig {

    // 过滤器跨域配置
    @Bean
    public CorsFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();

        CorsConfiguration config = new CorsConfiguration();

        // 允许跨域的头部信息
        config.addAllowedHeader("*");
        // 允许跨域的方法
        config.addAllowedMethod("*");
        // 可访问的外部域
        config.addAllowedOrigin("*");
        // 需要跨域用户凭证(cookie、HTTP认证及客户端SSL证明等)
        //config.setAllowCredentials(true);
        //config.addAllowedOriginPattern("*");

        // 跨域路径配置
        source.registerCorsConfiguration("/**", config);
        return new CorsFilter(source);
    }
}

 

方式二:实现 WebMvcConfigurer,重写 addCorsMappings 方法

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebConfig implements WebMvcConfigurer {

    // 拦截器跨域配置
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        // 跨域路径
        CorsRegistration cors = registry.addMapping("/**");

        // 可访问的外部域
        // 在Springboot2.4对应Spring5.3后在设置allowCredentials(true)的基础上不能直接使用通配符设置allowedOrigins,而是需要指定特定的URL。如果需要设置通配符,需要通过allowedOriginPatterns指定
        cors.allowedOrigins("*");
        // 支持跨域用户凭证
        //cors.allowCredentials(true);
        // 允许跨域的域名,可以用*表示允许任何域名使用
        //cors.allowedOriginPatterns("*");
        // 设置 header 能携带的信息
        cors.allowedHeaders("*");
        // 支持跨域的请求方法
        cors.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS");
        // 设置跨域过期时间,单位为秒
        cors.maxAge(3600);
    }

    // 简写形式
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("*")
                //.allowCredentials(true)
                //.allowedOriginPatterns("*")
                .allowedHeaders("*")
                .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
                // maxAge(3600)表明在3600秒内,不需要再发送预检验请求,可以缓存该结果
                //.exposedHeaders(HttpHeaders.SET_COOKIE).maxAge(3600L); 
                .maxAge(3600);
    }
}

 

方式三:使用 @CrossOrigin 注解

@RestController
@RequestMapping("/client")
// @CrossOrigin
public class HelloController {

    @CrossOrigin
    @GetMapping("/hello")
    public Result hello() {
        return Result.success();
    }

    @RequestMapping(value = "/test", method = RequestMethod.GET)
    public Result test() {
        return Result.fail();
    }

}

CrossOrigin源码解析

查看代码

// @CrossOrigin 源码
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface CrossOrigin {
    /** @deprecated */
    @Deprecated
    String[] DEFAULT_ORIGINS = new String[]{"*"};
    /** @deprecated */
    @Deprecated
    String[] DEFAULT_ALLOWED_HEADERS = new String[]{"*"};
    /** @deprecated */
    @Deprecated
    boolean DEFAULT_ALLOW_CREDENTIALS = false;
    /** @deprecated */
    @Deprecated
    long DEFAULT_MAX_AGE = 1800L;

    @AliasFor("origins")
    String[] value() default {};

    @AliasFor("value")
    String[] origins() default {};

    String[] originPatterns() default {};

    String[] allowedHeaders() default {};

    String[] exposedHeaders() default {};

    RequestMethod[] methods() default {};

    String allowCredentials() default "";

    long maxAge() default -1L;
}

 

方式四:采用过滤器(filter)的方式

package com.shiyun.filter;
import org.springframework.stereotype.Component;
import javax.servlet.*;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Component
public class CoresFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void destroy() {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, HEAD");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "access-control-allow-origin, authority, content-type, version-info, X-Requested-With");
        filterChain.doFilter(servletRequest, servletResponse);
    }
}

 

方式五:使用FilterRegistrationBean并且设置过滤器设置执行顺序


import org.springframework.boot.web.servlet.FilterRegistrationBean;
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;

/**
 * Classname:CorsFilterConfig
 *
 * @description:解决跨域请求问题
 **/
@Configuration
public class CorsFilterConfig  {
    /**
     * @Description :跨域访问过滤器,设置执行顺序
     * @Date 19:55 2021/6/15 0015
     * @return org.springframework.boot.web.servlet.FilterRegistrationBean<org.springframework.web.filter.CorsFilter>
     **/
   @Bean
    public FilterRegistrationBean<CorsFilter> corsFilterRegistrationBean(){
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
       config.addAllowedOriginPattern("*");
       config.addAllowedHeader("*");
       config.addAllowedMethod("*");
       config.setAllowCredentials(true);
        source.registerCorsConfiguration("/**", config); // CORS 配置对所有接口都有效
        FilterRegistrationBean<CorsFilter> bean = new FilterRegistrationBean<>(new CorsFilter(source));
        //设置执行顺序,数字越小越先执行
        bean.setOrder(0);
        return bean;
    }
}

vuecli+axios 测试案例

<template>
  <div class="main">
    <div class="button-group">
      <button class="button" @click="handleGet('/client/hello')">hello</button>|
      <button class="button" @click="handleGet('/client/test')">test</button>|
    </div>
  </div>
</template>

<script>
import axios from '../../node_modules/axios'

let http = axios.create({
  baseURL: 'http://localhost:9090',
  timeout: 1000 * 5
})

// 跨域请求是否提供凭据信息(cookie、HTTP认证及客户端SSL证明等)  这个最好是与后端的 allowCredentials 保持一致
// http.defaults.withCredentials = true

export default {
  methods: {
    handleGet(url) {
      http({
        url
      }).then(res => {
        console.log(res.data)
      })
    }
  }
}
</script>

 

posted @ 2022-05-27 16:23  xiexie0812  阅读(841)  评论(0编辑  收藏  举报