亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Java 中的跨域問題解決方法

 更新時間:2025年05月27日 15:17:04   作者:喜歡單調(diào)  
跨域問題本質(zhì)上是瀏覽器的一種安全機制,與Java本身無關(guān),但Java后端開發(fā)者需要理解其來源以便正確解決,下面給大家介紹Java 中的跨域問題解決方法,感興趣的朋友一起看看吧

1、Java 中跨域問題的來源

跨域問題(Cross-Origin Resource Sharing, CORS)本質(zhì)上是瀏覽器的一種安全機制,與Java本身無關(guān),但Java后端開發(fā)者需要理解其來源以便正確解決。以下是跨域問題的詳細來源分析:

1.1. 瀏覽器同源策略(Same-Origin Policy)

  • 根本來源:瀏覽器出于安全考慮實施的同源策略
  • 同源定義:協(xié)議(http/https)+域名+端口三者完全相同
  • 限制內(nèi)容:限制不同源的DOM訪問,限制不同源的AJAX請求,限制不同源的Cookie/LocalStorage訪問

1.2. Java后端常見的跨域觸發(fā)場景

1.2.1 前后端分離架構(gòu)

開發(fā)時前端與后端運行在不同端口

生產(chǎn)環(huán)境前端與后端可能部署在不同域名下

1.2.2 微服務架構(gòu)

網(wǎng)關(guān)與服務可能在不同域
服務間調(diào)用也可能涉及跨域

1.2.3 第三方API集成

調(diào)用外部服務如支付接口、地圖API等

1.3. Java中具體的跨域表現(xiàn)

1.3.1 典型錯誤

Access to XMLHttpRequest at 'http://api.example.com' from origin 'http://frontend.com' 
has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present 
on the requested resource.

1.3.2 觸發(fā)條件

1.4. Java特有的跨域問題來源

1.4.1 Spring Security默認配置

Spring Security默認啟用CSRF保護
會與CORS機制產(chǎn)生沖突

1.4.2 Servlet容器行為

Tomcat/Jetty等容器默認不帶CORS頭
過濾器鏈順序可能影響CORS處理

1.4.3 傳統(tǒng)Java Web應用

JSP時代頁面和后端同源,現(xiàn)代前后端分離導致問題顯現(xiàn)

1.5. 為什么需要Java端解決

瀏覽器行為不可控:同源策略是瀏覽器強制實施的
安全責任在后端:哪些源可以訪問應由后端決定
靈活控制需求:不同接口可能需要不同的跨域策略

1.6. 特殊注意事項

Cookie跨域:需要設(shè)置Access-Control-Allow-Credentials: true
自定義頭跨域:需在Access-Control-Allow-Headers中聲明
緩存問題:合理設(shè)置Access-Control-Max-Age提高性能

2、Java 中解決跨域問題的方法

跨域問題是由于瀏覽器的同源策略(Same-Origin Policy)導致的,當你的前端應用(如運行在 http://localhost:8080)嘗試訪問不同源(如 http://api.example.com)的后端API時,瀏覽器會阻止這種請求。以下是Java中常見的跨域解決方案:

2.1. Spring Boot 解決方案

2.1.1 使用 @CrossOrigin 注解

@RestController
@RequestMapping("/api")
public class MyController {
    // 允許單個方法跨域
    @CrossOrigin(origins = "http://localhost:3000")
    @GetMapping("/hello")
    public String hello() {
        return "Hello, CORS!";
    }
    // 允許整個控制器跨域
    @CrossOrigin(origins = "http://localhost:3000")
    @GetMapping("/another")
    public String another() {
        return "Another endpoint";
    }
}

2.1.2 全局配置跨域

@Configuration
public class CorsConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")  // 所有路徑
                .allowedOrigins("http://localhost:3000", "https://example.com")  // 允許的源
                .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")  // 允許的方法
                .allowedHeaders("*")  // 允許的請求頭
                .allowCredentials(true)  // 允許攜帶憑證(cookie等)
                .maxAge(3600);  // 預檢請求的緩存時間(秒)
    }
}

2.2. 傳統(tǒng) Servlet 解決方案

2.2.1 使用 Filter

/**
 * CORS跨域過濾器配置
 * 用于處理瀏覽器跨域請求的支持
 * 過濾器會攔截所有請求(/*)并添加CORS響應頭
 */
@WebFilter("/*")  // 攔截所有請求
public class CorsFilter implements Filter {
    /**
     * 過濾器核心方法,處理請求和響應
     * @param req ServletRequest對象
     * @param res ServletResponse對象
     * @param chain FilterChain對象,用于繼續(xù)過濾器鏈
     */
    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) 
            throws IOException, ServletException {
        // 類型轉(zhuǎn)換為HTTP相關(guān)的請求/響應對象
        HttpServletResponse response = (HttpServletResponse) res;
        HttpServletRequest request = (HttpServletRequest) req;
        // 設(shè)置允許所有域訪問(生產(chǎn)環(huán)境應替換為具體域名)
        response.setHeader("Access-Control-Allow-Origin", "*");
        // 設(shè)置允許的HTTP方法
        response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
        // 設(shè)置預檢請求的緩存時間(1小時)
        response.setHeader("Access-Control-Max-Age", "3600");
        // 設(shè)置允許的請求頭(包括自定義頭)
        response.setHeader("Access-Control-Allow-Headers", "authorization, content-type, xsrf-token");
        // 設(shè)置允許前端訪問的響應頭(暴露自定義頭)
        response.addHeader("Access-Control-Expose-Headers", "xsrf-token");
        // 處理OPTIONS預檢請求
        if ("OPTIONS".equals(request.getMethod())) {
            // 直接返回200狀態(tài)碼,不繼續(xù)過濾器鏈
            response.setStatus(HttpServletResponse.SC_OK);
        } else {
            // 非OPTIONS請求,繼續(xù)過濾器鏈
            chain.doFilter(req, res);
        }
    }
    /**
     * 過濾器初始化方法(可留空)
     * @param filterConfig 過濾器配置對象
     */
    @Override 
    public void init(FilterConfig filterConfig) {
        // 初始化邏輯(如有需要)
    }
    /**
     * 過濾器銷毀方法(可留空)
     */
    @Override 
    public void destroy() {
        // 清理資源邏輯(如有需要)
    }
}

2.3. Spring Security 解決方案

如果你的應用使用了Spring Security,需要在安全配置中添加CORS支持:

/**
 * Spring Security 安全配置類
 * 用于配置應用的安全策略和CORS跨域設(shè)置
 */
@Configuration  // 標記為Spring配置類
@EnableWebSecurity  // 啟用Spring Security的Web安全支持
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    /**
     * 配置HTTP安全策略
     * @param http HttpSecurity對象,用于配置安全策略
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            // 啟用CORS支持(使用下面定義的corsConfigurationSource bean)
            .cors().and()  
            // 禁用CSRF防護(跨站請求偽造),因為API通常使用token驗證而非session
            // 注意:如果前端與后端同域且使用session,應該保持啟用
            .csrf().disable()  
            // 開始配置請求授權(quán)規(guī)則
            .authorizeRequests()
                // 允許/api/public/開頭的URL無需認證
                .antMatchers("/api/public/**").permitAll()  
                // 其他所有請求都需要認證
                .anyRequest().authenticated();
    }
    /**
     * 配置CORS跨域設(shè)置
     * @return CorsConfigurationSource 跨域配置源
     */
    @Bean
    public CorsConfigurationSource corsConfigurationSource() {
        // 創(chuàng)建CORS配置對象
        CorsConfiguration configuration = new CorsConfiguration();
        // 設(shè)置允許的源(前端地址),可以添加多個
        configuration.setAllowedOrigins(Arrays.asList("http://localhost:3000"));
        // 設(shè)置允許的HTTP方法
        configuration.setAllowedMethods(Arrays.asList(
            "GET",      // 獲取資源
            "POST",     // 創(chuàng)建資源
            "PUT",      // 更新資源
            "DELETE",   // 刪除資源
            "OPTIONS"   // 預檢請求
        ));
        // 設(shè)置允許的請求頭(*表示所有)
        configuration.setAllowedHeaders(Arrays.asList("*"));
        // 允許發(fā)送憑據(jù)(cookie、認證信息等)
        // 注意:當設(shè)置為true時,allowedOrigins不能為*
        configuration.setAllowCredentials(true);
        // 創(chuàng)建基于URL的CORS配置源
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        // 對所有URL路徑應用上述CORS配置
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }
}

2.4. 注意事項

生產(chǎn)環(huán)境:不要使用 * 作為允許的源,應該明確指定允許的域名
憑證:如果前端需要發(fā)送cookie等憑證信息,需要設(shè)置 allowCredentials(true),并且不能使用 * 作為允許的源
預檢請求:對于復雜請求(如帶自定義頭的請求),瀏覽器會先發(fā)送OPTIONS預檢請求
緩存:合理設(shè)置 maxAge 可以減少預檢請求的次數(shù)

2.5. 測試跨域是否成功

在瀏覽器開發(fā)者工具中檢查響應頭是否包含:

Access-Control-Allow-Origin: http://your-frontend-domain
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: content-type

Spring Boot應用推薦使用全局配置或Spring Security配置的方式。

到此這篇關(guān)于Java 中的跨域問題的文章就介紹到這了,更多相關(guān)Java 跨域內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • idea?intellij快速修復if語句缺少大括號的問題

    idea?intellij快速修復if語句缺少大括號的問題

    這篇文章主要介紹了idea?intellij快速修復if語句缺少大括號的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-04-04
  • Java中抓取 Thread Dumps 的方式匯總

    Java中抓取 Thread Dumps 的方式匯總

    Thread dumps(線程轉(zhuǎn)儲)能幫助我們判斷 CPU 峰值、死鎖、內(nèi)存異常、應用反應遲鈍、響應時間變長和其他系統(tǒng)問題。在這篇文章當中,總結(jié)了7中抓取 Java Thread Dumps 文件的方式,分享給大家,希望對大家學習Java能夠有所幫助。
    2016-06-06
  • SpringBoot整合Log4j2實現(xiàn)自定義日志打印失效的原因及解決

    SpringBoot整合Log4j2實現(xiàn)自定義日志打印失效的原因及解決

    本文給大家介紹了關(guān)于SpringBoot項目整合Log4j2實現(xiàn)自定義日志打印失效原因及解決辦法,主要的原因是因為SpringBoot的logback包的存在,文中通過圖文給大家了詳細解決方法,需要的朋友可以參考下
    2024-01-01
  • SpringMVC---配置與使用的示例

    SpringMVC---配置與使用的示例

    這篇文章主要介紹了SpringMVC---配置與使用的示例,幫助大家更好的理解和學習spring框架,感興趣的朋友可以了解下
    2020-10-10
  • Spring框架中@PostConstruct注解詳解

    Spring框架中@PostConstruct注解詳解

    在Spring項目經(jīng)常遇到@PostConstruct注解,下面這篇文章主要給大家介紹了關(guān)于Spring框架中@PostConstruct注解的相關(guān)資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-07-07
  • springboot集成RestTemplate及常見的用法說明

    springboot集成RestTemplate及常見的用法說明

    這篇文章主要介紹了springboot集成RestTemplate及常見的用法說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • Spring中的AutowireCandidateResolver的具體使用詳解

    Spring中的AutowireCandidateResolver的具體使用詳解

    這篇文章主要介紹了Spring中的AutowireCandidateResolver的具體使用詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-04-04
  • Springboot重寫addInterceptors()方法配置攔截器實例

    Springboot重寫addInterceptors()方法配置攔截器實例

    這篇文章主要介紹了Springboot重寫addInterceptors()方法配置攔截器實例,spring?boot拋棄了復雜的xml配置,我們可以自定義配置類(標注@Configuration注解的類)來實現(xiàn)WebMvcConfigurer接口,并重寫addInterceptors()方法來配置攔截器,需要的朋友可以參考下
    2023-09-09
  • Go并發(fā)編程中使用channel的方法

    Go并發(fā)編程中使用channel的方法

    本文給大家介紹Go并發(fā)編程中使用channel的方法,通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2021-11-11
  • 詳解Java數(shù)據(jù)庫連接池

    詳解Java數(shù)據(jù)庫連接池

    今天繼續(xù)Java的課題,兩天沒有做任何事情,過了個自在的周末,但是不知道為什么總是有點淡淡的憂桑.之前游戲服務器的數(shù)據(jù)源使用的是阿里巴巴的Druid,今天就大概說說數(shù)據(jù)源,給個實例,需要的朋友可以參考下
    2021-06-06

最新評論