跨域共享(CORS)与 @CrossOrigin
注解
在现代的Web开发中,跨域请求是一个常见的场景。由于安全原因,浏览器会对跨域请求进行限制。为了打破这种限制,CORS(Cross-Origin Resource Sharing)应运而生,它是一种机制,允许浏览器在一个域上发起请求到另一个域,资源服务器通过HTTP头告诉浏览器该请求是被允许的。
在 Spring Boot 中,可以通过 @CrossOrigin
注解来简化 CORS 配置,从而使得跨域请求更加方便。
一、CORS(跨域资源共享)概述
CORS 是一种标准,它允许 Web 应用在一个域名下的浏览器中发起跨域 HTTP 请求。跨域请求被浏览器默认限制,主要是出于安全原因,避免恶意网站进行攻击。
跨域请求通常包括两种方式:
-
简单请求:符合以下条件的请求被认为是简单请求:
- 请求方式是
GET
、POST
或HEAD
。 - 请求头中只有以下几种字段:
Accept
、Accept-Language
、Content-Language
、Last-Event-ID
、Content-Type
(仅支持application/x-www-form-urlencoded
、multipart/form-data
、text/plain
)。
- 请求方式是
-
预检请求 (Preflight Request):当请求方式或请求头不符合简单请求的条件时,浏览器会发送一个
OPTIONS
请求,来询问目标服务器是否允许跨域请求。如果服务器响应允许,浏览器才会发送实际请求。
二、CORS 的工作原理
-
客户端请求:客户端向不同域的服务器发送请求(通常是 Ajax 请求)。
-
服务器响应:
-
如果服务器允许该跨域请求,它将在响应头中设置 CORS 相关的字段,例如
Access-Control-Allow-Origin
。 -
常见的 CORS 响应头包括:
Access-Control-Allow-Origin
:指定哪些域名可以访问资源。如果值为*
,表示任何域都可以访问。Access-Control-Allow-Methods
:指定允许的 HTTP 方法,例如GET, POST, PUT, DELETE
等。Access-Control-Allow-Headers
:指定允许的请求头字段。Access-Control-Allow-Credentials
:是否允许发送 Cookie 信息。
-
-
浏览器处理:浏览器根据响应头判断是否允许此次跨域请求。
三、@CrossOrigin
注解
Spring 提供了 @CrossOrigin
注解来处理 CORS 跨域问题。通过该注解,我们可以方便地在方法或类级别上进行跨域设置。
1. 使用方式
- 全局配置 :可以在
@SpringBootApplication
类中通过 Java 配置类全局配置 CORS。 - 方法级别配置 :也可以直接在控制器的方法上使用
@CrossOrigin
注解来进行局部配置。
2. 在 Controller 类或方法上使用 @CrossOrigin
可以通过 @CrossOrigin
注解来允许特定的请求跨域访问。
示例:
kotlin
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ExampleController {
// 允许所有来源的跨域请求
@CrossOrigin
@GetMapping("/hello")
public String hello() {
return "Hello, world!";
}
// 仅允许特定来源的跨域请求
@CrossOrigin(origins = "http://example.com")
@GetMapping("/greet")
public String greet() {
return "Greetings from Spring Boot!";
}
// 允许多个来源
@CrossOrigin(origins = {"http://example.com", "http://another.com"})
@GetMapping("/multi-origin")
public String multiOrigin() {
return "Multiple origins are allowed!";
}
}
3. @CrossOrigin
参数
origins
:指定允许的跨域源,可以是单个域名或多个域名,也可以是*
(允许所有域)。methods
:允许的 HTTP 方法,默认为所有方法。allowedHeaders
:指定允许的请求头,默认为所有请求头。exposedHeaders
:指定哪些响应头是可供客户端访问的。allowCredentials
:是否允许带上认证信息(如 Cookies)。默认为false
。maxAge
:预检请求的有效期(单位:秒)。
完整示例:
less
@CrossOrigin(origins = "http://example.com",
methods = {RequestMethod.GET, RequestMethod.POST},
allowedHeaders = "Authorization",
allowCredentials = "true",
maxAge = 3600)
@GetMapping("/secure")
public String secureEndpoint() {
return "This is a secure endpoint with CORS!";
}
四、全局配置 CORS
如果想在 Spring Boot 应用中进行全局的 CORS 配置,可以通过配置类来完成。使用 WebMvcConfigurer
接口并重写 addCorsMappings()
方法来实现。
全局 CORS 配置:
kotlin
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;
@Configuration
public class GlobalCorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**") // 允许所有路径
.allowedOrigins("http://example.com", "http://another.com") // 允许的来源
.allowedMethods("GET", "POST") // 允许的方法
.allowedHeaders("Authorization", "Content-Type") // 允许的请求头
.allowCredentials(true) // 允许带上身份认证信息
.maxAge(3600); // 预检请求缓存时间
}
}
这样,你的应用程序中的所有请求都会遵循这个 CORS 配置,而无需在每个方法上单独添加 @CrossOrigin
注解。
五、CORS 与安全性
- 公开 CORS 配置 :尽量避免使用
Access-Control-Allow-Origin: *
来允许所有域访问,尤其是在生产环境中。这样做可能暴露敏感信息。建议限制允许的来源。 - Credentials :如果需要发送带有认证信息(如 cookies)的请求,可以设置
allowCredentials = true
,同时需要显式指定origins
为具体域名,不能是*
。 - Preflight Requests:当浏览器进行预检请求时,确保服务器返回正确的响应,允许跨域请求。
总结
- CORS(跨域资源共享) 是一种机制,允许浏览器发起跨域 HTTP 请求,通常通过设置响应头来控制哪些源能够访问。
- Spring 提供了
@CrossOrigin
注解和全局配置方法来简化 CORS 的配置,适应多种跨域需求。 - 使用 CORS 时要特别注意安全性,避免开放过多的跨域请求,特别是对于敏感信息的传输。
- www.52runoob.com/archives/48...