SpringBoot 如何解決跨域問題?
跨域問題是Web開發中常見的問題之一,特別是在前后端分離的項目中。Spring Boot作為一個流行的Java后端框架,提供了多種方式來解決跨域問題。本文將深入探討Spring Boot如何解決跨域問題,包括原理分析、代碼實現和示例展示。
一、跨域問題
1.什么是跨域
跨域是指瀏覽器出于安全考慮,對來自不同域名、協議或端口的請求進行限制。通常,當一個網頁發起的請求目標是與其來源不同的域時,就會發生跨域問題。瀏覽器采用同源策略(Same-Origin Policy)來阻止某些不安全的請求。
2.同源策略
同源策略是瀏覽器的一個安全特性,用于防止惡意網站讀取另一個網站的敏感信息。只有當協議、域名和端口號都相同時,瀏覽器才允許請求通過。
3.CORS
CORS,全稱 Cross-Origin Resource Sharing 翻譯為跨域資源共享,它使用額外的 HTTP頭來告訴瀏覽器允許 Web應用從不同的域進行請求。CORS是 W3C的一個標準,允許服務器聲明哪些源站點可以訪問它的資源。
二、Spring Boot如何解決跨域?
整理來說,Spring Boot解決跨域問題的方法有三種:
- 全局配置CORS
- 使用@CrossOrigin注解
- 自定義過濾器
1.全局配置CORS
在Spring Boot中,可以通過實現WebMvcConfigurer接口來全局配置CORS。
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 WebConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("http://example.com")
.allowedMethods("GET", "POST", "PUT", "DELETE")
.allowedHeaders("*")
.allowCredentials(true)
.maxAge(3600);
}
}
代碼分析:
- addMapping("/**"): 允許所有路徑的請求。
- allowedOrigins("http://example.com"): 允許的跨域請求來源。
- allowedMethods("GET", "POST", "PUT", "DELETE"): 允許的HTTP方法。
- allowedHeaders("*"): 允許的請求頭。
- allowCredentials(true): 是否允許發送Cookie。
- maxAge(3600): 預檢請求的緩存時間。
2.使用@CrossOrigin注解
Spring提供了@CrossOrigin注解用于簡化跨域配置。可以在控制器類或方法級別使用。
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class MyController {
@CrossOrigin(origins = "http://example.com")
@GetMapping("/greet")
public String greet() {
return "Hello World";
}
}
代碼分析:
- @CrossOrigin(origins = "http://example.com"): 指定允許跨域的來源。
- 可以在類級別使用@CrossOrigin,應用于該類的所有請求方法。
3.自定義過濾器
通過自定義過濾器,可以更靈活地處理跨域請求。
如下示例代碼,自定義過濾器 CorsFilter 實現 Filter,從而允許https://yuanjava.com 作為跨域的來源。
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import org.springframework.stereotype.Component;
@Component
public class CorsFilter implements CorsFilter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletResponse res = (HttpServletResponse) response;
res.setHeader("Access-Control-Allow-Origin", "https://yuanjava.com");
res.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
res.setHeader("Access-Control-Allow-Headers", "Content-Type");
res.setHeader("Access-Control-Allow-Credentials", "true");
if ("OPTIONS".equalsIgnoreCase(((HttpServletRequest) request).getMethod())) {
res.setStatus(HttpServletResponse.SC_OK);
return;
}
chain.doFilter(request, response);
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void destroy() {
}
}
代碼分析:
- setHeader("Access-Control-Allow-Origin", "https://yuanjava.com"): 設置允許跨域的來源。
- setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE"): 設置允許的HTTP方法。
- setHeader("Access-Control-Allow-Headers", "Content-Type"): 設置允許的請求頭。
- setHeader("Access-Control-Allow-Credentials", "true"): 允許發送Cookie。
對于OPTIONS預檢請求,直接返回狀態碼200。
三、示例展示
假設我們有一個簡單的 Spring Boot應用程序,它提供一個 RESTful API。我們希望允許來自"https://yuanjava.com"的跨域請求。
1.項目結構
src
└── main
├── java
│ └── com
│ └── yuanjava
│ ├── CorsFilter.java
│ ├── MyController.java
│ └── WebConfig.java
└── resources
└── application.properties
2.代碼實現
- WebConfig.java: 全局配置CORS
- MyController.java: 使用@CrossOrigin注解
- CorsFilter.java: 自定義過濾器
3.測試跨域請求
可以使用Postman或編寫簡單的JavaScript代碼來測試跨域請求。
fetch('http://localhost:8080/greet', {
method: 'GET',
headers: {
'Content-Type': 'application/json'
},
credentials: 'include'
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
4.驗證
- 啟動Spring Boot應用程序。
- 通過瀏覽器或Postman測試API。
- 確認跨域請求成功,并在控制臺或日志中查看請求和響應。
四、總結
通過本文,我們詳細探討了 Spring Boot解決跨域問題的三種方法,包括全局配置、使用注解和自定義過濾器。每種方法都有其優缺點,選擇哪種方式取決于應用的具體需求和復雜性。
- 全局配置: 適用于需要統一配置跨域策略的應用。
- @CrossOrigin注解: 適合于特定控制器或方法的跨域配置。
- 自定義過濾器: 提供更靈活的跨域處理方式。