SSE實時通信與前端聯調實戰

1.SSE 原理機制

sse 類似websocket,但是sse是單向的,不可逆的,只能服務端向客戶端發送數據流

2.解決跨域問題

Access to XMLHttpRequest at 'http://127.0.0.1:8090/sse/doChat' from origin 'http://127.0.0.1:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.
request.js:48err: Error: Network Error 

require.js 文件


// 創建axios實例
const instance = axios.create({// baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url// baseURL: "http://192.168.3.110:8090", // url = base url + request urlbaseURL: "http://127.0.0.1:8090", // url = base url + request url// baseURL: "http://150.109.247.64:9090",// baseURL: "https://www.itzixi.com/api", // url = base url + request urlwithCredentials: true, // send cookies when cross-domain requeststimeout: 60000 // request timeout
});// axios請求的攔截器
instance.interceptors.request.use(config => {// do something before request is sentvar userInfo = cookieUtils.getUserInfo();// console.log(userInfo);if (userInfo) {// console.log("userId = " + userInfo.id);config.headers['headerUserId'] = userInfo.id;}var userToken = cookieUtils.getToken();// console.log("userToken = " + userToken);if (userToken) {// console.log("userToken = " + userToken);config.headers['headerUserToken'] = userToken;}return config},error => {// do something with request errorconsole.log(error) // for debugreturn Promise.reject(error)}
);// axios響應的攔截器
instance.interceptors.response.use(response => {const res = response.datareturn res;},error => {console.log('err: ' + error) // for debugconsole.log('err: ' + error.data) // for debugreturn Promise.reject(error)}
)
MvcConfiguration.java 文件如下
package com.spring.springai.config;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 MvcConfiguration implements WebMvcConfigurer {/*** 解決跨域* addMapping:設置哪些接口支持跨域* allowedOrigins:設置跨域的來源,也就是哪些域名最終可以接收響應* allowedMethods:設置支持跨域的方法* allowHeaders:運行哪些請求頭* @param registry*/public void addCorsMappings(CorsRegistry registry) {registry.addMapping("/**") // 允許所有接口支持跨域.allowedOrigins("*")// 允許所有來源.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")// 允許所有HTTP方法.allowedHeaders("*");// 允許所有請求頭
//         .allowCredentials(true); // 允許發送Cookie,需要指定具體的origin}
}

這個錯誤是因為你的前端請求設置了?withCredentials: true(即包含憑據,如 cookies、HTTP認證等),但后端 CORS 配置使用了通配符?*?作為?allowedOrigins,這是不被允許的。

根據 CORS 策略,當請求包含憑據時,服務器不能使用?Access-Control-Allow-Origin: *,而必須指定明確的域名。

你有兩種解決方案:

方案1:前端移除 withCredentials(如果不需憑據)

如果你的跨域請求不需要攜帶 cookies 或認證信息,可以在前端代碼中移除?withCredentials?設置:

// 如果是使用 axios
axios.get('http://127.0.0.1:8090/sse/doChat', {withCredentials: false // 或者直接移除這個配置
})// 如果是原生 XMLHttpRequest
const xhr = new XMLHttpRequest();
xhr.withCredentials = false; // 設置為 false
方案2:后端指定具體域名并啟用 allowCredentials(推薦)

如果你需要攜帶憑據,修改后端的 CORS 配置:

@Configuration
public class MvcConfiguration implements WebMvcConfigurer {@Overridepublic void addCorsMappings(CorsRegistry registry) {registry.addMapping("/**").allowedOrigins("http://127.0.0.1:3000") // 指定前端具體域名.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS").allowedHeaders("*").allowCredentials(true); // 允許憑據}
}
方案3:使用 allowedOriginPatterns(更靈活)

Spring Framework 5.3+ 支持使用模式匹配:

@Configuration
public class MvcConfiguration implements WebMvcConfigurer {@Overridepublic void addCorsMappings(CorsRegistry registry) {registry.addMapping("/**").allowedOriginPatterns("http://127.0.0.1:*", "http://localhost:*") // 使用模式匹配.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS").allowedHeaders("*").allowCredentials(true);}
}
方案4:使用 Filter 進行更精細的控制
@Configuration
public class CorsConfig {@Beanpublic CorsFilter corsFilter() {UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();CorsConfiguration config = new CorsConfiguration();config.setAllowCredentials(true);config.addAllowedOrigin("http://127.0.0.1:3000");config.addAllowedHeader("*");config.addAllowedMethod("*");source.registerCorsConfiguration("/**", config);return new CorsFilter(source);}
}
對于 SSE (Server-Sent Events) 的特殊處理

如果你使用的是 SSE,還需要確保正確處理 OPTIONS 預檢請求:

@Configuration
public class MvcConfiguration implements WebMvcConfigurer {@Overridepublic void addCorsMappings(CorsRegistry registry) {registry.addMapping("/sse/**") // 單獨配置 SSE 端點.allowedOrigins("http://127.0.0.1:3000").allowedMethods("GET", "POST", "OPTIONS").allowedHeaders("*").allowCredentials(true).maxAge(3600); // 預檢請求緩存時間}
}

推薦使用方案2或方案3,指定具體的前端域名并啟用?allowCredentials(true),這樣既能保證安全性,又能滿足攜帶憑據的需求。

最終解決方法:
  public void addCorsMappings(CorsRegistry registry) {registry.addMapping("/**") // 允許所有接口支持跨域//.allowedOrigins("*")// 允許所有來源.allowedOrigins("http://127.0.0.1:3000", "http://localhost:3000", "http://ai.mywoshop.com:3000").allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")// 允許所有HTTP方法.allowedHeaders("*")// 允許所有請求頭.allowCredentials(true); // 允許發送Cookie,需要指定具體的origin}

前端代碼:https://gitee.com/yang-jiayu12/springai-mcp-front-end

后端代碼:https://gitee.com/yang-jiayu12/springai-mcp

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/920328.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/920328.shtml
英文地址,請注明出處:http://en.pswp.cn/news/920328.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

從傳統到創新:用報表插件重塑數據分析平臺

一、傳統 BI 平臺面臨的挑戰 在當今數字化時代,數據已成為企業決策的重要依據。傳統的商業智能(BI)平臺在數據處理和分析方面發揮了重要作用,但隨著數據量的爆炸式增長和用戶需求的日益多樣化,其局限性也逐漸顯現。 …

MySQL--MySQL中的DECIMAL 與 Java中的BigDecimal

1. 為什么需要 DECIMAL在數據庫中,常見的數值類型有:INT、BIGINT → 整數,存儲容量有限。FLOAT、DOUBLE → 浮點數,存儲效率高,但存在精度丟失問題。DECIMAL(M, D) → 定點數,存儲精確值。例子:…

低空無人機系統關鍵技術與應用前景:SmartMediaKit視頻鏈路的基石價值

引言:低空經濟的新興格局 低空經濟作為“新質生產力”的代表,正在從政策驅動、技術突破和市場需求的共振中走向產業化。2023年,中國低空經濟的市場規模已超過 5000 億元人民幣,同比增長超過 30%。無人機(UAV&#xff…

在Windows系統上升級Node.js和npm

在Windows系統上升級Node.js和npm,我推薦以下幾種方法: 方法1:使用官網安裝包(最簡單) 訪問 nodejs.org 下載Windows安裝包(.msi文件) 運行安裝包,選擇"修復"或直接安裝新…

【Jetson】基于llama.cpp部署gpt-oss-20b(推理與GUI交互)

前言 本文在jetson設備上使用llama.cpp完成gpt-oss 20b的部署,包括后端推理和GUI的可視化交互。 使用的設備為orin nx 16g(super),這個顯存大小推理20b的模型完全沒有問題。 使用硬件如下,支持開啟super模式。&#…

Matplotlib 可視化大師系列(一):plt.plot() - 繪制折線圖的利刃

目錄Matplotlib 可視化大師系列博客總覽Matplotlib 可視化大師系列(一):plt.plot() - 繪制折線圖的利刃一、 plt.plot() 是什么?二、 函數原型與核心參數核心參數詳解三、 從入門到精通:代碼示例示例 1:最基…

第二階段Winfrom-8:特性和反射,加密和解密,單例模式

1_預處理指令 (1)源代碼指定了程序的定義,預處理指令(preprocessor directive)指示編譯器如何處理源代碼。例如,在某些情況下,我們希望編譯器能夠忽略一部分代碼,而在其他情況下&am…

【開題答辯全過程】以 微信小程序的醫院掛號預約系統為例,包含答辯的問題和答案

個人簡介一名14年經驗的資深畢設內行人,語言擅長Java、php、微信小程序、Python、Golang、安卓Android等開發項目包括大數據、深度學習、網站、小程序、安卓、算法。平常會做一些項目定制化開發、代碼講解、答辯教學、文檔編寫、也懂一些降重方面的技巧。感謝大家的…

鴻蒙ArkUI 基礎篇-06-組件基礎語法-Column/Row/Text

目錄 掌握組件寫法,使用組件布局界面 ArkUI與組件 先布局再內容 DevEco Studio代碼實戰 預覽效果 總結 練習 掌握組件寫法,使用組件布局界面 ArkUI與組件 ArkUI(方舟開發框架):構建 鴻蒙 應用 界面 的框架 組件…

8.27 網格memo

lc329計算矩陣中最長遞增路徑長度嘗試從矩陣每個位置出發,int dfs() 往上下左右四個方向找嚴格遞增的路徑retmax(ret,dfs(x,y)1);return memo[i][j]ret;返回所有路徑里的最長長度 class Solution {public:int dx[4]{0,0,1,-1};int dy[4]{1,-1,0,0};int m,n;vector&l…

flume監控文件寫入 Kafka 實戰:解耦應用與消息隊列的最佳實踐

flume監控文件寫入 Kafka 實戰:解耦應用與消息隊列的最佳實踐 在日志采集場景中,直接讓應用程序通過 log4j2 寫入 Kafka 會導致應用與 Kafka 強耦合(如 Kafka 故障可能影響應用運行)。更優的方案是:應用程序將日志寫入…

從瀏覽器無法訪問到Docker容器的 FastAPI 服務地址【宿主機瀏覽器和容器不在同一個網絡層面:端口映射】

文章目錄1. 問題根源:Docker 網絡模型2. 解決方案:端口映射(Port Mapping)方法 1:重新運行容器并添加端口映射(推薦)方法 2:獲取宿主機的 IP 進行訪問(特定情況&#xff…

線性代數中矩陣等價與離散數學中關系的閉包之間的關聯

最近在重溫線性代數時,學到矩陣的等價的定義及其性質,發現其性質與離散數學中關系的閉包所要滿足的性質非常相似,不由的讓人不懷疑這二者之間存在某種關聯,從而引發以下的思考:從deepseek的回答中我明白了矩陣的等價其…

從MyJUnit反思Java項目的工程實踐(版本控制篇)

從 MyJUnit 反思Java項目的工程實踐(版本控制篇) 參考資料 deepseekgithub copilotCSDN-Git代碼管理工作流程:GitFlow詳解Conventional Commits手冊封面來自 qwen-image 遵循 git flow 分支管理模型 Git Flow 是一種圍繞項目發布的核心分支模型, 它規定了不同的開發…

小工具推薦

小工具 ? 平時不太喜歡去搜羅一些好用的工具,但是看到自己感興趣的還是會記下來,有的是github上的開源項目,有的是一些直接在線的工具。主要是除了工作時間也不知道去干點什么,或者是和朋友玩玩游戲,或者是city walk…

【js】加密庫sha.js 嚴重漏洞速查

前言sha.js 是 JavaScript 生態里最常用的輕量級加密庫。它由 Browserify 社區維護,體積不足 20 KB,卻實現了 SHA-1、SHA-224、SHA-256、SHA-384、SHA-512 全系列算法,是 crypto-browserify、webpack、web3.js 等數百個流行包的“根依賴”。而…

FPGA入門學習路徑

FPGA入門學習路徑 專業基礎 數電(數字電路基礎-CSDN博客) 語法 Verilog(Verilog硬件描述語言-CSDN博客) VHDL(VHDL硬件描述語言-CSDN博客) FPGA開發流程 常用接口設計 學習目的:通過簡單…

HTML響應式設計的顏色選擇器,適配各種屏幕尺寸

顏色選擇器 響應式設計的顏色選擇器,適配各種屏幕尺寸 支持色相滑塊和RGB數值兩種調色方式 點擊顏色值或復制按鈕即可復制十六進制顏色代碼 自動根據背景色調整文字顏色確保可讀性 包含復制成功提示動畫效果 現代化UI設計,采用圓角、陰影和漸變背景 完全…

ChatGPT登錄不進怎么辦?

ChatGPT登錄不進的核心原因分類ChatGPT登錄失敗并非單一問題導致,通常與網絡環境、賬號狀態、設備設置及平臺限制相關,不同場景下的故障表現與誘因存在明顯差異,可分為以下四類:網絡連接與地域限制:ChatGPT對訪問地域有…

【ConcurrentHashMap】實現原理和HashMap、Redis哈希的區別

【ConcurrentHashMap】實現原理和HashMap、Redis哈希的區別【一】核心思想【1】HashMap?(1)概括(2)🚀線程不安全的場景和原因1-場景一:Put 操作導致的數據覆蓋/丟失 (Lost Update)??2-場景二&#xff1a…