溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么理解Spring Boot跨域

發布時間:2021-11-17 10:24:33 來源:億速云 閱讀:160 作者:iii 欄目:大數據
# 怎么理解Spring Boot跨域

## 一、什么是跨域問題

### 1.1 同源策略的概念
同源策略(Same-Origin Policy)是瀏覽器最核心的安全機制之一,它規定:
- 協議相同(http/https)
- 域名相同(www.example.com)
- 端口相同(8080)

只有三者完全一致才屬于同源,否則就會觸發跨域限制。這是瀏覽器為了防止惡意網站竊取數據而設置的安全屏障。

### 1.2 跨域的表現形式
當出現跨域請求時,瀏覽器控制臺會顯示類似錯誤:
```javascript
Access-Control-Allow-Origin' header is present on the requested resource

常見跨域場景包括: - 前端運行在http://localhost:3000,后端在http://localhost:8080 - 微服務架構中不同子域間的調用(api.service.com調用auth.service.com) - 前后端分離部署時的域名差異

二、Spring Boot解決跨域的四種方式

2.1 使用@CrossOrigin注解

最簡單的局部解決方案,支持方法級和類級配置:

@RestController
@CrossOrigin(origins = "http://example.com") // 類級別
public class MyController {
    
    @GetMapping("/hello")
    @CrossOrigin( // 方法級別
        origins = "*",
        allowedHeaders = "*",
        methods = {RequestMethod.GET, RequestMethod.POST}
    )
    public String hello() {
        return "Hello World";
    }
}

參數說明: - origins:允許的源列表(默認*) - methods:允許的HTTP方法 - allowedHeaders:允許的請求頭 - exposedHeaders:暴露給客戶端的響應頭 - allowCredentials:是否允許憑據(cookies等)

2.2 實現WebMvcConfigurer(全局配置)

推薦的生產環境方案,通過配置類統一管理:

@Configuration
public class CorsConfig implements WebMvcConfigurer {
    
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("https://trusted.com")
                .allowedMethods("GET", "POST", "PUT")
                .allowCredentials(true)
                .maxAge(3600);
    }
}

優勢: - 統一管理所有端點的CORS策略 - 支持預檢請求(OPTIONS)緩存 - 可結合Spring Security使用

2.3 使用Filter手動設置響應頭

適用于需要精細控制的場景:

@Component
public class SimpleCorsFilter implements Filter {
    
    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) 
        throws IOException, ServletException {
        
        HttpServletResponse response = (HttpServletResponse) res;
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
        
        chain.doFilter(req, res);
    }
}

關鍵響應頭: - Access-Control-Allow-Origin:允許的源 - Access-Control-Allow-Methods:允許的方法 - Access-Control-Allow-Headers:允許的請求頭 - Access-Control-Expose-Headers:暴露的響應頭 - Access-Control-Allow-Credentials:是否允許憑據

2.4 結合Spring Security配置

當項目啟用安全模塊時,需要特殊處理:

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.cors().configurationSource(request -> {
            CorsConfiguration config = new CorsConfiguration();
            config.applyPermitDefaultValues();
            config.addAllowedOrigin("https://secure-domain.com");
            return config;
        });
        
        // 其他安全配置...
    }
}

注意事項: - 必須顯式調用http.cors() - 默認會禁用allowCredentials - 需要處理CSRF與CORS的沖突

三、深入理解CORS機制

3.1 簡單請求 vs 預檢請求

簡單請求需同時滿足: 1. 使用GET、HEAD或POST方法 2. 僅包含自動設置的頭部(如Accept、Content-Language) 3. Content-Type為:text/plain、multipart/form-data或application/x-www-form-urlencoded

預檢請求(OPTIONS)觸發條件: - 使用PUT、DELETE等非簡單方法 - 包含自定義頭部(如Authorization) - Content-Type為application/json

3.2 完整CORS交互流程

  1. 瀏覽器發送OPTIONS預檢請求
  2. 服務器響應允許的源/方法/頭部
  3. 瀏覽器驗證通過后發送真實請求
  4. 服務器返回實際數據+ CORS頭部
sequenceDiagram
    Browser->>Server: OPTIONS /api (預檢請求)
    Server-->>Browser: 返回Allowed-Origin/Methods/Headers
    Browser->>Server: GET /api (真實請求)
    Server-->>Browser: 數據 + CORS頭

四、生產環境最佳實踐

4.1 安全配置建議

  1. 不要盲目使用*:應明確指定可信域名 “`java // 不安全 .allowedOrigins(”*“)

// 安全做法 .allowedOrigins(”https://production.com”, “https://staging.com”)


2. **啟用Credential時嚴格限制源**:
   ```java
   .allowCredentials(true)
   .allowedOrigins("https://exact.domain.com") // 不能使用*或通配符
  1. 限制暴露的頭部
    
    .exposedHeaders("X-Custom-Header", "Content-Disposition")
    

4.2 常見問題排查

問題1:配置了CORS但仍報錯 - 檢查是否有多個Filter覆蓋了CORS頭 - 確認Spring Security配置是否正確

問題2:預檢請求返回403 - 確保OPTIONS方法被允許 - 在Spring Security中配置:

  http.authorizeRequests().antMatchers(HttpMethod.OPTIONS).permitAll();

問題3:Cookie無法跨域 - 前端需要設置withCredentials: true - 后端配置:

  .allowCredentials(true)
  .allowedOriginPatterns("https://*.domain.com") // 注意使用allowedOriginPatterns而非allowedOrigins

五、擴展:替代解決方案

5.1 反向代理方案

通過Nginx統一域名:

location /api {
    proxy_pass http://backend:8080;
    add_header 'Access-Control-Allow-Origin' '$http_origin' always;
}

5.2 JSONP(僅限GET請求)

傳統跨域方案,已逐漸淘汰:

function handleResponse(data) {
    console.log(data);
}
const script = document.createElement('script');
script.src = 'http://other-domain.com/api?callback=handleResponse';
document.body.appendChild(script);

六、總結

Spring Boot提供了多層次、靈活的跨域解決方案,開發者應根據: - 項目架構復雜度 - 安全要求級別 - 部署環境特點

選擇最適合的方案。對于現代應用,推薦優先采用WebMvcConfigurer全局配置,配合細致的域名/方法限制,在保證安全的前提下實現跨域資源共享。

關鍵點記憶
- 開發環境可用*,生產環境必須指定具體域名
- 帶Credential的請求不能使用通配符
- Spring Security需要單獨配置
- 預檢請求的緩存能提升性能 “`

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女