由跨域引發一些思考

由跨域引發一些思考

    • 前言
    • 什么是跨域?
      • 為什么會產生跨域?
      • 跨域場景示例:
      • 跨域常見的解決方法:
        • JSONP(JSON with Padding)
        • CORS(Cross-Origin Resource Sharing)
        • document.domain + iframe
        • location.hash + iframe
        • window.name + iframe
        • postMessage
        • 代理服務器
        • Node.js中間件代理
        • WebSocket
    • 什么是代理?
      • 工作原理
      • 功能與應用
    • 類型
    • 為什么說配置代理能夠解決跨域的問題呢?
    • 基于Webpack或者是Vite開發配置代理?
    • 本地開發配置了代理,上線后還需要配置代理么?
    • 小結

前言

最近加了個群,今天有人在群里問了一個問題“前端配置了跨域代理,項目發布到線上還需要配置 nginx 反向代理嗎?”,由此,在群里展開了激烈的討論。討論的主要點就是在跨域和代理上面,由此引發了我的一些思考。首先記錄一些基本的概念。

什么是跨域?

跨域(Cross-Origin)是指在互聯網上的一個域下的文檔或腳本嘗試請求另一個域下的資源時,域名、協議或端口不同的這種行為。由于瀏覽器實施的同源策略(Same-origin policy),這是一種安全機制,用于限制一個源中的文檔或腳本與來自另一個源的資源進行交互,以防止惡意網站讀取另一個網站的數據。

為什么會產生跨域?

  1. 同源策略:瀏覽器的同源策略是為了保護用戶信息的安全,它規定了來自一個源的Web內容,只能與同一個源下的資源進行交互。這意味著,如果嘗試從不同源加載數據,如使用XMLHttpRequest請求數據,瀏覽器會默認阻止這種行為,以防惡意站點讀取另一個站點的數據。
  2. 安全考量:如果沒有同源策略,惡意網站可以通過腳本讀取銀行網站的cookie信息等敏感數據,造成嚴重的安全威脅。因此,跨域限制是必要的安全措施。

跨域場景示例:

  • 當前端網頁部署在example.com域名下,嘗試通過JavaScript向api.example2.com發送Ajax請求獲取數據時,就發生了跨域。
  • 即使是同一域名,但端口不同(如example.com:80嘗試訪問example.com:8080)或者協議不同(HTTPS與HTTP),也會被視為跨域。

跨域常見的解決方法:

JSONP(JSON with Padding)
  • 原理:利用<script>標簽沒有跨域限制的特性,通過動態創建<script>標簽,并設置其src屬性為跨域URL(通常包含回調函數名作為參數),來加載并執行跨域腳本。
  • 缺點:只能發送GET請求,存在安全風險(如XSS攻擊)。
CORS(Cross-Origin Resource Sharing)
  • 原理:通過服務器設置響應頭中的Access-Control-Allow-Origin等字段來允許跨域請求。
  • 支持所有類型的HTTP請求。
  • 需要在服務器端進行配置。
document.domain + iframe
  • 原理:將兩個頁面的document.domain設置為相同的值,以允許它們通過iframe進行跨域通信。
  • 僅限于主域相同,子域不同的跨域應用場景。
location.hash + iframe
  • 原理:利用iframe的location.hash屬性在不同域之間進行數據傳遞。
  • 需要借助中間頁面來實現雙向通信。
window.name + iframe
  • 原理:通過iframe的window.name屬性在不同域之間共享數據。
  • window.name的值在頁面重新加載后依然存在。
postMessage
  • 原理:使用window.postMessage方法可以在不同的窗口(包括iframe)之間安全地傳遞數據。
  • 需要目標窗口監聽message事件來接收數據。
代理服務器
  • 原理:在服務器端設置一個代理服務器,作為中間層來處理跨域請求。
  • 客戶端向代理服務器發送請求,代理服務器將請求轉發給目標服務器,并將響應返回給客戶端。
  • 可以在前端完全避免跨域問題,但增加了服務器端的復雜性。
Node.js中間件代理
  • 原理:在Node.js服務器端使用中間件(如http-proxy-middleware)來代理跨域請求。
  • 客戶端向Node.js服務器發送請求,Node.js服務器將請求轉發給目標服務器,并將響應返回給客戶端。
  • 可以在前端避免跨域問題,但需要搭建Node.js服務器環境。
WebSocket
  • 原理:WebSocket是一種網絡通信協議,可以在單個TCP連接上進行全雙工通信。
  • 不受同源策略的限制,可以實現跨域通信。
  • 需要服務器端支持WebSocket協議。

什么是代理?

這里的代理其實是指的網絡代理。網絡代理(Proxy),又稱代理服務器,是一種位于客戶端和目標服務器之間的中間服務器。以下是關于網絡代理的詳細解釋:
網絡代理允許一個網絡終端(一般為客戶端)通過這個服務與另一個網絡終端(一般為服務器)進行非直接的連接。簡單來說,它就是網絡信息的中轉站,代理網絡用戶去取得網絡信息。

工作原理

  • 客戶端需要配置代理服務器的地址和端口,然后將網絡請求發送給代理服務器。
  • 代理服務器接收請求后,根據客戶端的要求進行處理(如更改IP地址、緩存資源等),然后將請求轉發給目標服務器。
  • 目標服務器將響應發送給代理服務器,代理服務器再將響應轉發給客戶端。

功能與應用

  1. 隱私保護:通過使用匿名代理或VPN,用戶可以隱藏自己的真實IP地址,防止被目標服務器和網絡監聽者識別,有助于保護個人隱私和防止網絡監控。
  2. 繞過地域限制:有些網絡資源會因為地域、政策等原因進行限制。通過使用代理服務器或VPN,用戶可以“偽裝”成其他地區的IP地址,從而訪問受限制的資源。
  3. 負載均衡:對于大型網站和應用,負載均衡是保證高性能和可用性的關鍵。通過使用反向代理,可以將客戶端的請求分發到多個目標服務器,從而實現負載均衡和故障轉移。
  4. 內容過濾與審計:企業和學校等組織可以使用HTTP代理對員工和學生的網絡訪問進行監控和控制,如限制訪問特定網站、屏蔽敏感內容等,有助于保證網絡安全和合規性。
  5. 網絡加速:通過使用緩存代理和CDN技術,可以將網絡資源緩存到距離用戶更近的服務器上,從而提高訪問速度和降低延遲。

類型

  • HTTP代理:能夠代理客戶機的HTTP訪問,主要是代理瀏覽器訪問網頁。
  • FTP代理:能夠代理客戶機上的FTP軟件訪問FTP服務器。
  • RTSP代理:代理客戶機上的Realplayer訪問Real流媒體服務器。
  • POP3代理:代理客戶機上的郵件軟件用POP3方式收發郵件。
  • VPN代理:在共用網絡上建立專用網絡的技術,通過在公用網絡服務商ISP所提供的網絡平臺之上的邏輯網絡來實現。

為什么說配置代理能夠解決跨域的問題呢?

配置代理能夠解決跨域問題,主要是因為代理服務器在請求發送和接收過程中充當了中間層的角色。以下是詳細解釋:
中間層的作用:

  • 當客戶端發送請求時,請求首先到達代理服務器,而不是直接到達目標服務器。
  • 在代理服務器上,可以將請求中的域名或IP地址進行轉換,使得原本不同源的請求在服務器端看起來像是來自同一源的請求。
    解決跨域的原理:
  • 跨域問題本質上是瀏覽器的一種安全策略,即同源策略(Same-Origin Policy),它禁止不同源的網頁之間進行某些交互。
  • 通過配置代理,可以在請求發送之前將請求中的域名轉換為目標服務器所接受的域名,從而繞過瀏覽器的同源策略檢查。
  • 例如,如果客戶端在localhost:8080下運行,而目標服務器在www.example.com上,客戶端發送的請求會首先到達代理服務器。在代理服務器上,可以將請求的域名從localhost:8080轉換為www.example.com,然后再將請求轉發給目標服務器。
    返回數據的處理:
  • 當目標服務器返回數據時,數據也會首先到達代理服務器。
  • 在代理服務器上,可以將返回數據中的域名從www.example.com轉換回localhost:8080(或其他客戶端所期望的域名),然后再將數據返回給客戶端。

基于Webpack或者是Vite開發配置代理?

我們在平時的前端開發的過程中,通常都會配置代理來解決跨域問題;比如說在Webpack中配置代理:

const { createProxyMiddleware } = require('http-proxy-middleware');  module.exports = {  // ... 其他配置項  devServer: {  proxy: {  '/api': {  target: '<url>', // 目標服務器的地址  ws: true, // 如果你的應用程序使用了websockets,則需要設置為true  secure: false, // 如果你的目標服務器使用了HTTPS,需要設置為false(除非你配置了HTTPS代理)  changeOrigin: true, // 如果你的目標服務器和你的開發服務器不在同一個域上,需要設置為true  pathRewrite: {'^/api' : ''} // 重寫路徑,例如將/api/users重寫為/users  },  // 可以配置多個代理規則  // '/other': { ... }  }  }  
};

在Vite中配置代理:

// vite.config.js  
export default {  // ... 其他配置項  server: {  proxy: {  // 選項寫法  '/api': {  target: '<url>', // 目標服務器的地址  changeOrigin: true, // 如果你的目標服務器和你的開發服務器不在同一個域上,需要設置為true  rewrite: (path) => path.replace(/^\/api/, '') // 重寫路徑,例如將/api/users重寫為/users  },  // 或者使用字符串簡寫  '/foo': '<other_url>'  }  }  
}

本地開發配置了代理,上線后還需要配置代理么?

在本地開發環境中配置代理主要是為了解決跨域問題,允許前端代碼能夠訪問不同源的API服務。然而,當應用程序部署到生產環境后,跨域問題的處理方式會有所不同。
通常,上線后不需要在前端應用中配置代理。 這是因為生產環境中的前端代碼通常是通過構建過程(如Webpack、Rollup、Vite等)打包并部署到靜態文件服務器或CDN上的,而這些服務器通常不會運行代理服務器。
在生產環境中處理跨域問題的方法主要有以下幾種:

  1. 后端服務器配置CORS(跨源資源共享):
    這是最常見的方法。后端服務器配置CORS策略,允許來自特定來源(或所有來源)的跨域請求。前端代碼不需要進行任何特殊配置,只需按照正常的HTTP請求方式發送請求即可。
  2. 使用API網關:
    在微服務架構中,API網關通常用于處理跨域請求。API網關可以配置CORS策略,并將請求轉發到后端服務。這樣,前端代碼就可以通過API網關訪問后端服務,而無需直接配置代理。
  3. JSONP(僅適用于GET請求):
    雖然JSONP是一種較老的跨域技術,但它仍然在某些情況下被使用。它通過動態插入

小結

在我們前端開發過程中配置了前端代理,當項目上線后,要根據實際的策略來考慮是否需要再遠程再配置代理

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

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

相關文章

AutoHotKey自動熱鍵(二)中文版幫助手冊下載和自定義一般鍵盤快捷鍵

所有的操作其實在開發者手冊中已經交待完了,所以我們要使用中文的手冊來進行使用 autohotkey1.1.15中文手冊下載 好了,為什么有了中文手冊,這里還要進行一些具體的介紹呢,就是為了讓大家少踩坑,能夠快速形成生產力 這里先講一下自定義快捷鍵WIN鍵和ALT鍵和CTRL鍵和SHIFT鍵的組…

智慧的網絡爬蟲之CSS概述

智慧的網絡爬蟲之CSS概述 ? CSS 是“Cascading Style Sheet”的縮寫&#xff0c;中文意思為“層疊樣式表”&#xff0c;用于描述網頁的表現形式。如網頁元素的位置、大小、顏色等。css的主要作用是定義網頁的樣式。 CSS樣式 1. 行內樣式 行內樣式&#xff1a;直接定義在 HT…

深入理解Git:fetch與pull的區別與運用

在Git的版本控制世界中&#xff0c;fetch和pull是兩個至關重要的命令&#xff0c;它們都與從遠程倉庫獲取數據有關。然而&#xff0c;這兩個命令在功能和用法上卻存在著顯著的差異。本文將詳細解析fetch和pull的區別&#xff0c;以及它們在實際開發中的應用&#xff0c;幫助讀者…

Qt 5.14.2+Android環境搭建

1. 安裝QT5.14.2的過程中&#xff0c;選中套件&#xff08;kit&#xff09; qt for android。 如果已經安裝了qt creator但沒有安裝該套件&#xff0c;可以找到在qt安裝目錄下的MaintenanceTool.exe&#xff0c;運行該程序添加套件。 2. 安裝jdk8&#xff0c;android sdk&…

五分鐘了解MQ消息集成

一、MQ消息集成的定義 MQ消息集成是通過消息中間件&#xff08;Message Queue&#xff09;實現的一種數據集成方式。它通過將數據發送到中間件中&#xff0c;再從中間件中接收數據&#xff0c;實現不同系統之間的數據交換。在MQ消息集成中&#xff0c;發送者和接收者之間不需要…

vue3.2及以上 父調子的方法defineExpose定義供父調用的方法及屬性

1、定義子類LoginForm&#xff1a; function handleLogin(account, token) {console.log(account,token)}defineExpose({handleLogin,}); 2、父類調用子類組件 const loginFormRef ref(); <LoginForm ref"loginFormRef" />loginFormRef.value.handleLogin(…

代碼隨想錄第38天|動態規劃

1049. 最后一塊石頭的重量 II 參考 備注: 當物體容量也等同于價值時, 01背包問題的含義則是利用好最大的背包容量sum/2, 使得結果盡可能的接近或者小于 sum/2 等價: 盡可能的平分成相同的兩堆, 其差則為結果, 比如 (abc)-d, (ac)-(bd) , 最終的結果是一堆減去另外一堆的和, 問…

Deep-LIBRA:一種用于可靠量化乳腺密度的人工智能方法,并在乳腺癌風險評估中進行了獨立驗證| 文獻速遞-深度學習自動化疾病檢查

Title 題目 Deep-LIBRA: An artificial-intelligence method for robust quantification of breast density with independent validation in breast cancer risk assessment Deep-LIBRA&#xff1a;一種用于可靠量化乳腺密度的人工智能方法&#xff0c;并在乳腺癌風險評估中…

【LeetCode】每日一題:相交鏈表

給你兩個單鏈表的頭節點 headA 和 headB &#xff0c;請你找出并返回兩個單鏈表相交的起始節點。如果兩個鏈表不存在相交節點&#xff0c;返回 null 。 圖示兩個鏈表在節點 c1 開始相交&#xff1a; 題目數據 保證 整個鏈式結構中不存在環。 注意&#xff0c;函數返回結果后&am…

7/1 uart

uart4.c #include "uart4.h"//UART4_RX > PB2 //UART4_TX > PG11char rebuf[51] {0}; //rcc/gpio/uart4初始化 void hal_uart4_init() {/********RCC章節初始化*******///1.使能GPIOB組控制器 MP_AHB4ENSETR[1] 1RCC->MP_AHB4ENSETR | (0x1 << 1)…

【C++11:右值引用,列表初始化】

統一列表初始化&#xff1a; 構造函數的函數名與函數體之間增加一個列表&#xff0c;用于對成員初始化 在實例化對象時&#xff0c;支持單/多參數的隱式轉化&#xff0c;同時也可以省略符號&#xff0c;讓代碼更簡潔 右值的引用 左值&#xff1a; 左值與右值的重要區別就是能…

全國產化飛騰模塊BIOS下修復系統啟動文件

1、背景介紹 全國產飛騰模塊采用麒麟信安操作系統&#xff0c;當系統下面的grub.cfg文件被用戶誤操作導致無法啟動時&#xff0c;可以在BIOS下通過U盤中備份的grub.cfg替換硬盤上原來的grub.cfg文件&#xff0c;從而實現啟動。 2、操作步驟 首先進入BIOS命令行模式&#xff…

Meta低頭,庫克認錯,XR回歸第一性原理

圖片&#xff5c;Photo by Maxim Hopman on Unsplash ©自象限原創 作者丨羅輯 2024年&#xff0c;XR的故事應該怎么講&#xff1f; 如果從數據上看&#xff0c;這應該是個沉重的話題。 根據 IDC 報告&#xff0c;2023 年全球 VR 市場出貨量下滑了 10.7%。2024 年第一…

【必看】賣慘營銷

經常賣慘的人到底是什么心理&#xff1f; Berry Ni同學說&#xff1a; 吸引別人的注意力。想要得到關注。 讓你降低對他的期待。 讓你能夠在他做好一件小事的情況下就表揚他。 控制你對他的想法認知。 ? 浪矢心理同學說&#xff1a; 1&#xff0c;求關注。他覺得買慘有好處&…

【Excel、RStudio計算T檢測的具體操作步驟】

目錄 一、基礎知識1.1 顯著性檢驗1.2 等方差T檢驗、異方差T檢驗1.3 單尾p、雙尾p1.3.1 檢驗目的不同1.3.2 用法不同1.3.3 如何選擇 二、Excel2.1 統計分析工具2.1.1 添加統計分析工具2.1.2 數據分析 2.2 公式 -> 插入函數 -> T.TEST 三、RStudio 一、基礎知識 參考: 1.…

Gradle學習-4 創建二進制插件工程

二進制插件工程創建有兩種方式&#xff1a; 創建獨立的工程&#xff0c;調試的時候&#xff0c;需要手動發布成一個二進制插件jar包&#xff0c;給其他工程里面引用&#xff0c;進行功能測試。這種方式是比較麻煩的。創建buildSrc子工程&#xff0c;它是一個大工程中的子工程&…

開源網安榮獲第一新聲“2024中國最佳信創安全廠商”,信創實力獲認可

近日&#xff0c;由權威機構【第一新聲】與【天眼查】聯合發起的“2024中國最佳信創廠商系列榜單”評選中&#xff0c;開源網安以其技術創新能力和在信創領域持續投入&#xff0c;成功入選“中國最佳信創安全廠商”。 開源網安&#xff0c;作為軟件安全領域創領者&#xff0c;自…

數據結構 - C/C++ - 棧

目錄 結構特性 結構實現 結構容器 結構設計 順序棧 鏈式棧 結構特性 棧(stack)是線性表的一種形式&#xff0c;限定僅在表的一端進行插入或者刪除的操作。 棧頂 - 表中允許插入、刪除的一端稱為棧頂(top)&#xff0c;棧頂位置是可以發生變化的。 插入 - 進棧、入棧、壓棧…

數據結構預科

在堆區申請兩個長度為32的空間&#xff0c;實現兩個字符串的比較【非庫函數實現】 要求&#xff1a; 1> 定義函數&#xff0c;在對區申請空間&#xff0c;兩個申請&#xff0c;主函數需要調用2次 2> 定義函數&#xff0c;實現字符串的輸入&#xff0c;void input(char …

31 C++11

本節目標 c11簡介列表初始化變量類型推導范圍for循環新增加容器右值新的類功能可變參數模板 1. c11簡介 在2003年標準委員會提交了一份計數勘誤表&#xff08;簡稱TC1&#xff09;&#xff0c;使得c03這個名字已經取代了c98稱為c11之前的最新的c標準名稱。不過由于c03&#x…