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

SpringBoot使用CORS解決無法跨域訪問問題的具體步驟

 更新時間:2025年05月14日 09:17:00   作者:柯南二號  
跨域問題指的是不同站點之間,使用 ajax 無法相互調(diào)用的問題,跨域問題本質(zhì)是瀏覽器的一種保護機制,它的初衷是為了保證用戶的安全,防止惡意網(wǎng)站竊取數(shù)據(jù),本文給大家介紹了SpringBoot使用CORS解決無法跨域訪問問題的具體步驟,需要的朋友可以參考下

一、跨域問題

跨域問題指的是不同站點之間,使用 ajax 無法相互調(diào)用的問題??缬騿栴}本質(zhì)是瀏覽器的一種保護機制,它的初衷是為了保證用戶的安全,防止惡意網(wǎng)站竊取數(shù)據(jù)。但這個保護機制也帶來了新的問題,它的問題是給不同站點之間的正常調(diào)用,也帶來的阻礙,那怎么解決這個問題呢?接下來我們一起來看。

跨域三種情況

在請求時,如果出現(xiàn)了以下情況中的任意一種,那么它就是跨域請求:

  • 協(xié)議不同,如 http 和 https;
  • 域名不同;
  • 端口不同。

也就是說,即使域名相同,如果一個使用的是 http,另一個使用的是 https,那么它們也屬于跨域訪問。常見的跨域問題如下圖所示:

場景編號當(dāng)前頁面地址(發(fā)起方)資源地址(目標(biāo)方)是否跨域原因說明
1http://example.comhttp://example.com協(xié)議、域名、端口都相同
2http://example.comhttps://example.com協(xié)議不同
3http://example.comhttp://example.com:8080端口不同
4http://example.comhttp://sub.example.com子域名不同
5http://example.comhttp://example.org主域名不同
6http://example.comhttp://example.com/path/page僅路徑不同,不構(gòu)成跨域
7http://127.0.0.1http://localhost雖然都是本地,但域名不同
8http://localhost:3000http://localhost:4000端口不同
9http://a.example.comhttp://b.example.com子域名不同
10https://example.comhttps://example.com協(xié)議、域名、端口都相同

跨域的核心判斷標(biāo)準(zhǔn)是:協(xié)議(scheme)、主機(host)、端口(port)三者中有任意一個不同即為跨域。

二、跨域解決方案

在Spring Boot中,可以使用CORS(跨源資源共享,Cross-Origin Resource Sharing)來解決前端請求接口時出現(xiàn)的跨域問題。Spring Boot 提供了多種方式來配置 CORS,以下是幾種常見的解決方式:

方法一:使用 @CrossOrigin 注解(適用于單個控制器或方法)

import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/api")
@CrossOrigin(origins = "*") // 允許所有來源跨域訪問
public class MyController {

    @GetMapping("/data")
    public String getData() {
        return "Hello, CORS!";
    }
}

你也可以只在特定方法上添加:

@CrossOrigin(origins = "http://localhost:3000")
@GetMapping("/specific")
public String specificEndpoint() {
    return "This is CORS-enabled only for localhost:3000";
}

方法二:全局配置 CORS(推薦)

適合需要對整個項目的接口統(tǒng)一進行跨域配置。

方法 2.1:實現(xiàn) WebMvcConfigurer

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 CorsGlobalConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**") // 匹配所有請求路徑
                .allowedOrigins("*") // 允許所有來源
                .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") // 允許的方法
                .allowedHeaders("*") // 允許的請求頭
                .allowCredentials(true) // 是否允許攜帶cookie
                .maxAge(3600); // 預(yù)檢請求緩存時間(秒)
    }
}

allowedOrigins("*") 與 allowCredentials(true) 不可同時使用,若需攜帶 Cookie,需指定具體域名。

方法三:通過 Filter 自定義 CORS 過濾器

適用于更底層的控制(不推薦,除非有特殊需求)。

import javax.servlet.*;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
import java.io.IOException;

@Component
public class CorsFilter implements Filter {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {

        HttpServletResponse res = (HttpServletResponse) response;
        res.setHeader("Access-Control-Allow-Origin", "*");
        res.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
        res.setHeader("Access-Control-Allow-Headers", "*");
        res.setHeader("Access-Control-Allow-Credentials", "true");

        chain.doFilter(request, response);
    }
}

注意事項

  • 如果你使用了 spring-security,還需要在安全配置類中額外開啟 CORS。
  • @CrossOrigin 默認支持 GET/HEAD/POST,其他請求方法如 PUT/DELETE 需要手動配置。
  • 在生產(chǎn)環(huán)境下,不要使用 "\*" 通配符,應(yīng)明確指定允許的域名。

三、完整示例演示

寫一個完整的node.js前端出現(xiàn)要跨域訪問的時候,用SpringBoot的CORS()來解決跨域問題完整代碼實例。

3.1 創(chuàng)建前端的node.js服務(wù)

創(chuàng)建目錄

mkdir node-frontend && cd node-frontend

初始化

npm init -y

安裝依賴

npm install express node-fetch cors

新建一個index.js文件

const express = require('express');
const fetch = require('node-fetch');
const cors = require('cors');

const app = express();
const PORT = 3000;

app.use(cors()); // 允許前端頁面跨域訪問(如果需要)

// 前端頁面
app.get('/', (req, res) => {
  res.send(`
    <html>
      <body>
        <h2>Node.js Frontend</h2>
        <button onclick="callBackend()">Call Spring Boot API</button>
        <p id="result"></p>
        <script>
          function callBackend() {
            fetch('http://localhost:8080/api/hello', {
              method: 'GET',
              credentials: 'include'
            })
            .then(response => response.text())
            .then(data => {
              document.getElementById('result').innerText = data;
            })
            .catch(error => console.error('Error:', error));
          }
        </script>
      </body>
    </html>
  `);
});


app.listen(PORT, () => {
    console.log(`Frontend running at http://localhost:${PORT}`);
}); 

啟動node.js的服務(wù)

cd node-frontend
node index.js

訪問http://localhost:3000/,看到如下頁面

在沒有配置這個的時候,通過F12查看控制臺,點擊按鈕會提示如下信息:

3.2 創(chuàng)建后端的springboot服務(wù)

后端接口:HelloController.java

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/api")
public class HelloController {

    @GetMapping("/hello")
    public String hello() {
        return "Hello from Spring Boot!";
    }
}

跨域配置:CorsConfig.java

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 CorsConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("http://localhost:3000") // 只允許 node 前端
                .allowedMethods("GET", "POST", "OPTIONS", "DELETE")
                .allowCredentials(true);
    }
}

啟動springboot和node.js服務(wù)以后,再去訪問http://localhost:3000/,點擊下面這個按鈕,就會順利拿到后端返回的數(shù)據(jù)

四、CORS詳細解析

下面是對提到的 Spring Boot 跨域配置中每一項的詳細解釋:

registry.addMapping("/**")
        .allowedOrigins("http://localhost:3000") // 只允許來自該源的跨域請求
        .allowedMethods("GET", "POST", "OPTIONS", "DELETE") // 允許的 HTTP 方法
        .allowCredentials(true); // 允許攜帶憑證(如 Cookie)

逐項解釋

addMapping("/**")
  • 作用:設(shè)置哪些 URL 路徑可以被跨域請求訪問。
  • "/**" 表示對 所有接口 開啟跨域支持。
  • 示例:/api/hello/user/info 等都受此配置控制。

allowedOrigins("http://localhost:3000")

  • 作用:設(shè)置允許跨域請求的來源(origin),即前端運行的地址。
  • 瀏覽器發(fā)起跨域請求時會帶上 Origin 請求頭,Spring 會檢查它是否在這個列表中。
  • 示例:
    • 當(dāng)前設(shè)置只允許從 http://localhost:3000 發(fā)起的跨域請求。
    • 如果你用的是 React/Vite/Node.js 前端開發(fā)服務(wù)器,就很可能是這個端口。

注意:如果你使用 allowedOrigins("*") 通配所有來源,就不能使用 allowCredentials(true),否則瀏覽器會拒絕響應(yīng)。

allowedMethods("GET", "POST", "OPTIONS", "DELETE")

  • 作用:指定允許前端發(fā)起的 HTTP 方法。
  • 常見的跨域請求方法包括:
    • GET:獲取資源
    • POST:提交數(shù)據(jù)
    • OPTIONS:預(yù)檢請求(preflight),瀏覽器用于詢問服務(wù)器是否允許跨域
    • DELETE:刪除資源
  • 你也可以加上 "PUT""PATCH" 等方法,取決于你的 API 接口支持哪些。

allowCredentials(true)

  • 作用:允許前端在跨域請求中攜帶認證信息(如 Cookie、HTTP 認證頭)。

  • 如果你希望用戶登錄后發(fā)送帶 cookie 的請求(比如 JSESSIONID),必須設(shè)置為 true。

  • 配合前端的配置使用:

fetch("http://localhost:8080/api/hello", {
  credentials: "include"  // 必須設(shè)置這項才能帶上 Cookie
});

 **關(guān)鍵點:**當(dāng) allowCredentials(true) 時,allowedOrigins("*") 是不允許的,必須指定明確的 Origin。

allowedHeaders("*")

  • 作用:指定哪些請求頭(headers)是允許的跨域請求中使用的。
  • 默認情況下,瀏覽器不允許跨域請求攜帶自定義請求頭。使用 allowedHeaders 可以明確告訴 Spring Boot 服務(wù)器,允許哪些請求頭攜帶過來。

示例:

.allowedHeaders("*") // 允許所有請求頭
  • 這表示只有 Authorization 和 Content-Type 這兩個頭部字段可以在跨域請求中被使用。

例子:

假設(shè)你想在請求中添加一個自定義的 X-Auth-Token 頭部字段來驗證身份,那么你需要在服務(wù)器端配置允許這個頭部:

.allowedHeaders("X-Auth-Token")

maxAge(3600)

  • 作用:指定瀏覽器在進行 預(yù)檢請求(preflight) 時,緩存響應(yīng)的最大時間(單位:秒)。
  • 預(yù)檢請求是指在實際發(fā)起跨域請求之前,瀏覽器會先發(fā)送一個 OPTIONS 請求到目標(biāo)服務(wù)器,詢問是否允許跨域操作。服務(wù)器響應(yīng)該請求后,瀏覽器會根據(jù)返回的信息決定是否繼續(xù)發(fā)送實際的請求。

示例:

.maxAge(3600)  // 允許預(yù)檢請求的緩存時間為 3600 秒(即 1 小時)
  • 實際效果:如果預(yù)檢請求成功,瀏覽器會緩存該響應(yīng) 3600 秒,直到緩存過期才重新發(fā)送預(yù)檢請求。如果你有大量的跨域請求,增加緩存時間能夠減少預(yù)檢請求的頻繁發(fā)起,提高性能。

例子:

  • 如果你經(jīng)常發(fā)送跨域請求,而預(yù)檢請求(OPTIONS)非常頻繁,你可以通過增加 maxAge 來減少預(yù)檢請求的次數(shù),從而提高性能。
  • maxAge(3600) 表示預(yù)檢請求的響應(yīng)將在 1 小時內(nèi)緩存,不會再發(fā)送新的預(yù)檢請求。

綜合配置

根據(jù)上述的解釋,完整的跨域配置代碼可能是這樣的:

registry.addMapping("/**")
        .allowedOrigins("http://localhost:3000") // 只允許來自該源的跨域請求
        .allowedMethods("GET", "POST", "OPTIONS", "PUT", "DELETE") // 允許的 HTTP 方法
        .allowedHeaders("Content-Type", "Authorization", "X-Auth-Token") // 允許的請求頭
        .allowCredentials(true) // 允許攜帶憑證(如 Cookie)
        .maxAge(3600); // 預(yù)檢請求緩存 1 小時

總結(jié)配置最佳實踐

registry.addMapping("/**")
        .allowedOrigins("http://localhost:3000")  // 推薦明確指定前端地址
        .allowedMethods("GET", "POST", "OPTIONS", "PUT", "DELETE")
        .allowedHeaders("*")                      // 可選,允許前端發(fā)送的自定義 Header
        .allowCredentials(true)
        .maxAge(3600);                            // 可選,預(yù)檢請求的緩存時間(單位秒)

以上就是SpringBoot使用CORS解決無法跨域訪問問題的具體步驟的詳細內(nèi)容,更多關(guān)于SpringBoot CORS跨域訪問的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Java如何獲取屬性的注釋信息詳解

    Java如何獲取屬性的注釋信息詳解

    Java注解是從Java5開始添加到Java的,這篇文章主要給大家介紹了關(guān)于Java如何獲取屬性的注釋信息的相關(guān)資料,文中介紹的非常詳細,需要的朋友可以參考下
    2021-07-07
  • 詳解Spring Security中權(quán)限注解的使用

    詳解Spring Security中權(quán)限注解的使用

    這篇文章主要為大家詳細介紹一下Spring Security中權(quán)限注解的使用方法,文中的示例代碼講解詳細,對我們學(xué)習(xí)或工作有一定參考價值,需要的可以參考一下
    2022-05-05
  • Java如何將文件內(nèi)容轉(zhuǎn)換為MD5哈希值

    Java如何將文件內(nèi)容轉(zhuǎn)換為MD5哈希值

    這篇文章主要介紹了Java如何將文件內(nèi)容轉(zhuǎn)換為MD5哈希值的實現(xiàn)方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2025-05-05
  • java 遠程文件url如何轉(zhuǎn)為輸入流

    java 遠程文件url如何轉(zhuǎn)為輸入流

    這篇文章主要介紹了java 遠程文件url如何轉(zhuǎn)為輸入流方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • Java數(shù)組的初始化方法詳解

    Java數(shù)組的初始化方法詳解

    在Java程序開發(fā)中,數(shù)組是一個非常常用的數(shù)據(jù)類型,數(shù)組的初始化是使用數(shù)組來存儲和處理數(shù)據(jù)的關(guān)鍵步驟之一,但是,關(guān)于Java數(shù)組的初始化,經(jīng)常會讓人感到迷惑,本文將詳細介紹Java數(shù)組的初始化方法,幫助讀者從此告別關(guān)于Java數(shù)組初始化的困惑
    2023-11-11
  • 如何在java中正確使用注釋

    如何在java中正確使用注釋

    在編寫程序時,經(jīng)常需要添加一些注釋,用以描述某段代碼的作用。 一般來說,對于一份規(guī)范的程序源代碼而言,注釋應(yīng)該占到源代碼的 1/3 以上。下面我們來詳細了解一下吧
    2019-06-06
  • SpringCloud+Nacos實現(xiàn)環(huán)境切換與配置管理最佳實踐

    SpringCloud+Nacos實現(xiàn)環(huán)境切換與配置管理最佳實踐

    本文介紹了在SpringBoot項目中,如何通過SpringProfiles、Nacos配置中心及Maven構(gòu)建工具實現(xiàn)環(huán)境切換和配置管理,需要的朋友可以參考下
    2026-04-04
  • Java使用注解實現(xiàn)BigDecimal的四舍五入

    Java使用注解實現(xiàn)BigDecimal的四舍五入

    BigDecimal是Java中的一個類,位于java.math包中,它提供了任意精度的有符號十進制數(shù)字的表示,以及對這些數(shù)字進行算術(shù)運算的方法,本文介紹了Java使用注解實現(xiàn)BigDecimal的四舍五入的相關(guān)知識,需要的朋友可以參考下
    2024-09-09
  • 一篇文章讓你徹底了解Java可重入鎖和不可重入鎖

    一篇文章讓你徹底了解Java可重入鎖和不可重入鎖

    最近正在閱讀Java ReentrantLock源碼,始終對可重入和不可重入概念理解不透徹,今天特地整理了本篇文章,讓你徹底了解Java可重入鎖和不可重入鎖,需要的朋友可以參考下
    2021-06-06
  • java日期格式化SimpleDateFormat的使用詳解

    java日期格式化SimpleDateFormat的使用詳解

    這篇文章主要介紹了java SimpleDateFormat使用,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-05-05

最新評論

商河县| 西丰县| 潼关县| 鲜城| 长阳| 惠州市| 诸暨市| 阳谷县| 施甸县| 淳安县| 铜梁县| 永德县| 宁明县| 四平市| 双柏县| 土默特右旗| 阳江市| 太湖县| 双城市| 清远市| 仲巴县| 沙湾县| 大城县| 柳林县| 自治县| 丰城市| 南丹县| 河北区| 正安县| 绵阳市| 濮阳县| 韶关市| 泉州市| 玉门市| 昭通市| 阿尔山市| 共和县| 苍溪县| 泰兴市| 海安县| 高邮市|