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

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

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

一、跨域問題

跨域問題指的是不同站點(diǎn)之間,使用 ajax 無法相互調(diào)用的問題。跨域問題本質(zhì)是瀏覽器的一種保護(hù)機(jī)制,它的初衷是為了保證用戶的安全,防止惡意網(wǎng)站竊取數(shù)據(jù)。但這個保護(hù)機(jī)制也帶來了新的問題,它的問題是給不同站點(diǎn)之間的正常調(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)、主機(jī)(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(推薦)

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

方法 2.1:實(shí)現(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);
    }
}

注意事項(xiàng)

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

三、完整示例演示

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

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查看控制臺,點(diǎn)擊按鈕會提示如下信息:

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/,點(diǎn)擊下面這個按鈕,就會順利拿到后端返回的數(shù)據(jù)

四、CORS詳細(xì)解析

下面是對提到的 Spring Boot 跨域配置中每一項(xiàng)的詳細(xì)解釋:

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

逐項(xiàng)解釋

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

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

  • 作用:設(shè)置允許跨域請求的來源(origin),即前端運(yùn)行的地址。
  • 瀏覽器發(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)

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

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

  • 配合前端的配置使用:

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

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

allowedHeaders("*")

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

示例:

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

例子:

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

.allowedHeaders("X-Auth-Token")

maxAge(3600)

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

示例:

.maxAge(3600)  // 允許預(yù)檢請求的緩存時間為 3600 秒(即 1 小時)
  • 實(shí)際效果:如果預(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é)配置最佳實(shí)踐

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

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

相關(guān)文章

  • 淺談SpringSecurity基本原理

    淺談SpringSecurity基本原理

    今天帶大家了解一下SpringSecurity的基本原理,文中有非常詳細(xì)的代碼示例,對正在學(xué)習(xí)java的小伙伴們有很好地幫助,需要的朋友可以參考下
    2021-05-05
  • Java 無符號右移與右移運(yùn)算符的使用介紹

    Java 無符號右移與右移運(yùn)算符的使用介紹

    這篇文章主要介紹了Java 無符號右移與右移運(yùn)算符的使用介紹,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-06-06
  • 如何利用Spring的@Import擴(kuò)展點(diǎn)與spring進(jìn)行無縫整合

    如何利用Spring的@Import擴(kuò)展點(diǎn)與spring進(jìn)行無縫整合

    這篇文章主要介紹了如何利用Spring的@Import擴(kuò)展點(diǎn)與spring進(jìn)行無縫整合的實(shí)例代碼,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-08-08
  • SpringSecurity中的UserDetails和UserDetailsService接口詳解

    SpringSecurity中的UserDetails和UserDetailsService接口詳解

    這篇文章主要介紹了SpringSecurity中的UserDetails和UserDetailsService接口詳解,UserDetailsService 在 Spring Security 中主要承擔(dān)查詢系統(tǒng)內(nèi)用戶、驗(yàn)證密碼、封裝用戶信息和角色權(quán)限,需要的朋友可以參考下
    2023-11-11
  • SpringBoot接口路徑重復(fù),啟動服務(wù)器失敗的解決

    SpringBoot接口路徑重復(fù),啟動服務(wù)器失敗的解決

    這篇文章主要介紹了SpringBoot接口路徑重復(fù),啟動服務(wù)器失敗的解決,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • Java中List集合的常用方法詳解

    Java中List集合的常用方法詳解

    這篇文章主要為大家詳細(xì)介紹了Java中List集合的常用方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-02-02
  • Java8 stream 中利用 groupingBy 進(jìn)行多字段分組求和案例

    Java8 stream 中利用 groupingBy 進(jìn)行多字段分組求和案例

    這篇文章主要介紹了Java8 stream 中利用 groupingBy 進(jìn)行多字段分組求和案例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-08-08
  • Java讀取TXT文件內(nèi)容的方法

    Java讀取TXT文件內(nèi)容的方法

    本篇文章主要介紹了Java讀取TXT文件內(nèi)容的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-06-06
  • java中l(wèi)ambda(函數(shù)式編程)一行解決foreach循環(huán)問題

    java中l(wèi)ambda(函數(shù)式編程)一行解決foreach循環(huán)問題

    這篇文章主要介紹了java中l(wèi)ambda(函數(shù)式編程)一行解決foreach循環(huán)問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • SpringBoot整合MP通過Redis實(shí)現(xiàn)二級緩存方式

    SpringBoot整合MP通過Redis實(shí)現(xiàn)二級緩存方式

    這篇文章主要介紹了SpringBoot整合MP通過Redis實(shí)現(xiàn)二級緩存方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-01-01

最新評論