springmvc源码学习(二十八)解决跨域的几种方式

2023-11-14


前言


一、跨域

是由于浏览器的同源策略限制,同源策略是一个重要的安全策略,会阻止一个域的javascript脚本和另外一个域的内容进行交互。一个请求url的协议(protocol)、域名(host)、端口(port)都要相同,其中有一个不同都会产生跨域问题。

二、解决

1、CorsFilter

(1)自定义 CustomCorsFilter

public class CustomCorsFilter extends CorsFilter {
    private CorsProps corsProps;

    public CustomCrosFilter(CorsConfigurationSource configSource, CorsProps corsProps) {
        super(configSource);
        this.corsProps = corsProps;

    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
                                    FilterChain filterChain) throws ServletException, IOException {


        response.setHeader("Access-Control-Allow-Origin", corsProps.getOrigin());
        response.setHeader("Access-Control-Allow-Credentials", corsProps.getCredentials());
        response.setHeader("Access-Control-Allow-Methods", corsProps.getMethods());
        response.setHeader("Access-Control-Allow-Headers", corsProps.getHeaders());
        filterChain.doFilter(request, response);
    }

(2)CorsProps

@ConfigurationProperties(prefix = "cors")
@Data
public class CorsProps {
    private String origin = "*";
    private String credentials = "true";
    private String methods = "POST, GET, PUT, DELETE, OPTIONS";
    private String headers = "Content-Type, Data-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With, Accept, DataType, responseType";
    private String maxAge = "300";
}

(3)CorsAutoConfiguration

@Configuration
@ConditionalOnProperty(prefix = "cors",matchIfMissing = true,value = "enabled")
@Slf4j
public class CorsAutoConfiguration {
    @Autowired
    private CorsProps corsProps;

    @Bean
    public CustomCorsFilter corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", buildConfig());
        return new CustomCorsFilter(source,crosProps);
    }

    private CorsConfiguration buildConfig() {
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        // Access-Control-Allow-Origin
        corsConfiguration.addAllowedOrigin(corsProps.getOrigin());
        corsConfiguration.addAllowedHeader(corsProps.getHeaders());
        // Access-Control-Allow-Methods
        corsConfiguration.addAllowedMethod(corsProps.getMethods());
        // 预检请求的有效期 Access-Control-Max-Age
        corsConfiguration.setMaxAge(Long.valueOf(corsProps.getMaxAge()));
        // 是否支持安全证书 Access-Control-Allow-Credentials
        corsConfiguration.setAllowCredentials(Boolean.valueOf(corsProps.getCredentials()));
        return corsConfiguration;
    }

    @Bean
    public FilterRegistrationBean corsFilterRegistrationBean(CustomCorsFilter corsFilter) {
        FilterRegistrationBean frb = new FilterRegistrationBean();
        //设置最高优先级
        frb.setOrder(Ordered.HIGHEST_PRECEDENCE);
        frb.setFilter(corsFilter);
        frb.addUrlPatterns("/*");
        frb.setName("customCorsFilter ");
        return frb;
    }

2、实现 WebMvcConfigurer

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

   @Autowired
    private CorsProps corsProps;
    
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowCredentials(Boolean.getBoolean(corsProps.getCredentials()))
                .allowedOrigins(corsProps.getOrigin())
                .allowedMethods(corsProps.getMethods().split(","))
                .allowedHeaders(corsProps.getHeaders());
    }

}

3、实现 HandlerInterceptor

(1)CorsHandlerInterceptor

public class CorsHandlerInterceptor implements HandlerInterceptor {

    private CorsProps corsProps;

    public CorsHandlerInterceptor(CorsProps corsProps) {
        this.corsProps = corsProps;
    }

    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        response.setHeader("Access-Control-Allow-Origin", corsProps.getOrigin());
        response.setHeader("Access-Control-Allow-Credentials", corsProps.getCredentials());
        response.setHeader("Access-Control-Allow-Methods", corsProps.getMethods());
        response.setHeader("Access-Control-Allow-Headers", corsProps.getHeaders());
       
        return true;
    }
}

(2)注册拦截器

@Configuration
public class CorsInterceptorConfig implements WebMvcConfigurer {

    @Autowired
    private CorsProps corsProps;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 添加拦截器,配置拦截地址
        registry.addInterceptor(new CorsHandlerInterceptor(corsProps))
                .addPathPatterns("/**");;
    }
}

其他方式也可以实现,如通过 @CrossOrigin 进行更细粒度的控制跨域 ,通过 nginx 进行代理转发等。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

springmvc源码学习(二十八)解决跨域的几种方式 的相关文章

随机推荐

  • Android开发网上的一些重要知识点

    1 android单实例运行方法 我们都知道Android平台没有任务管理器 而内部App维护 者一个Activity history stack来实现窗口显示和销毁 对于常规从快捷方式运行来看都是startActivity可能会使用FLA
  • SonarQube 04 SonarScanner的使用 Web Go项目扫描

    Web前端项目扫描 root jenkins master devops web service master ls build index html Jenkinsfile1 package lock json src config Je
  • Graph-node:创建一个新的subgraph

    Graph node 创建一个新的subgraph 1 合约源码 以TetherToken为例 TetherToken 2 开发子图 作为子图开发人员 您可以定义 The Graph 正在索引哪些区块链数据以及如何存储这些数据 以下是子图定
  • 为什么很多python文件中 都有这句代码if __name__ == ‘__main__‘:

    最近学习python 看到大多数写的好一点的python脚本或者程序中都会有 if name main 这句代码 然后收集了一些资料分享 1 这段代码是干嘛用的 python文件一般有两种使用方法 第一种是直接运行python文件 第二种是
  • 毕业设计基于OpenMV的火灾检测及人员搜寻智能车

    0 前言 这两年开始毕业设计和毕业答辩的要求和难度不断提升 传统的毕设题目缺少创新和亮点 往往达不到毕业答辩的要求 这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求 为了大家能够顺利以及最少的精力通过毕设 学长分享优质毕业设计项
  • GPT-4震撼发布:多模态大模型:Plus用户优先试用

    OpenAI 刚刚宣布正式推出 GPT 4 GPT 4 是 Generative Pre trained Transformer 4 的缩写 即生成型预训练变换模型 4 这是 OpenAI 努力扩展深度学习的最新里程碑 GPT 4 是一个大
  • Linux-0.11操作系统实验5-信号量的实现和应用

    实验环境 信号量的实现和应用 实验理论 Linux 0 11操作系统实验5理论 信号量与临界区 实验任务 在 Ubuntu 下编写程序 用信号量解决生产者 消费者问题 在 linux 0 11 中实现信号量 用生产者 消费者程序检验之 用信
  • python 快速排序的实现

    快速排序 快速排序 Quicksort 是对冒泡排序的一种改进 快速排序算法通过多次比较和交换来实现排序 其排序流程如下 首先设定一个分界值 通过该分界值将数组分成左右两部分 将大于或等于分界值的数据集中到数组右边 小于分界值的数据集中到数
  • DVWA-10.XSS (DOM)

    大约 跨站点脚本 XSS 攻击是一种注入问题 其中恶意脚本被注入到原本良性和受信任的网站上 当攻击者使用 Web 应用程序发送恶意代码 通常以浏览器端脚本的形式 时 就会发生 XSS 攻击 给其他最终用户 允许这些攻击成功的缺陷非常普遍 并
  • IDEA2021/2020 Run Dashboard的打开方法

    IDEA中微服务在service窗口以配置方式启动 网上千篇一律的在 workspace xml中配置Run Dashboard 但是只有在旧版本中才有这个节点的配置 但是新版的该怎么办呢 压根就没有这个节点 硬着头皮添加进去你会发现 问题
  • 卫星电话是直接与卫星通信还是通过地面站?

    问题 卫星电话是直接与卫星通信还是通过地面站 如果直接与卫星通信 那么得多大的发射功率 那么小的手机怎么能达到那个功率 如果是通过地面站的话 那么地面站岂不是和现在的蜂窝小区基站差不多了吗 我查卫星通信的时候 有一个人举例说明卫星通信的作用
  • 病毒分类

    根据病毒存在 隐藏 感染和激活的方式进行分类 寄生病毒 这是最常见的病毒类型 病毒并不是一个独立的程序 而是嵌入某个实用程序的一段代码 嵌入病毒的实用程序 称为感染了病毒的实用程序 一旦运行感染了病毒的实用程序 将首先激活病毒 由病毒完成对
  • 一、MicroPython移植到任意平台(简介以及源码裁剪)

    目录 一 MicroPython简介 二 MicroPython源码 1 源码获取 2 源码介绍 三 移植条件 四 系统结构 五 移植过程 一 MicroPython简介 适用于嵌入式设备的python开源解释器 占用资源少 可移植性强 二
  • linux下shell脚本启动jar包

    样例1 bin bash jar包文件路径及名称 目录按照各自配置 APP NAME home jar sys modules gen lgs modules gen jar 日志文件路径及名称 目录按照各自配置 LOG FILE home
  • C++函数模板和类模板的声明和定义问题

    C 函数模板和类模板的声明和定义问题 编译器并不是把函数模板处理成能够处理任意类的函数 编译器从函数模板通过具体类型产生不同的函数 编译器会对函数模板进行两次编译 在声明的地方对模板代码本身进行编译 在调用的地方对参数替换后的代码进行编译
  • JVM入门必备

    1 JVM 的位置 2 JVM 的体系结构 JVM Java虚拟机 是Java程序的运行环境 它对于Java平台的运行和跨平台特性的实现有着重要的作用 JVM的体系结构有以下几个部分 类加载器 ClassLoader 负责将 class字节
  • Nginx多站点部署

    背景 在nginx下每次新增站点需要修改nginx conf配置文件 比较麻烦 还容易出错 可以采用导入外部配置的方式进行添加 操作 将主配置文件中的server节点进行备份 然后删除主配置文件中的server 添加下面的配置 http i
  • SRAM,SDRAM,DRAM,ROM,EPROM,EEPROM

    SRAM 静态RAM 不用刷新 速度可以非常快 像CPU内部的cache 都是静态RAM 缺点是一个内存单元需要的晶体管数量多 因而价格昂贵 容量不大 什么是SRAM SRAM 的英文全称是 Static RAM 翻译成中文就是 静态随机存
  • hackbar 的简单使用

    https www cnblogs com wayne tao p 11027650 html 前言 hackbar是web渗透时的经典工具 但是当我开始学习网络安全的时候 发现hackbar已经开始收费了 本篇抛砖引玉介绍几个使用方法 针
  • springmvc源码学习(二十八)解决跨域的几种方式

    目录 前言 一 跨域 二 解决 1 CorsFilter 2 实现 WebMvcConfigurer 3 实现 HandlerInterceptor 前言 一 跨域 是由于浏览器的同源策略限制 同源策略是一个重要的安全策略 会阻止一个域的j