前后端分離架構下的跨域問題與解決方案

在現代Web開發中,特別是隨著前后端分離架構的普及,跨域問題成為了開發者必須面對的一個重要議題。本文將詳細介紹什么是跨域問題、其產生的原因以及如何從前端和后端兩個角度來解決這個問題,并提供一些實用的代碼示例。

一、跨域問題概述

1.?定義

跨域問題是指當一個資源試圖從一個源加載時,如果該資源的域名、協議或端口號與當前網頁的域名、協議或端口號不同,則會被瀏覽器阻止訪問。這是為了防止惡意網站讀取另一個網站的數據,從而保護用戶的隱私和安全。

2.?常見場景

  • 前端頁面部署在一個服務器上,而后端API部署在另一個服務器。
  • 開發環境與生產環境使用不同的域名或端口。

例如:

  • https://example.com/api?與?https://example.com:8080/api?不同源(端口不同)
  • https://example.com/api?與?http://example.com/api?不同源(協議不同)
  • https://example.com/api?與?https://sub.example.com/api?不同源(域名不同)

二、跨域問題產生原因

1.?同源策略

瀏覽器遵循同源策略(Same-origin policy),即只有當請求的URL的協議、域名和端口號都相同的情況下,才允許獲取資源。任何一項不匹配都會導致跨域問題。

2.?預檢請求(Preflight Request)

對于非簡單請求(如PUT, DELETE等),瀏覽器會先發送一個OPTIONS請求到目標服務器,詢問服務器是否允許此次跨域請求。如果服務器響應正確,瀏覽器才會繼續發送實際請求。

三、解決方案

(一)前端解決方案

1.?Proxy代理

在開發環境中,可以使用前端工具(如 Webpack Dev Server、Vite)配置代理服務器,將跨域請求轉發到目標服務器。

示例(Vue.js/Vite 配置):

// vite.config.js
export default defineConfig({server: {proxy: {'/api': {target: 'http://backend-api.com',  // 后端API地址changeOrigin: true,rewrite: (path) => path.replace(/^\/api/, '')}}}
})

原理:
前端請求發送到同域名的代理服務器(如http://localhost:3000/api),代理服務器再將請求轉發到實際的后端服務器(如http://backend-api.com),從而避免瀏覽器的同源策略限制。

2.?JSONP

JSONP 是一種古老的跨域解決方案,利用了<script>標簽不受同源策略限制的特性。

工作流程:

  1. 前端動態創建<script>標簽,src 指向后端 API,并添加回調函數名作為參數(如callback=handleData
  2. 后端收到請求后,將 JSON 數據包裝在回調函數中返回(如handleData({"name":"John"})
  3. 瀏覽器執行返回的 JavaScript 代碼,觸發回調函數處理數據

示例代碼:

function loadData() {const script = document.createElement('script');script.src = 'http://api.example.com/data?callback=handleData';document.body.appendChild(script);
}function handleData(data) {console.log('Received data:', data);
}

缺點

  • 只支持 GET 請求
  • 安全性較低,容易受到 XSS 攻擊
  • 僅適用于與支持 JSONP 的 API 交互

(二)后端解決方案

1.?CORS(Cross-Origin Resource Sharing)

CORS是一種W3C標準,它允許服務器聲明哪些源站通過瀏覽器有權限訪問哪些資源。下面是一個基于Gin框架的Go語言實現示例:

package middlewaresimport ("net/http""github.com/gin-gonic/gin"
)func Cors() gin.HandlerFunc {return func(context *gin.Context) {method := context.Request.Method// 允許所有域名進行跨域調用context.Header("Access-Control-Allow-Origin", "*")// 允許任何請求頭context.Header("Access-Control-Allow-Headers", "Content-Type,AccessToken,X-CSRF-Token, Authorization, Token,x-token,X-User-Id")// 允許任何方法(POST、GET等)context.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE,UPDATE")// 允許瀏覽器解析的頭context.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Content-Type")// 允許攜帶Cookiecontext.Header("Access-Control-Allow-Credentials", "true")// 處理預檢請求if method == "OPTIONS" {context.AbortWithStatus(http.StatusNoContent)}// 繼續處理請求context.Next()}
}

關鍵響應頭說明:

  • Access-Control-Allow-Origin:指定允許訪問資源的源,可以是具體域名或*(允許所有)
  • Access-Control-Allow-Methods:允許的 HTTP 方法
  • Access-Control-Allow-Headers:允許的請求頭
  • Access-Control-Allow-Credentials:是否允許攜帶 Cookie
  • Access-Control-Max-Age:預檢請求的緩存時間

注意事項:

  • 生產環境應避免使用*,而是指定具體的域名
  • 如果設置了Access-Control-Allow-Credentials: true,則不能使用*
  • 預檢請求(OPTIONS)需要快速響應,通常返回 204 狀態碼

四、生產環境中的跨域配置建議

  1. 精細控制 CORS 設置

    • 避免使用Access-Control-Allow-Origin: *,應指定具體的前端域名
    • 嚴格限制允許的請求頭和方法
    • 僅在必要時啟用Access-Control-Allow-Credentials
  2. 使用 HTTPS:混合使用 HTTP 和 HTTPS 可能導致跨域問題,建議前后端均使用 HTTPS。

  3. 監控預檢請求:確保服務器正確處理 OPTIONS 請求,避免性能瓶頸。

  4. 考慮 CDN:靜態資源(如 CSS、JS、圖片)可以部署到 CDN,避免跨域問題。

五、總結

跨域問題是Web開發中不可避免的一部分,尤其是在前后端分離的趨勢下。了解其背后的原理有助于我們選擇合適的解決方案。一般來說,后端通過配置CORS是最直接有效的方式,而前端則可以通過代理或者JSONP等方式作為補充。合理地應用這些技術,可以有效地提升用戶體驗,同時確保系統的安全性。

如果這篇文章對大家有幫助可以點贊關注,你的支持就是我的動力😊!

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

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

相關文章

搜索數據建設系列之數據架構重構

導讀 主要概述百度搜索業務數據建設的創新實踐&#xff0c;重點圍繞寬表模型設計、計算引擎優化和新一代業務服務交付模式&#xff08;圖靈3.0開發模式&#xff09;三大方向&#xff0c;解決了傳統數倉在搜索場景下面臨的諸多挑戰&#xff0c;實現了搜索數據建設的高效、穩定、…

2025年滲透測試面試題總結-2025年HW(護網面試) 29(題目+回答)

安全領域各種資源&#xff0c;學習文檔&#xff0c;以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各種好玩的項目及好用的工具&#xff0c;歡迎關注。、 目錄 2025年HW(護網面試) 29 1. 樣本分析思路 2. Linux GDB分析樣本示例 3. 應急案例&#xff1a;WebShell后…

動態編程入門第二節:委托與事件 - Unity 開發者的高級回調與通信藝術

動態編程入門第一節&#xff1a;C# 反射 - Unity 開發者的超級工具箱 動態編程入門第二節&#xff1a;委托與事件 - Unity 開發者的高級回調與通信藝術 上次我們聊了 C# 反射&#xff0c;它讓程序擁有了在運行時“看清自己”的能力。但光能看清還不夠&#xff0c;我們還需要讓…

降低網絡安全中的人為風險:以人為本的路徑

有效降低網絡安全中的人為風險&#xff0c;關鍵在于采取以人為本的方法。這種方法的核心在于通過高效的培訓和實踐&#xff0c;使員工掌握安全知識、踐行安全行為&#xff0c;并最終培育出安全且相互支持的文化氛圍。 誠然&#xff0c;技術和政策必須為良好的安全行為提供支持、…

opencv裁剪和編譯

opencv裁剪和編譯 0. 準備工作 0.1 下載和安裝Eigen 地址 https://eigen.tuxfamily.org/index.php?titleMain_Page對于opencv編譯&#xff0c;需要增加EIGEN_INCLUDE_PATH和開啟WITH_EIGEN -DWITH_EIGENON -DEIGEN_INCLUDE_PATH./3rd/eigen-3.4.01. 實際腳本 編譯腳本如下: ch…

小白成長之路-mysql數據基礎(三)

文章目錄一、主從復制二、案例總結一、主從復制 1、master開啟二進制日志記錄2、slave開啟IO進程&#xff0c;從master中讀取二進制日志并寫入slave的中繼日志3、slave開啟SQL進程&#xff0c;從中繼日志中讀取二進制日志并進行重放4、最終&#xff0c;達到slave與master中數據…

通過 Windows 共享文件夾 + 手機訪問(SMB協議)如何實現

通過 Windows 共享文件夾 手機訪問&#xff08;SMB協議&#xff09; 實現 PC 和安卓手機局域網文件共享&#xff0c;具體步驟如下&#xff1a; &#x1f4cc; 前置條件 電腦和手機連接同一局域網&#xff08;同一個Wi-Fi或路由器&#xff09;。關閉防火墻或放行SMB端口&#…

【Python3教程】Python3高級篇之正則表達式

博主介紹:?全網粉絲23W+,CSDN博客專家、Java領域優質創作者,掘金/華為云/阿里云/InfoQ等平臺優質作者、專注于Java技術領域? 技術范圍:SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大數據、物聯網、機器學習等設計與開發。 感興趣的可…

Redis--黑馬點評--達人探店功能實現詳解

達人探店發布探店筆記探店筆記類似于點評網站的評價&#xff0c;往往是圖文結合&#xff0c;對應的表有兩個&#xff1a;tb_blog&#xff1a;探店筆記表&#xff0c;包含筆記中的標題、文字、圖片等tb_blog_comments&#xff1a;其他用戶對探店筆記的評價tb_blog表結構如下&…

一探 3D 互動展廳的神奇構造?

3D 互動展廳的神奇之處&#xff0c;離不開一系列先進技術的強力支撐 。其中&#xff0c;VR(虛擬現實)技術無疑是核心亮點之一。通過佩戴 VR 設備&#xff0c;觀眾仿佛被瞬間 “傳送” 到一個全新的世界&#xff0c;能夠全身心地沉浸其中&#xff0c;360 度無死角地觀察周圍的一…

C++ 網絡編程(15) 利用asio協程搭建異步服務器

&#x1f680; [協程與異步服務器實戰]&#xff1a;[C20協程原理與Boost.Asio異步服務器開發] &#x1f4c5; 更新時間&#xff1a;2025年07月05日 &#x1f3f7;? 標簽&#xff1a;C20 | 協程 | Boost.Asio | 異步編程 | 網絡服務器 文章目錄前言一、什么是協程&#xff1f;二…

【Java21】在spring boot中使用虛擬線程

文章目錄 0.環境說明1.原理解析2.spring boot的方案3.注意事項&#xff08;施工中&#xff0c;歡迎補充&#xff09; 前置知識 虛擬線程VT&#xff08;Virtual Thread&#xff09; 0.環境說明 用于驗證的版本&#xff1a; spring boot: 3.3.3jdk: OpenJDK 21.0.5 spring boot…

利器:NPM和YARN及其他

文章目錄**1. 安裝 Yarn&#xff08;推薦方法&#xff09;****2. 驗證安裝****3. 常見問題及解決方法****① 權限不足&#xff08;Error: EPERM&#xff09;****② 網絡問題&#xff08;連接超時或下載失敗&#xff09;****③ 環境變量未正確配置****4. 替代安裝方法&#xff0…

跨平臺直播美顏SDK集成實錄:Android/iOS如何適配貼紙功能

眾所周知&#xff0c;直播平臺與短視頻平臺的貼紙功能不僅是用戶表達個性的方式&#xff0c;更是平臺提高用戶粘性和互動轉化的法寶。 可問題來了&#xff1a;如何讓一個貼紙功能&#xff0c;在Android和iOS兩大平臺上表現一致、運行流暢、加載穩定&#xff1f;這背后&#xff…

JavaWeb(蒼穹外賣)--學習筆記04(前端:HTML,CSS,JavaScript)

前言 本片文章是學習B站黑馬程序員蒼穹外賣的學習筆記。因為最近期末周&#xff0c;一直在應付考試所以就學的很少&#xff0c;恰好視頻中在講Nginx反向代理和負載均衡&#xff08;寫著對前端的內容做一個復習&#xff09; 概述&#xff1a; 1.web前端主要由三部分組成&…

智能學號抽取系統 V5.4.3.2 —— Vue.js 實現的多功能課堂隨機抽簽工具

智能學號抽取系統 V5.4.3.2 —— Vue.js 實現的多功能課堂隨機抽簽工具 在教學或會議場景中&#xff0c;我們經常需要隨機抽取一個或多個學號/編號來決定發言者、答題者或者參與者。為了提高效率和公平性&#xff0c;我們可以使用一些智能化的小工具來實現這一過程。 今天介紹…

從0開始學習R語言--Day39--Spearman 秩相關

在非參數統計中&#xff0c;不看數據的實際數值&#xff0c;單純比較兩組變量的值的排名是通用的基本方法&#xff0c;但在客觀數據中&#xff0c;很多變量的關系都是非線性的&#xff0c;其他的方法不是對樣本數據的大小和線性有要求&#xff0c;就是只能對比數據的差異性&…

WSL - Linux 安裝 Anaconda3-2025.06-0 詳細教程 [WSL 分發版均適用]

一、檢查系統狀態 安裝前先確認 WSL - Linxu 已正常啟動&#xff08;比如 Ubuntu&#xff09;&#xff0c;網絡連接穩定&#xff0c;并且系統磁盤有足夠空間&#xff0c;一般建議預留至少 5GB 以上的可用空間&#xff0c;避免因空間不足導致安裝失敗。 二、下載安裝包 Anacond…

熱血三國建筑攻略表格

<!DOCTYPE html> <html lang"zh-CN"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>熱血三國建筑攻略表格</title><style>…

SpringBoot+MySQL醫院掛號系統源碼

概述 基于SpringBootMySQL開發的醫院掛號系統完整源碼&#xff0c;該系統功能完善&#xff0c;包含從患者掛號到醫生管理的全流程解決方案&#xff0c;采用主流技術棧開發&#xff0c;代碼規范易于二次開發。 主要內容 系統包含完整的前后臺功能模塊&#xff1a; ??前臺功…