Spring Boot2 系列教程(十四)CORS 解决跨域问题

简介: Spring Boot2 系列教程(十四)CORS 解决跨域问题

今天和小伙伴们来聊一聊通过CORS解决跨域问题。

同源策略

很多人对跨域有一种误解,以为这是前端的事,和后端没关系,其实不是这样的,说到跨域,就不得不说说浏览器的同源策略。

同源策略是由 Netscape 提出的一个著名的安全策略,它是浏览器最核心也最基本的安全功能,现在所有支持 JavaScript 的浏览器都会使用这个策略。所谓同源是指协议、域名以及端口要相同。同源策略是基于安全方面的考虑提出来的,这个策略本身没问题,但是我们在实际开发中,由于各种原因又经常有跨域的需求,传统的跨域方案是 JSONP,JSONP 虽然能解决跨域但是有一个很大的局限性,那就是只支持 GET 请求,不支持其他类型的请求,而今天我们说的 CORS(跨域源资源共享)(CORS,Cross-origin resource sharing)是一个 W3C 标准,它是一份浏览器技术的规范,提供了 Web 服务从不同网域传来沙盒脚本的方法,以避开浏览器的同源策略,这是 JSONP 模式的现代版。

在 Spring 框架中,对于 CORS 也提供了相应的解决方案,今天我们就来 看看 SpringBoot 中如何实现 CORS。

实践

接下来我们就来看看 Spring Boot 中如何实现这个东西。

首先创建两个普通的 Spring Boot 项目,这个就不用我多说,第一个命名为 provider 提供服务,第二个命名为 consumer 消费服务,第一个配置端口为 8080,第二个配置配置为 8081,然后在 provider 上提供两个 hello 接口,一个 get,一个 post,如下:

@RestController
public class HelloController {
    @GetMapping("/hello")
    public String hello() {
        return "hello";
    }
    @PostMapping("/hello")
    public String hello2() {
        return "post hello";
    }
}

在 consumer 的 resources/static 目录下创建一个 html 文件,发送一个简单的 ajax 请求,如下:

<div id="app"></div>
<input type="button" onclick="btnClick()" value="get_button">
<input type="button" onclick="btnClick2()" value="post_button">
<script>
    function btnClick() {
        $.get('http://localhost:8080/hello', function (msg) {
            $("#app").html(msg);
        });
    }
 
    function btnClick2() {
        $.post('http://localhost:8080/hello', function (msg) {
            $("#app").html(msg);
        });
    }
</script>

然后分别启动两个项目,发送请求按钮,观察浏览器控制台如下:

Access to XMLHttpRequest at 'http://localhost:8080/hello' from origin 'http://localhost:8081' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

可以看到,由于同源策略的限制,请求无法发送成功。

使用 CORS 可以在前端代码不做任何修改的情况下,实现跨域,那么接下来看看在 provider 中如何配置。首先可以通过 @CrossOrigin 注解配置某一个方法接受某一个域的请求,如下:

@RestController
public class HelloController {
    @CrossOrigin(value = "http://localhost:8081")
    @GetMapping("/hello")
    public String hello() {
        return "hello";
    }
 
    @CrossOrigin(value = "http://localhost:8081")
    @PostMapping("/hello")
    public String hello2() {
        return "post hello";
    }
}

这个注解表示这两个接口接受来自 http://localhost:8081 地址的请求,配置完成后,重启 provider ,再次发送请求,浏览器控制台就不会报错了,consumer 也能拿到数据了。

此时观察浏览器请求网络控制台,可以看到响应头中多了如下信息:

这个表示服务端愿意接收来自 http://localhost:8081 的请求,拿到这个信息后,浏览器就不会再去限制本次请求的跨域了。

provider 上,每一个方法上都去加注解未免太麻烦了,有的小伙伴想到可以讲注解直接加在 Controller 上,不过每个 Controller 都要加还是麻烦,在 Spring Boot 中,还可以通过全局配置一次性解决这个问题,全局配置只需要在 SpringMVC 的配置类中重写 addCorsMappings 方法即可,如下:

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
        .allowedOrigins("http://localhost:8081")
        .allowedMethods("*")
        .allowedHeaders("*");
    }
}

/** 表示本应用的所有方法都会去处理跨域请求,allowedMethods 表示允许通过的请求数,allowedHeaders 则表示允许的请求头。经过这样的配置之后,就不必在每个方法上单独配置跨域了。

存在的问题

了解了整个 CORS 的工作过程之后,我们通过 Ajax 发送跨域请求,虽然用户体验提高了,但是也有潜在的威胁存在,常见的就是 CSRF(Cross-site request forgery)跨站请求伪造。跨站请求伪造也被称为 one-click attack 或者 session riding,通常缩写为 CSRF 或者 XSRF,是一种挟制用户在当前已登录的 Web 应用程序上执行非本意的操作的攻击方法,举个例子:

假如一家银行用以运行转账操作的URL地址如下:http://icbc.com/aa?bb=cc,那么,一个恶意攻击者可以在另一个网站上放置如下代码:<img src="http://icbc.com/aa?bb=cc">,如果用户访问了恶意站点,而她之前刚访问过银行不久,登录信息尚未过期,那么她就会遭受损失。

基于此,浏览器在实际操作中,会对请求进行分类,分为简单请求,预先请求,带凭证的请求等,预先请求会首先发送一个 options 探测请求,和浏览器进行协商是否接受请求。默认情况下跨域请求是不需要凭证的,但是服务端可以配置要求客户端提供凭证,这样就可以有效避免 csrf 攻击。

好了,这个问题就说这么多,关于 Spring Boot 中的 CORS ,松哥还有一个小小的视频教程

相关文章
|
12天前
|
人工智能 Java Serverless
【MCP教程系列】搭建基于 Spring AI 的 SSE 模式 MCP 服务并自定义部署至阿里云百炼
本文详细介绍了如何基于Spring AI搭建支持SSE模式的MCP服务,并成功集成至阿里云百炼大模型平台。通过四个步骤实现从零到Agent的构建,包括项目创建、工具开发、服务测试与部署。文章还提供了具体代码示例和操作截图,帮助读者快速上手。最终,将自定义SSE MCP服务集成到百炼平台,完成智能体应用的创建与测试。适合希望了解SSE实时交互及大模型集成的开发者参考。
|
10天前
|
人工智能 前端开发 JavaScript
webpack-dev-server代理后端一直报CORS跨域或500错误
在Vue项目中使用Webpack的devServer代理后端接口时,遇到500错误。问题根源在于浏览器请求中携带的Origin头导致服务器报错,而Postman测试正常。通过分析发现,调整或移除Origin头可解决问题。解决办法包括:1) 在代理配置中添加正确的Origin头;2) 删除请求中的Origin头。文章还深入解析了Origin头的作用及changeOrigin配置的实际意义,并附带相关文档链接,帮助开发者更好地理解与解决类似跨域问题。
|
2月前
|
前端开发 JavaScript 应用服务中间件
前端跨域问题解决Access to XMLHttpRequest at xxx from has been blocked by CORS policy
跨域问题是前端开发中常见且棘手的问题,但通过理解CORS的工作原理并应用合适的解决方案,如服务器设置CORS头、使用JSONP、代理服务器、Nginx配置和浏览器插件,可以有效地解决这些问题。选择合适的方法可以确保应用的安全性和稳定性,并提升用户体验。
869 90
|
2月前
|
缓存 NoSQL Java
基于SpringBoot的Redis开发实战教程
Redis在Spring Boot中的应用非常广泛,其高性能和灵活性使其成为构建高效分布式系统的理想选择。通过深入理解本文的内容,您可以更好地利用Redis的特性,为应用程序提供高效的缓存和消息处理能力。
194 79
|
2月前
|
JSON 缓存 前端开发
对CORS(跨域)的一些见解
CORS(跨域资源共享)是W3C标准,用于解决AJAX跨源请求限制。浏览器与服务器需共同支持CORS,浏览器自动处理请求头,开发者无需额外操作。CORS分为简单请求与非简单请求:简单请求满足特定条件(如方法为GET/POST/HEAD且头信息有限制),浏览器直接发送;非简单请求需先进行“预检”请求(OPTIONS方法),确认服务器允许后才发送实际请求。服务器回应需包含Access-Control-Allow-Origin等字段,以控制跨域访问权限。
81 10
|
1月前
|
人工智能 缓存 自然语言处理
保姆级Spring AI 注解式开发教程,你肯定想不到还能这么玩!
这是一份详尽的 Spring AI 注解式开发教程,涵盖从环境配置到高级功能的全流程。Spring AI 是 Spring 框架中的一个模块,支持 NLP、CV 等 AI 任务。通过注解(如自定义 `@AiPrompt`)与 AOP 切面技术,简化了 AI 服务集成,实现业务逻辑与 AI 基础设施解耦。教程包含创建项目、配置文件、流式响应处理、缓存优化及多任务并行执行等内容,助你快速构建高效、可维护的 AI 应用。
|
6月前
|
开发框架 中间件 Java
如何处理跨域资源共享(CORS)的 OPTIONS 请求?
处理 CORS 的 OPTIONS 请求的关键是正确设置响应头,以告知浏览器是否允许跨域请求以及允许的具体条件。根据所使用的服务器端技术和框架,可以选择相应的方法来实现对 OPTIONS 请求的处理,从而确保跨域资源共享的正常进行。
319 61
|
5月前
|
安全 Java 应用服务中间件
SpringBoot:CORS是什么?SpringBoot如何解决跨域问题?
CORS是Web开发中常见且重要的机制,SpringBoot通过提供注解、全局配置和过滤器等多种方式来解决跨域问题。选择适合的方式可以帮助开发者轻松处理跨域请求,提高应用的灵活性和安全性。
285 2
|
6月前
|
安全
CORS 跨域资源共享的实现原理是什么?
CORS 跨域资源共享的实现原理是什么?
|
6月前
|
安全
CORS 跨域资源共享的实现原理
CORS 跨域资源共享的实现原理
110 0

热门文章

最新文章