最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java 中的跨域問題解決方法

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

1、Java 中跨域問題的來源

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

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

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

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

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

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

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

1.2.2 微服務(wù)架構(gòu)

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

1.2.3 第三方API集成

調(diào)用外部服務(wù)如支付接口、地圖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默認(rèn)配置

Spring Security默認(rèn)啟用CSRF保護(hù)
會與CORS機(jī)制產(chǎn)生沖突

1.4.2 Servlet容器行為

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

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

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

1.5. 為什么需要Java端解決

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

1.6. 特殊注意事項(xiàng)

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

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

跨域問題是由于瀏覽器的同源策略(Same-Origin Policy)導(dǎo)致的,當(dāng)你的前端應(yīng)用(如運(yùn)行在 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);  // 預(yù)檢請求的緩存時間(秒)
    }
}

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

2.2.1 使用 Filter

/**
 * CORS跨域過濾器配置
 * 用于處理瀏覽器跨域請求的支持
 * 過濾器會攔截所有請求(/*)并添加CORS響應(yīng)頭
 */
@WebFilter("/*")  // 攔截所有請求
public class CorsFilter implements Filter {
    /**
     * 過濾器核心方法,處理請求和響應(yīng)
     * @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)的請求/響應(yīng)對象
        HttpServletResponse response = (HttpServletResponse) res;
        HttpServletRequest request = (HttpServletRequest) req;
        // 設(shè)置允許所有域訪問(生產(chǎn)環(huán)境應(yīng)替換為具體域名)
        response.setHeader("Access-Control-Allow-Origin", "*");
        // 設(shè)置允許的HTTP方法
        response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
        // 設(shè)置預(yù)檢請求的緩存時間(1小時)
        response.setHeader("Access-Control-Max-Age", "3600");
        // 設(shè)置允許的請求頭(包括自定義頭)
        response.setHeader("Access-Control-Allow-Headers", "authorization, content-type, xsrf-token");
        // 設(shè)置允許前端訪問的響應(yīng)頭(暴露自定義頭)
        response.addHeader("Access-Control-Expose-Headers", "xsrf-token");
        // 處理OPTIONS預(yù)檢請求
        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 解決方案

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

/**
 * Spring Security 安全配置類
 * 用于配置應(yīng)用的安全策略和CORS跨域設(shè)置
 */
@Configuration  // 標(biāo)記為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防護(hù)(跨站請求偽造),因?yàn)锳PI通常使用token驗(yàn)證而非session
            // 注意:如果前端與后端同域且使用session,應(yīng)該保持啟用
            .csrf().disable()  
            // 開始配置請求授權(quán)規(guī)則
            .authorizeRequests()
                // 允許/api/public/開頭的URL無需認(rèn)證
                .antMatchers("/api/public/**").permitAll()  
                // 其他所有請求都需要認(rèn)證
                .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"   // 預(yù)檢請求
        ));
        // 設(shè)置允許的請求頭(*表示所有)
        configuration.setAllowedHeaders(Arrays.asList("*"));
        // 允許發(fā)送憑據(jù)(cookie、認(rèn)證信息等)
        // 注意:當(dāng)設(shè)置為true時,allowedOrigins不能為*
        configuration.setAllowCredentials(true);
        // 創(chuàng)建基于URL的CORS配置源
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        // 對所有URL路徑應(yīng)用上述CORS配置
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }
}

2.4. 注意事項(xiàng)

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

2.5. 測試跨域是否成功

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

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

Spring Boot應(yīng)用推薦使用全局配置或Spring Security配置的方式。

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

相關(guān)文章

  • 解析java稀疏數(shù)組如何幫助我們節(jié)省內(nèi)存提升性能

    解析java稀疏數(shù)組如何幫助我們節(jié)省內(nèi)存提升性能

    這篇文章主要為大家介紹了java稀疏數(shù)組如何幫助我們節(jié)省內(nèi)存提升性能解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-11-11
  • SpringBoot多數(shù)據(jù)庫連接(mysql+oracle)的實(shí)現(xiàn)

    SpringBoot多數(shù)據(jù)庫連接(mysql+oracle)的實(shí)現(xiàn)

    這篇文章主要介紹了SpringBoot多數(shù)據(jù)庫連接(mysql+oracle)的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • IDEA社區(qū)版創(chuàng)建spring boot項(xiàng)目的安裝插件的圖文教程

    IDEA社區(qū)版創(chuàng)建spring boot項(xiàng)目的安裝插件的圖文教程

    這篇文章主要介紹了IDEA社區(qū)版創(chuàng)建spring boot項(xiàng)目的安裝插件,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-11-11
  • Spring?Boot數(shù)據(jù)響應(yīng)問題實(shí)例詳解

    Spring?Boot數(shù)據(jù)響應(yīng)問題實(shí)例詳解

    這篇文章主要給大家介紹了關(guān)于Spring?Boot數(shù)據(jù)響應(yīng)問題的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2022-03-03
  • Java原子變量類常見問題解決

    Java原子變量類常見問題解決

    這篇文章主要介紹了Java原子變量類常見問題解決,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-03-03
  • Java使用easyExcel實(shí)現(xiàn)Excel文件解析

    Java使用easyExcel實(shí)現(xiàn)Excel文件解析

    這篇文章主要為大家詳細(xì)介紹了Java如何使用easyExcel實(shí)現(xiàn)Excel文件解析,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2025-02-02
  • Java中Json與List、Map、entity的互相轉(zhuǎn)化

    Java中Json與List、Map、entity的互相轉(zhuǎn)化

    在開發(fā)中,Json轉(zhuǎn)換的場景往往也就是那么幾個,本文主要介紹了Java中Json與List、Map、entity的互相轉(zhuǎn)化,具有一定的參考價值,感興趣的可以了解一下
    2022-07-07
  • Java?C++題解leetcode764最大加號標(biāo)志示例

    Java?C++題解leetcode764最大加號標(biāo)志示例

    這篇文章主要為大家介紹了Java?C++題解leetcode764最大加號標(biāo)志示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-01-01
  • springboot如何獲取文件流

    springboot如何獲取文件流

    這篇文章主要介紹了springboot如何獲取文件流,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • 詳解Java中的Lambda表達(dá)式

    詳解Java中的Lambda表達(dá)式

    這篇文章主要介紹了Java中的Lambda表達(dá)式的的相關(guān)資料,文中講解非常詳細(xì),示例代碼幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-06-06

最新評論

镇赉县| 泰安市| 玉树县| 兖州市| 老河口市| 新巴尔虎右旗| 来安县| 清水河县| 白河县| 盐津县| 内乡县| 攀枝花市| 蓬莱市| 凤翔县| 黑龙江省| 永康市| 鹰潭市| 徐闻县| 深圳市| 阳朔县| 铜川市| 嘉义县| 金昌市| 深圳市| 抚宁县| 中山市| 揭西县| 吉安县| 德令哈市| 镇远县| 五莲县| 邯郸市| 繁昌县| 乐亭县| 安国市| 兰州市| 新沂市| 千阳县| 漠河县| 卓尼县| 山东省|