SpringBoot跨域的几种解决方案

方法一、SpringBoot的注解@CrossOrigin(也支持SpringMVC)

使用注解作用到具体controller或者method上面(局部跨域)

简单粗暴的方式,Controller层在需要跨域的类或者方法上加上该注解即可

@RestController
@CrossOrigin
@RequestMapping("/situation")
public class SituationController extends PublicUtilController {

    @Autowired
    private SituationService situationService;
    // log日志信息
    private static Logger LOGGER = Logger.getLogger(SituationController.class);
    
}
/**
 *  在方法上(@RequestMapping)使用注解 @CrossOrigin 
 */
 
@RequestMapping("/hello")
@ResponseBody
@CrossOrigin("http://localhost:8080") 
public String index( ){
    return "Hello World";
}
 
/**
 * 或者在控制器(@Controller)上使用注解 @CrossOrigin
 */
 
@Controller
@CrossOrigin(origins = "http://www.xxxxx.com", maxAge = 3600)
public class AccountController {
 
    @RequestMapping("/hello")
    @ResponseBody
    public String index( ){
        return "Hello World";
    }
}

但每个Controller都得加,代码侵入严重,使用麻烦,加在Controller公共父类(PublicUtilController)中,所有Controller继承即可。

@CrossOrigin
public class PublicUtilController {

    /**
     * 公共分页参数整理接口
     * @param currentPage
     * @param pageSize
     * @return
     */
    public PageInfoUtil proccedPageInfo(String currentPage, String pageSize) {

        /* 分页 */
        PageInfoUtil pageInfoUtil = new PageInfoUtil();
        try {
            /*
             * 将字符串转换成整数,有风险, 字符串为a,转换不成整数
             */
            pageInfoUtil.setCurrentPage(Integer.valueOf(currentPage));
            pageInfoUtil.setPageSize(Integer.valueOf(pageSize));
        } catch (NumberFormatException e) {
        }
        return pageInfoUtil;
    }
}

当然,这里虽然指SpringBoot,SpringMVC也是同样的,但要求在Spring4.2及以上的版本。

另外,如果SpringMVC框架版本不方便修改,也可以通过修改tomcat的web.xml配置文件来处理

SpringMVC使用@CrossOrigin使用场景要求

jdk1.8+
Spring4.2+

方法二、处理跨域请求的Configuration

继承重写WebMvcConfigurer(全局跨域)

增加一个配置类,CrossOriginConfig.java。继承WebMvcConfigurerAdapter或者实现WebMvcConfigurer接口,其他都不用管,项目启动时,会自动读取配置。

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

/**
 * AJAX请求跨域
 */
@Configuration
public class CorsConfig extends WebMvcConfigurerAdapter {
    static final String ORIGINS[] = new String[] { "GET", "POST", "PUT", "DELETE" };
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**").allowedOrigins("*").allowCredentials(true).allowedMethods(ORIGINS).maxAge(3600);
    }
@Configuration
public class MyWebAppConfigurer extends WebMvcConfigurerAdapter{
 
    @Override
    public void addCorsMappings(CorsRegistry registry) {
           registry.addMapping("/api/**")
            // 放行哪些原始域
           .allowedOrigins("*")
            // 是否发送Cookie信息
           .allowCredentials(true)
            // 放行哪些原始域(请求方式)
           .allowedMethods("GET","POST", "PUT", "DELETE")
            // 放行哪些原始域(头部信息)
           .allowedHeaders("*")
            // 暴露哪些头部信息(因为跨域访问默认不能获取全部头部信息)
           .exposedHeaders("Header1", "Header2");
           .allowCredentials(false).maxAge(3600);
    }
}

方法三、采用过滤器(filter)的方式

通过导入配置重新生成新的CorsFilter(全局跨域)

同方法二加配置类,增加一个CORSFilter 类,并实现Filter接口即可,其他都不用管,接口调用时,会过滤跨域的拦截。

@Component
public class CORSFilter implements Filter {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        HttpServletResponse res = (HttpServletResponse) response;
        // 设置允许Cookie
        res.addHeader("Access-Control-Allow-Credentials", "true");
        // 允许http://www.xxx.com域(自行设置,这里只做示例)发起跨域请求
        res.addHeader("Access-Control-Allow-Origin", "*");
        // 设置允许跨域请求的方法
        res.addHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT");
        // 允许跨域请求包含content-type
        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 destroy() {
    }
    
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }
}
@Configuration
public class CorsFilterConfig {
    @Bean
    public CorsFilter corsFilter() {
        // 1.添加CORS配置信息
        CorsConfiguration config = new CorsConfiguration();
          // 放行哪些原始域
          config.addAllowedOrigin("*");
          // 是否发送Cookie信息
          config.setAllowCredentials(true);
          // 放行哪些原始域(请求方式)
          config.addAllowedMethod("*");
          // 放行哪些原始域(头部信息)
          config.addAllowedHeader("*");
          // 暴露哪些头部信息(因为跨域访问默认不能获取全部头部信息)
          config.addExposedHeader("*");
 
        // 2.添加映射路径导入配置
        UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource();
        configSource.registerCorsConfiguration("/**", config);
 
        // 3.返回新的CorsFilter.
        return new CorsFilter(configSource);
    }
}

 方法五、 手动设置响应头(局部跨域)

使用 HttpServletResponse 对象添加响应头(Access-Control-Allow-Origin)来授权原始域,这里 Origin的值也可以设置为 “*”,表示全部放行。推荐:150道常见的Java面试题分解汇总

@RequestMapping("/index")
public String index(HttpServletResponse response) {
    response.addHeader("Access-Allow-Control-Origin","*");
    return "index";
}

方法四、采用nginx做动态代理

使用nginx作为代理,解决跨域问题

1)更改前端ajax访问路径:不直接访问请求接口,而是访问另外一个本域下的接口,例如:http://kuayu.com/getCat

2)修改nginx配置文件:

location /getCat { #添加访问目录为/getCat
            rewrite  ^/getCat/(.*)$ /$1 break;
            proxy_pass   http://csdn.b.com/cat/;
       }

猜你喜欢

转载自blog.csdn.net/wr_java/article/details/115301470