springboot项目解决跨域的几种方式

        跨域资源共享(CORS):通过修改Http协议header的方式,实现跨域。说的简单点就是,通过设置HTTP的响应头信息,告知浏览器哪些情况在不符合同源策略的条件下也可以跨域访问,浏览器通过解析Http协议中的Header执行具体判断。具体的Header如下:

CORS跨域常用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

目录

1.使用CorsFilter进行全局跨域配置

2. 重写WebMvcConfigurer的addCorsMappings方法(全局跨域配置)

3.使用CrossOrigin注解(局部跨域配置)

4 使用HttpServletResponse设置响应头(局部跨域配置)


springboot项目实现cors的四种方式

1.使用CorsFilter进行全局跨域配置

创建一个配置类

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

/**
 * @author xiaomifeng1010
 * @version 1.0
 * @date: 2022/4/6 11:37
 * @Description 全局跨域处理
 */
@Configuration
public class GlobalCorsConfigure {

    @Bean
    public CorsFilter corsFilter() {

        CorsConfiguration config = new CorsConfiguration();
        //开放哪些ip、端口、域名的访问权限,星号表示开放所有域
        config.addAllowedOrigin("*");
        //是否允许发送Cookie信息
        config.setAllowCredentials(true);
        //开放哪些Http方法,允许跨域访问
        config.addAllowedMethod(HttpMethod.GET);
        config.addAllowedMethod(HttpMethod.POST);
        config.addAllowedMethod(HttpMethod.PUT);
        config.addAllowedMethod(HttpMethod.DELETE);
        //允许HTTP请求中的携带哪些Header信息
        config.addAllowedHeader("*");
        //暴露哪些头部信息(因为跨域访问默认不能获取全部头部信息)
        config.addExposedHeader("*");

        //添加映射路径,“/**”表示对所有的路径实行全局跨域访问权限的设置
        UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource();
        configSource.registerCorsConfiguration("/**", config);

        return new CorsFilter(configSource);
    }
}

2. 重写WebMvcConfigurer的addCorsMappings方法(全局跨域配置)

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

/**
 * @author xiaomifeng1010
 * @version 1.0
 * @date: 2022/4/6 11:37
 * @Description 全局跨域处理
 */
@Configuration
public class GlobalCorsConfigure {

    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurer() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/**")    //添加映射路径,“/**”表示对所有的路径实行全局跨域访问权限的设置
                        .allowedOrigins("*")    //开放哪些ip、端口、域名的访问权限
                        .allowCredentials(true)  //是否允许发送Cookie信息
                        .allowedMethods("GET","POST", "PUT", "DELETE")     //开放哪些Http方法,允许跨域访问
                        .allowedHeaders("*")     //允许HTTP请求中的携带哪些Header信息
                        .exposedHeaders("*");   //暴露哪些头部信息(因为跨域访问默认不能获取全部头部信息)
            }
        };
    }
}

3.使用CrossOrigin注解(局部跨域配置)

  • 将CrossOrigin注解加在Controller层的方法上,该方法定义的RequestMapping端点将支持跨域访问
  • 将CrossOrigin注解加在Controller层的类定义处,整个类所有的方法对应的RequestMapping端点都将支持跨域访问
@RequestMapping("/cors")
@ResponseBody
@CrossOrigin(origins = "http://localhost:8080", maxAge = 3600) 
public String cors( ){
    return "cors";
}

4 使用HttpServletResponse设置响应头(局部跨域配置)

这种方式略显麻烦,不建议在SpringBoot项目中使用。

@RequestMapping("/cors")
@ResponseBody
public String cors(HttpServletResponse response){
    //使用HttpServletResponse定义HTTP请求头,最原始的方法也是最通用的方法
    response.addHeader("Access-Control-Allow-Origin", "http://localhost:8080");
    return "cors";
}

注意事项,如果你的项目中使用了某个独立的认证框架,那么springboot中提供的跨域配置可能会不生效,例如使用sa-token这个授权认证的框架后,解决跨域问题的话,亲测直接使用上边前三种方法是不生效的,因此,需要使用sa-token中提供的过滤器进行配置

如下:

import cn.dev33.satoken.context.SaHolder;
import cn.dev33.satoken.filter.SaServletFilter;
import cn.dev33.satoken.jwt.StpLogicJwtForStyle;
import cn.dev33.satoken.router.SaRouter;
import cn.dev33.satoken.stp.StpLogic;
import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.util.SaResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author xiaomifeng1010
 * @version 1.0
 * @date: 2022/4/1 10:51
 * @Description
 */
@Configuration
@Slf4j
public class SaTokenConfigure {

    /**
     * @description: Sa-Token 整合jwt(Style模式)
     * @author: xiaomifeng1010
     * @date: 2022/4/1
     * @param
     * @return: StpLogic
     **/
    @Bean
    public StpLogic getStpLogicJwt() {
        return new StpLogicJwtForStyle();
    }

    /**
     * @description: 注册 Sa-Token全局过滤器
     * @author: xiaomifeng1010
     * @date: 2022/4/1
     * @param
     * @return: SaServletFilter
     **/
    @Bean
    public SaServletFilter getSaServletFilter() {
        return new SaServletFilter()

                // 指定 拦截路由 与 放行路由
                .addInclude("/**").addExclude("/favicon.ico")
                // 认证函数: 每次请求执行
                .setAuth(obj -> {
                    log.info("---------- 进入Sa-Token全局认证 -----------");

                    // 登录认证 -- 拦截所有路由,并排除/user/doLogin和获取验证码的接口 用于开放登录
                    SaRouter.match("/h5/**").notMatch("/h5/getCaptcha","/h5/login").check(() -> StpUtil.checkLogin());
                })
                // 异常处理函数:每次认证函数发生异常时执行此函数
                .setError(e -> {
                    log.error("---------- 进入Sa-Token异常处理 -----------");
                      log.error(e.getMessage());
                    return SaResult.error(e.getMessage());
                })
                // 前置函数:在每次认证函数之前执行
                .setBeforeAuth(r -> {
                    // 设置一些安全响应头
                    SaHolder.getResponse()
                            // 服务器名称
                            .setServer("sa-server")
                            // 允许指定域访问跨域资源
                            .setHeader("Access-Control-Allow-Origin", "*")
                            // 允许所有请求方式
                            .setHeader("Access-Control-Allow-Methods", "POST,GET,OPTIONS,DELETE")
                            // 有效时间
                            .setHeader("Access-Control-Max-Age", "3600")
                            // 允许的header参数
                            .setHeader("Access-Control-Allow-Headers", "*")
                            // 是否可以在iframe显示视图: DENY=不可以 | SAMEORIGIN=同域下可以 | ALLOW-FROM uri=指定域名下可以
//                            .setHeader("X-Frame-Options", "SAMEORIGIN")
                            // 是否启用浏览器默认XSS防护: 0=禁用 | 1=启用 | 1; mode=block 启用, 并在检查到XSS攻击时,停止渲染页面
                            .setHeader("X-XSS-Protection", "1; mode=block")
                            // 禁用浏览器内容嗅探
                            .setHeader("X-Content-Type-Options", "nosniff")
                    ;
                })
                ;
    }
}

在这个配置类中也有一个注意事项:就是异常处理时,不要使用你在项目中自定义的 统一响应封装对象,需要使用sa-token中自带的统一响应封装对象SaResult,不然返回的对象格式不是标准的json格式,亲自试过踩坑

你可能感兴趣的:(Spring,Boot,java,spring,boot,跨域,cors)