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

Springboot解決跨域問(wèn)題的實(shí)現(xiàn)方案

 更新時(shí)間:2026年01月07日 10:32:16   作者:不如打代碼KK  
本文從跨域的本質(zhì)(同源策略)出發(fā),系統(tǒng)講解SpringBoot中5種主流跨域方案,每個(gè)方案包含原理解析+可運(yùn)行代碼+適用場(chǎng)景,幫你徹底解決跨域問(wèn)題,感興趣的朋友跟隨小編一起看看吧

Springboot如何解決跨域問(wèn)題?

在前后端分離架構(gòu)中,跨域問(wèn)題是Java開(kāi)發(fā)者繞不開(kāi)的“基礎(chǔ)門檻”。本文從跨域的本質(zhì)(同源策略)出發(fā),系統(tǒng)講解SpringBoot中5種主流跨域方案,每個(gè)方案包含原理解析+可運(yùn)行代碼+適用場(chǎng)景,幫你徹底解決跨域問(wèn)題。

一、先搞懂:為什么會(huì)有跨域?

跨域的根源是瀏覽器的同源策略(Same-Origin Policy)——這是瀏覽器的安全機(jī)制,要求請(qǐng)求的“源”必須與當(dāng)前頁(yè)面的“源”完全一致,才允許交互。也就是說(shuō)在兩個(gè)后端之間互相調(diào)用接口是沒(méi)有跨域問(wèn)題的。

1.1 同源的定義

“源”由三部分組成,三者完全相同才叫“同源”:

  • 協(xié)議(如http/https
  • 域名(如localhost/www.xxx.com
  • 端口(如8080/8090

示例:當(dāng)前頁(yè)面是http://localhost:8080,以下請(qǐng)求會(huì)被判定為跨域:

  • https://localhost:8080(協(xié)議不同)
  • http://127.0.0.1:8080(域名不同)
  • http://localhost:8090(端口不同)

1.2 跨域的表現(xiàn)

瀏覽器會(huì)攔截跨域請(qǐng)求,控制臺(tái)拋出類似錯(cuò)誤:

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

二、方案1:JSONP(基本不用)

JSONP是早期跨域方案,前端后端需要同時(shí)更改,需要增加一個(gè)callback請(qǐng)求參數(shù),當(dāng)然這個(gè)callback參數(shù)也可以自定義。

2.1 原理

  1. 前端通過(guò)<script>標(biāo)簽請(qǐng)求后端接口,傳遞回調(diào)函數(shù)名(如callback=handleData);
  2. 后端將數(shù)據(jù)包裹在回調(diào)函數(shù)中返回(如handleData({"msg":"success"}));
  3. 前端提前定義回調(diào)函數(shù),接收并處理數(shù)據(jù)。

2.2 實(shí)戰(zhàn)代碼

后端接口
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class JsonpController {
    /**
     * JSONP接口:接收前端傳遞的callback參數(shù),返回包裹后的JSON
     */
    @GetMapping("/info")
    public String jsonpInfo(@RequestParam String callback) {
        // 模擬返回的數(shù)據(jù)(比如根據(jù)id=16查詢到的信息)
        String data = "{\"code\":200,\"msg\":\"success\",\"data\":{\"id\":16,\"name\":\"測(cè)試數(shù)據(jù)\",\"desc\":\"JSONP跨域示例\"}}";
        // 拼接JSONP格式的響應(yīng)(回調(diào)函數(shù)名 + 數(shù)據(jù))
        return callback + "(" + data + ")";
    }
}
前端測(cè)試
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>jQuery Ajax JSONP跨域示例</title>
    <!-- 引入jQuery -->
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.min.js"></script>
</head>
<body>
<button id="submitBtn">發(fā)起JSONP請(qǐng)求</button>

<script>
    $("#submitBtn").click(function () {
        $.ajax({
            url: 'http://localhost:8080/info?id=16', // 后端接口地址(帶參數(shù)id=16)
            type: 'GET', // JSONP僅支持GET請(qǐng)求
            dataType: 'jsonp', // 關(guān)鍵:指定數(shù)據(jù)類型為jsonp
            jsonp: 'callback', // 告訴后端:前端用callback參數(shù)傳遞回調(diào)函數(shù)名(默認(rèn)就是callback,可省略)
            success: function (response) {
                // 成功接收后端返回的數(shù)據(jù)
                console.log("JSONP請(qǐng)求成功,返回?cái)?shù)據(jù):", response);
                alert("請(qǐng)求成功!數(shù)據(jù)ID:" + response.data.id + ",名稱:" + response.data.name);
            },
            error: function (err) {
                console.error("JSONP請(qǐng)求失?。?, err);
                alert("請(qǐng)求失敗,請(qǐng)檢查控制臺(tái)");
            }
        });
    });
</script>
</body>
</html>

2.3 適用場(chǎng)景

僅適用于簡(jiǎn)單GET請(qǐng)求,或需要兼容老舊瀏覽器(如IE)的場(chǎng)景,不推薦現(xiàn)代項(xiàng)目使用。

三、方案2:全局配置(WebMvcConfigurer)

這是SpringBoot中最常用、最優(yōu)雅的跨域方案,通過(guò)配置全局CORS規(guī)則實(shí)現(xiàn)。

3.1 原理

基于W3C的CORS標(biāo)準(zhǔn),服務(wù)端通過(guò)響應(yīng)頭告知瀏覽器“允許哪些源的請(qǐng)求”,核心響應(yīng)頭包括:

  • Access-Control-Allow-Origin:允許的跨域源;
  • Access-Control-Allow-Methods:允許的請(qǐng)求方法;
  • Access-Control-Allow-Credentials:是否允許攜帶Cookie。

3.2 實(shí)戰(zhàn)代碼

全局配置類
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("/**") // 匹配所有接口
                .allowedOriginPatterns("*") // 允許所有源(生產(chǎn)環(huán)境建議指定域名)
                .allowedMethods("GET", "POST", "PUT", "DELETE") // 允許的請(qǐng)求方法
                .allowedHeaders("*") // 允許所有請(qǐng)求頭
                .allowCredentials(true) // 允許攜帶Cookie
                .maxAge(3600); // 預(yù)檢請(qǐng)求緩存1小時(shí)
    }
}
測(cè)試接口
@RestController
public class TestController {
    @GetMapping("/api/test/get")
    public String testGet() {
        return "GET跨域成功";
    }

    @PostMapping("/api/test/post")
    public String testPost(@RequestBody String data) {
        return "POST跨域成功,接收:" + data;
    }
}
前端測(cè)試(Axios)
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<button onclick="axios.get('http://localhost:8080/api/test/get').then(res=>alert(res.data))">測(cè)試GET</button>
<button onclick="axios.post('http://localhost:8080/api/test/post', {name:'張三'}).then(res=>alert(res.data))">測(cè)試POST</button>

3.3 適用場(chǎng)景

前后端分離的現(xiàn)代項(xiàng)目,推薦作為默認(rèn)方案使用。

四、方案3:CorsFilter(官方Filter方案)

通過(guò)Spring官方的CorsFilter實(shí)現(xiàn)跨域,比手動(dòng)寫(xiě)Filter更規(guī)范、更靈活。

4.1 原理

CorsFilter是Spring封裝的CORS過(guò)濾器,通過(guò)CorsConfiguration配置規(guī)則,再綁定到指定路徑,自動(dòng)攔截請(qǐng)求并添加跨域響應(yīng)頭。

4.2 實(shí)戰(zhàn)代碼

配置類
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

import java.util.Collections;

@Configuration
public class CorsFilterConfig {
    @Bean
    public CorsFilter corsFilter() {
        // 1. 配置跨域規(guī)則
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowedOriginPatterns(Collections.singletonList("*"));
        config.addAllowedHeader(CorsConfiguration.ALL);
        config.addAllowedMethod(CorsConfiguration.ALL);
        config.setAllowCredentials(true);
        config.setMaxAge(3600L);

        // 2. 綁定路徑
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", config); // 所有路徑應(yīng)用規(guī)則

        // 3. 返回CorsFilter
        return new CorsFilter(source);
    }
}

4.3 適用場(chǎng)景

需要更靈活的跨域邏輯(如動(dòng)態(tài)調(diào)整跨域規(guī)則),或項(xiàng)目中已使用Filter鏈的場(chǎng)景。

五、方案4:局部配置(@CrossOrigin注解)

僅為個(gè)別接口/Controller配置跨域,優(yōu)先級(jí)高于全局配置。

5.1 原理

@CrossOrigin是Spring提供的注解,底層基于CORS機(jī)制,為標(biāo)注的接口自動(dòng)添加跨域響應(yīng)頭。

5.2 實(shí)戰(zhàn)代碼

單個(gè)接口配置
@RestController
public class CrossOriginController {
    @CrossOrigin(origins = "*", maxAge = 3600)
    @GetMapping("/api/cross/test")
    public String crossTest() {
        return "單個(gè)接口跨域成功";
    }
}
Controller級(jí)配置
@CrossOrigin(origins = "http://localhost:8080") // 僅允許8080源
@RestController
public class CrossOriginController2 {
    @GetMapping("/api/cross/test2")
    public String crossTest2() {
        return "Controller級(jí)跨域成功";
    }
}

5.3 適用場(chǎng)景

個(gè)別接口需要單獨(dú)配置跨域的場(chǎng)景,不推薦全局使用。

六、方案對(duì)比與選型建議

方案適用場(chǎng)景優(yōu)點(diǎn)缺點(diǎn)
JSONP簡(jiǎn)單GET請(qǐng)求、兼容老舊瀏覽器實(shí)現(xiàn)簡(jiǎn)單僅支持GET、有安全風(fēng)險(xiǎn)
WebMvcConfigurer前后端分離全局跨域優(yōu)雅簡(jiǎn)潔、易維護(hù)靈活性稍弱
CorsFilter復(fù)雜跨域規(guī)則、Filter鏈場(chǎng)景靈活可控、官方規(guī)范代碼量略多
@CrossOrigin個(gè)別接口/Controller跨域局部配置、無(wú)需全局修改不適合全局場(chǎng)景

到此這篇關(guān)于Springboot解決跨域問(wèn)題的實(shí)現(xiàn)方案的文章就介紹到這了,更多相關(guān)Springboot跨域內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java中四種9*9乘法表的實(shí)現(xiàn)方式(附代碼)

    Java中四種9*9乘法表的實(shí)現(xiàn)方式(附代碼)

    這篇文章主要介紹了Java中四種9*9乘法表的實(shí)現(xiàn)方式(附代碼),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11
  • Spring?中?PageHelper?不生效問(wèn)題及解決方法

    Spring?中?PageHelper?不生效問(wèn)題及解決方法

    這篇文章主要介紹了Spring?中?PageHelper?不生效問(wèn)題,使用這個(gè)插件時(shí)要注意版本的問(wèn)題,不同的版本可能 PageHelper 不會(huì)生效,本文結(jié)合示例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2022-12-12
  • mybatis實(shí)現(xiàn)獲取入?yún)⑹荓ist和Map的取值

    mybatis實(shí)現(xiàn)獲取入?yún)⑹荓ist和Map的取值

    這篇文章主要介紹了mybatis實(shí)現(xiàn)獲取入?yún)⑹荓ist和Map的取值問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-06-06
  • MyBatis動(dòng)態(tài)<if>標(biāo)簽使用避坑指南

    MyBatis動(dòng)態(tài)<if>標(biāo)簽使用避坑指南

    這篇文章主要為大家介紹了MyBatis動(dòng)態(tài)<if>標(biāo)簽使用避坑指南,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-03-03
  • 關(guān)于druid連接池的使用詳解

    關(guān)于druid連接池的使用詳解

    文章介紹了Druid連接池的兩種使用方式:直接在代碼中配置和通過(guò)配置文件配置,同時(shí),文章詳細(xì)講解了如何在Web項(xiàng)目中啟用Druid的監(jiān)控功能,包括配置web.xml文件、設(shè)置過(guò)濾器等步驟,最后,文章還提到了Druid提供的加密解密工具,使數(shù)據(jù)庫(kù)密碼更安全
    2025-02-02
  • Java自定義異常與異常使用的最佳方式

    Java自定義異常與異常使用的最佳方式

    這篇文章主要介紹了Java自定義異常與異常使用的最佳方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • Java內(nèi)存映射 大文件輕松處理

    Java內(nèi)存映射 大文件輕松處理

    這篇文章主要介紹了Java內(nèi)存映射 大文件輕松處理,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-08-08
  • java時(shí)間日期使用與查詢代碼詳解

    java時(shí)間日期使用與查詢代碼詳解

    這篇文章主要介紹了java時(shí)間日期使用與查詢代碼詳解,具有一定借鑒價(jià)值,需要的朋友可以參考下。
    2017-11-11
  • java多線程復(fù)制文件的實(shí)例代碼

    java多線程復(fù)制文件的實(shí)例代碼

    java多線程復(fù)制文件的實(shí)例代碼,需要的朋友可以參考一下
    2013-03-03
  • Java中如何將json字符串轉(zhuǎn)換成map/list

    Java中如何將json字符串轉(zhuǎn)換成map/list

    這篇文章主要介紹了Java中如何將json字符串轉(zhuǎn)換成map/list,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-07-07

最新評(píng)論

天祝| 梁河县| 青龙| 彭水| 霸州市| 蒙阴县| 库尔勒市| 饶平县| 英超| 遂宁市| 靖江市| 潜江市| 会泽县| 迁西县| 桐城市| 乃东县| 马尔康县| 化德县| 右玉县| 金堂县| 噶尔县| 丰宁| 略阳县| 涟水县| 平和县| 泌阳县| 那坡县| 洪湖市| 准格尔旗| 商城县| 恩施市| 奉节县| 子洲县| 孝感市| 北辰区| 中江县| 抚顺市| 泾阳县| 沁源县| 府谷县| 永康市|