SpringBoot 如何处理跨域请求?你说的出几种方法?

引言:在现代的Web开发中,跨域请求(Cross-Origin Resource Sharing,CORS)是一个常见的挑战。随着前后端分离架构的流行,前端应用通常运行在一个与后端 API 不同的域名或端口上,这就导致了浏览器的同源策略(Same-Origin Policy)的限制,从而出现了跨域请求问题。

Spring Boot 作为一种流行的 Java 后端框架,提供了多种处理跨域请求的方法,使得开发人员能够灵活地配置和管理跨域资源共享。本文将深入探讨几种常见的解决方案,帮助开发人员理解如何在 Spring Boot 应用中有效地处理跨域请求问题。

题目

SpringBoot 如何处理跨域请求?你说的出几种方法?

推荐解析

跨域请求概述

1)什么是跨域请求?
跨域请求(Cross-Origin Request)指的是在浏览器环境下,前端代码发起的请求与当前页面的域名(或端口、协议)不同。浏览器的同源策略(Same-Origin Policy)限制了从一个源(域名、协议、端口组成的组合)加载的文档或脚本如何与来自另一个源的资源进行交互。

具体来说,如果一个页面加载自 http://domain1.com,则它的同源策略默认限制了对 http://domain2.com 发起的请求。

2)为什么会出现跨域问题?

跨域问题的出现主要是为了保护用户数据和用户隐私安全。如果没有同源策略的限制,恶意网站可以利用当前用户的身份在其他网站上进行操作,如发送请求、读取数据,这可能导致信息泄露或潜在的安全威胁。

3)可能会导致的安全风险

信息泄露:允许恶意网站读取其他网站的敏感数据。

CSRF(跨站请求伪造)攻击:如果没有适当的防护措施,允许攻击者伪造用户的请求并在用户不知情的情况下执行操作。

恶意脚本注入:通过跨域请求注入恶意脚本,影响其他域上的安全性。

跨域解决方案

1)使用@CrossOrigin注解

Spring 框架提供了@CrossOrigin注解,可以直接在 Controller 类或方法上使用,以声明允许来自特定源的请求。例如:

@RestController
@RequestMapping("/api")
public class MyController {

    @CrossOrigin(origins = "http://allowed-origin.com")
    @GetMapping("/data")
    public ResponseEntity<String> getData() {
        // 处理逻辑
    }
}

优点:简单直接,适用于简单的跨域场景。

缺点:无法进行更细粒度的配置,如请求方法、请求头等。

2) 使用WebMvcConfigurer配置类

通过自定义WebMvcConfigurer配置类,可以更灵活地配置跨域请求。例如:

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/api/**")
                .allowedOrigins("http://allowed-origin.com")
                .allowedMethods("GET", "POST")
                .allowedHeaders("header1", "header2")
                .exposedHeaders("header3")
                .allowCredentials(true)
                .maxAge(3600);
    }
}

优点:可以精确控制允许的源、方法、头部等。

缺点:需要编写额外的配置类,相对比较复杂。

3)使用过滤器(Filter)

通过自定义过滤器来处理跨域请求,这种方法可以在请求到达 Controller 之前进行处理。例如:

@Component
public class CorsFilter implements Filter {

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
            throws IOException, ServletException {
        
        HttpServletResponse response = (HttpServletResponse) res;
        HttpServletRequest request = (HttpServletRequest) req;
        
        response.setHeader("Access-Control-Allow-Origin", "http://allowed-origin.com");
        response.setHeader("Access-Control-Allow-Methods", "GET,POST");
        response.setHeader("Access-Control-Allow-Headers", "header1,header2");
        response.setHeader("Access-Control-Expose-Headers", "header3");
        response.setHeader("Access-Control-Allow-Credentials", "true");
        response.setHeader("Access-Control-Max-Age", "3600");
        
        chain.doFilter(req, res);
    }

}

优点:可以完全自定义跨域请求处理逻辑。

缺点:需要更多的Java编程经验,并且可能需要处理更复杂的跨域场景。

其他补充

鱼聪明 AI 的回答:

鱼聪明 AI 地址:https://www.yucongming.com/

1. 预检请求(Preflight Requests)

跨域请求中,某些复杂请求(如带有自定义头部的请求、使用某些特殊方法如PUT、DELETE等的请求)会触发浏览器先发送一个预检请求(OPTIONS请求)到服务器,以确定是否允许实际的请求。预检请求包含以下头部信息:

  • Origin:表明发起请求的源。
  • Access-Control-Request-Method:实际请求将使用的HTTP方法。
  • Access-Control-Request-Headers:实际请求将使用的自定义头部。

服务器需要正确响应预检请求,以确保浏览器安全地执行实际请求。

处理预检请求的方法:
  • 使用@CrossOrigin注解处理

    @CrossOrigin(origins = "http://allowed-origin.com", methods = {RequestMethod.GET, RequestMethod.POST}, allowedHeaders = {"header1", "header2"})
    @RequestMapping(value = "/api/data", method = RequestMethod.OPTIONS)
    public ResponseEntity<Void> preflight() {
        return ResponseEntity.ok().build();
    }
    

    在Controller中定义一个处理OPTIONS请求的方法,并使用@CrossOrigin注解指定允许的源、方法和头部。

  • 通过WebMvcConfigurer配置类处理

    @Configuration
    public class WebConfig implements WebMvcConfigurer {
    
        @Override
        public void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/api/**")
                    .allowedOrigins("http://allowed-origin.com")
                    .allowedMethods("GET", "POST")
                    .allowedHeaders("header1", "header2")
                    .exposedHeaders("header3")
                    .allowCredentials(true)
                    .maxAge(3600);
        }
    
        @Override
        public void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/api/**")
                    .allowedOrigins("http://allowed-origin.com")
                    .allowedMethods("GET", "POST")
                    .allowedHeaders("header1", "header2")
                    .exposedHeaders("header3")
                    .allowCredentials(true)
                    .maxAge(3600);
        }
    }
    

    WebMvcConfigurer配置类中,通过重写addCorsMappings方法来定义预检请求的处理方式。

2. 其他注意事项

  • Credentials(凭证)的处理

    如果请求需要使用凭证(如使用Cookie、HTTP认证信息等),需要确保在跨域请求中设置Access-Control-Allow-Credentialstrue,并在客户端请求中设置withCredentialstrue

  • 暴露自定义头部

    如果需要在响应中暴露某些自定义头部供客户端访问,可以通过Access-Control-Expose-Headers头部指定。

  • 缓存控制

    可以通过Access-Control-Max-Age头部指定预检请求的缓存时间,减少重复发送预检请求的次数,提升性能。

总结

避免跨域请求问题不仅仅是简单地允许跨域请求,还需要正确处理预检请求及相关细节。通过使用@CrossOrigin注解、自定义WebMvcConfigurer配置类或过滤器来处理跨域请求,可以有效地保证跨域请求的安全性和可靠性。同时,要特别注意凭证的处理及其他相关头部信息的配置,确保跨域请求能够在安全、可控的环境下完成。

欢迎交流

本文主要介绍 SpringBoot 处理跨域请求的方式,另外可以用 SpringSecurity 和 SpringCloudGateWay 等框架进行全局跨域处理,在文末还剩下三个问题,欢迎小伙伴在评论区进行留言!近期面试鸭小程序已全面上线,想要刷题的小伙伴可以积极参与!

1)如何区分简单请求和复杂请求?

2)在实际项目中,如何选择合适的跨域请求解决方案?

3)如何处理凭证(Credentials)在跨域请求中的应用?

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/767014.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

AI生成电商模特图应用定制

&#x1f31f; 广州AI生成电商模特图应用定制案例剖析— 触站AI&#xff0c;绘制智能图像的未来 &#x1f680; &#x1f3a8; 触站AI&#xff0c;让创意与智能共绘辉煌 &#x1f3a8;在这座充满创新活力的广州城&#xff0c;触站AI以其尖端AI技术&#xff0c;开启了企业AI图像…

动态代理--通俗易懂

程序为什么需要代理&#xff1f;代理长什么样&#xff1f; 例子 梳理 代理对象(接口)&#xff1a;要包含被代理的对象的方法 ---Star 被代理对象&#xff1a;要实现代理对象(接口) ---SuperStar 代理工具类&#xff1a;创建一个代理&#xff0c;返回值用代理对象&#xff0c…

yolov5实例分割跑通以及C#读取yolov5_Seg实例分割转换onnx进行检测部署

一、首先需要训练yolov5_seg的模型&#xff0c;可以去网上学习&#xff0c;或者你直接用我的&#xff0c; 训练环境和yolov5—7.0的环境一样&#xff0c;你可以直接拷过来用。 yolov5_seg算法 链接&#xff1a;https://pan.baidu.com/s/1m-3lFWRHwg5t8MmIOKm4FA 提取码&…

Zombie Voices Audio Pack(僵尸游戏音频包)

僵尸声音音频包是600多个高质量声波的集合。 它提供了僵尸主题游戏所需的一切&#xff0c;这要归功于它的20多个类别&#xff1a; 攻击、咬、呼吸、窒息、损坏、死亡、进食、血腥、咕噜、大笑、疼痛、反应、尖叫、喉咙、呕吐、单词和句子。 我们的僵尸动画包带来的额外奖励&am…

自从棋牌游戏有了AI助阵,赢“麻”了!看这篇就够了

毛主席曾经说过&#xff1a;“中国对世界的三大贡献&#xff0c;第一是中医&#xff0c;第二是曹雪芹的《红楼梦》&#xff0c;第三是麻将牌。”麻将起源于中国&#xff0c;是国粹。各地的麻将玩法各不相同&#xff0c;比如云贵川地区的“缺一门”打法&#xff0c;广东麻将流行…

【课程设计】基于python的一款简单的计算器

我们是大二本科生团队&#xff0c;主力两人耗时3天完成了这款计算器的制作。希望大家给我们多多引流&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; 欢迎各位优秀的高考学子报考长安大学&#xff0c;报考长安大学电子信息工程专业。 欢迎有志于就…

vite项目如何在本地启动https协议

vite项目如何在本地启动https协议 本地启动正常配置在vite.config.js文件中默认启动http协议的请求&#xff0c;如何改成https呢&#xff1f;今天的开发中遇到了这个问题项目需求&#xff1a; 本地启动https协议的前端页面并且正常访问后台https协议的接口 解决方法&#xff1a…

python学习-tuple及str

为什么需要元组 定义元组 元组的相关操作 元组的相关操作 - 注意事项 元组的特点 字符串 字符串的下标&#xff08;索引&#xff09; 同元组一样&#xff0c;字符串是一个&#xff1a;无法修改的数据容器。 如果必须要修改字符串&#xff0c;只能得到一个新的字符串&#xff…

如何对GD32 MCU进行加密?

GD32 MCU有哪些加密方法呢&#xff1f;大家在平时项目开发的过程中&#xff0c;最后都可能会面临如何对出厂产品的MCU代码进行加密&#xff0c;避免产品流向市场被别人读取复制。 下面为大家介绍GD32 MCU所支持的几种常用的加密方法&#xff1a; 首先GD32 MCU本身支持防硬开盖…

信息学一周赛事安排

本周比赛提醒 本周末有以下几场比赛即将开始&#xff1a; :::block-1 1.ABC-361 比赛时间&#xff1a;7月6日&#xff08;周六&#xff09;晚20:00 比赛链接&#xff1a;https://atcoder.jp/contests/abc361 3.CF-956(Div.2) 比赛时间&#xff1a;7月7日&#xff08;周日…

【日常记录】【JS】获取用户IP地址及其他信息

1. 查询本机的IP地址 1.1 通过命令提示符 电脑按下 ctrl r &#xff0c;输入 cmd 后按回车&#xff0c;打开命令提示符窗口输入命令&#xff1a; ipconfig &#xff0c;然后按回车 下面这个红色框里面就是 ip地址 在输出结果中找到“无线局域网适配器 WLAN”或“以太网适配器…

python-切片、集合

序列是指&#xff1a;内容连续、有序&#xff0c;可使用下标索引的一类数据容器 序列的常用操作 - 切片 切片的语法 序列的常用操作 - 切片 注意切片的范围是左闭右开 为什么使用集合 集合的常用操作 - 修改 集合的常用操作 - 集合长度 集合常用功能总结 集合的特点

python小练习04

三国演义词频统计与词云图绘制 import jieba import wordcloud def analysis():txt open("三国演义.txt",r,encodingutf-8).read()words jieba.lcut(txt)#精确模式counts {}for word in words:if len(word) 1:continueelif word "诸葛亮" or word &q…

一个使用 g++ 模块化编译的 hello world 示例( Ubuntu 20.04 )

1. 确认 ubuntu 版本&#xff1a; 2. 文件夹结构&#xff1a; 3. 各个文件内容&#xff1a; 3.1. myadd.cpp&#xff1a; #include<iostream> using namespace std; int add_xxx( int a,int b ){int result a b;cout << a << " " << …

责任大,权力小:项目经理如何有效管理项目

成为项目经理&#xff0c;我们才会发现这份工作远非想象中那般轻松。在大多数企业中&#xff0c;项目经理更像是小团队中的舵手&#xff0c;需要在有限的权力和资源下&#xff0c;承担起巨大的责任&#xff0c;甚至不惜牺牲个人时间&#xff0c;加班至深夜。责任重大而权力有限…

解析MySQL的数据类型:理解每种类型及其应用

MySQL是一种流行的关系型数据库管理系统&#xff0c;被广泛应用于Web应用开发中。在数据库设计的过程中&#xff0c;选择合适的数据类型至关重要&#xff0c;因为它不仅影响存储效率和数据完整性&#xff0c;还影响数据库操作的性能和查询速度。本文将详细介绍MySQL支持的各种数…

职业技能大赛引领下人工智能专业实训教学的改革研究

在新时代背景下&#xff0c;人工智能&#xff08;AI&#xff09;作为科技发展的前沿领域&#xff0c;正以前所未有的速度影响着社会经济的各个方面&#xff0c;对高素质应用型AI专业人才的需求日益迫切。职业技能大赛作为检验和提升学生实践能力的重要平台&#xff0c;对于促进…

linux内存屏障

why? 为什么要有内存屏障&#xff0c;内存屏障主要解决什么问题 What? 内存屏障都有哪些 How? 内存屏障如何使用 本篇文章主要解决前两个问题 一、为什么要有内存屏障 我们都知道计算机运算任务需要CPU和内存相互配合共同完成&#xff0c;其中CPU负责逻辑计算&#xf…

HUAWEI MPLS 静态配置和动态LDP配置

MPLS(Multi-Protocol Label Switching&#xff0c;多协议标签交换技术)技术的出现&#xff0c;极大地推动了互联网的发展和应用。例如&#xff1a;利用MPLS技术&#xff0c;可以有效而灵活地部署VPN(Virtual Private Network&#xff0c;虚拟专用网)&#xff0c;TE(Traffic Eng…

将iStoreOS部署到VMware ESXi变成路由器

正文共&#xff1a;888 字 19 图&#xff0c;预估阅读时间&#xff1a;1 分钟 前面把iStoreOS部署到了VMware workstation上&#xff08;将iStoreOS部署到VMware Workstation&#xff09;。如果想把iStoreOS直接部署到ESXi上&#xff0c;你会发现转换镜像不能直接生成OVF或者OV…