跨域請求:解決方案

一、跨域核心概念:同源策略與跨域定義

跨域問題的根源是瀏覽器的?同源策略(Same-Origin Policy),這是瀏覽器為保護用戶數據安全而設置的核心安全限制。

1. 什么是 “同源”?

“同源” 指的是兩個 URL 的?協議、域名、端口號?三者完全一致。只有滿足同源條件,瀏覽器才允許 JS 腳本相互訪問數據(如 AJAX 請求、操作 DOM 等)。

URL 示例與?http://www.example.com:8080/index.html?是否同源原因分析
http://www.example.com:8080/about.html協議(http)、域名、端口完全一致
https://www.example.com:8080/index.html協議不同(http vs https)
http://blog.example.com:8080/index.html域名不同(www vs blog,二級域名差異)
http://www.example.com:80/index.html端口不同(8080 vs 80)
http://www.example.org:8080/index.html主域名不同(example.com?vs?example.org)

2. 什么是 “跨域”?

當 JS 腳本嘗試訪問?非同源?的資源(如發起 AJAX 請求、獲取非同源頁面的 DOM)時,就會觸發瀏覽器的同源策略限制,這種場景稱為 “跨域”。

常見跨域場景:
  • 前端項目部署在?http://localhost:5500,請求后端接口?http://localhost:3000(端口不同)。
  • 本地開發時,請求線上接口(如前端?http://127.0.0.1?請求?https://api.taobao.com,域名不同)。

3. 同源策略的作用

同源策略并非 “限制”,而是 “保護”:

  • 防止惡意網站通過 JS 讀取用戶在其他網站的 Cookie(如登錄狀態)。
  • 防止惡意網站篡改非同源頁面的 DOM,偽造用戶操作。
  • 避免敏感數據(如用戶信息、支付數據)被未授權的腳本竊取。

二、跨域解決方案:前端與后端配合實現

解決跨域的核心思路是 “繞過或允許” 同源策略限制,常見方案分為?前端主導(如 JSONP)、后端主導(如 CORS)和?代理轉發(如 Nginx 代理)三類。以下重點講解前端常用的 JSONP 和后端配置的 CORS。

1. 方案一:JSONP(前端主導,僅支持 GET 請求)

JSONP(JSON with Padding)是早期解決跨域的經典方案,利用?<script>?標簽不受同源策略限制的特性實現跨域請求。

1.1 JSONP 原理
  • <script>?標簽的?src?屬性可以加載任意域名的資源(如 CDN 上的 JS 文件),瀏覽器不攔截。
  • 后端返回的不是純 JSON 數據,而是?“回調函數名 ( JSON 數據)”?的 JS 代碼。
  • 前端提前定義好回調函數,當?<script>?加載并執行后端返回的 JS 代碼時,會自動調用回調函數,從而獲取數據。
1.2 JSONP 實現步驟(前端 + 后端)
(1)前端實現(以 “淘寶商品搜索建議” 為例)

html

預覽

<!-- 輸入框:用戶輸入關鍵詞 -->
<input type="text" id="searchInput" placeholder="輸入商品關鍵詞">
<button id="searchBtn">搜索</button>
<ul id="suggestList"></ul><script>
// 1. 提前定義回調函數:接收并處理后端返回的數據
function handleSuggest(data) {const suggestList = document.getElementById("suggestList");suggestList.innerHTML = ""; // 清空舊數據// 渲染搜索建議(淘寶接口返回的 data.result 是二維數組)data.result.forEach(item => {const li = document.createElement("li");li.innerText = item[0]; // item[0] 是商品名稱suggestList.appendChild(li);});
}// 2. 點擊按鈕發起 JSONP 請求
document.getElementById("searchBtn").onclick = function() {const keyword = document.getElementById("searchInput").value;if (!keyword) return;// 3. 創建 <script> 標簽,通過 src 發起跨域請求const script = document.createElement("script");// 淘寶開放接口:cb 參數指定回調函數名(必須與前端定義的一致)script.src = `http://suggest.taobao.com/sug?code=utf-8&q=${encodeURIComponent(keyword)}&callback=handleSuggest`;// 4. 將 <script> 插入頁面,觸發請求document.body.appendChild(script);// 5. 請求完成后移除 <script> 標簽(避免頁面冗余)script.onload = function() {document.body.removeChild(script);};
};
</script>
(2)后端實現(PHP 示例)

若后端是自建接口(如 PHP),需配合返回 “回調函數包裹的 JSON”:

php

<?php
// 1. 獲取前端傳遞的回調函數名(參數名通常為 callback)
$callback = $_GET['callback'];// 2. 準備要返回的數據(模擬商品搜索建議)
$data = ["code" => 200,"msg" => "success","result" => [["iPhone 15", "10000+ 銷量"],["iPhone 15 Pro", "5000+ 銷量"],["iPhone 15 殼", "20000+ 銷量"]]
];// 3. 轉換為 JSON 字符串
$jsonData = json_encode($data);// 4. 輸出:回調函數名( JSON 數據 )
echo $callback . "(" . $jsonData . ")";
// 最終輸出:handleSuggest({"code":200,"msg":"success",...})
?>
1.3 JSONP 的優缺點
優點缺點
兼容性好(支持所有瀏覽器,包括 IE)僅支持 GET 請求(無法發送 POST/PUT/DELETE)
無需后端復雜配置(僅需返回特定格式)安全性低(可能遭受 XSS 攻擊,需信任數據源)
前端實現簡單無法捕獲請求錯誤(如 404/500,<script>?加載失敗無回調)

2. 方案二:CORS(后端主導,支持所有 HTTP 方法)

CORS(Cross-Origin Resource Sharing,跨域資源共享)是 W3C 標準,也是目前解決跨域的?主流方案。它通過后端在響應頭中添加特定字段,明確告知瀏覽器 “允許該域名跨域訪問”,從而繞過同源策略限制。

2.1 CORS 原理
  • 前端發起跨域請求時,瀏覽器會先發送一個?預檢請求(OPTIONS 請求)(復雜請求,如 POST/PUT),詢問后端 “是否允許當前域名訪問”。
  • 后端通過響應頭(如?Access-Control-Allow-Origin)告知瀏覽器允許的域名、方法、頭部信息。
  • 瀏覽器驗證響應頭后,若符合條件,則允許前端接收數據;否則攔截請求。
2.2 CORS 實現步驟(后端配置 + 前端 AJAX)
(1)后端配置(以 PHP 為例)

只需在后端接口中添加 CORS 響應頭即可,核心字段如下:

php

<?php
// 1. 允許的前端域名(* 表示允許所有域名,生產環境建議指定具體域名)
header("Access-Control-Allow-Origin: http://localhost:5500");// 2. 允許的請求方法(GET/POST/PUT/DELETE 等)
header("Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS");// 3. 允許的請求頭(如 Content-Type、Authorization)
header("Access-Control-Allow-Headers: Content-Type");// 4. 允許前端攜帶 Cookie(需配合 withCredentials,生產環境慎用)
// header("Access-Control-Allow-Credentials: true");// 5. 處理預檢請求(OPTIONS 請求):直接返回 204 狀態碼
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {http_response_code(204);exit;
}// 6. 業務邏輯:返回數據
$response = ["code" => 200,"msg" => "CORS 跨域請求成功","data" => ["username" => "張三", "age" => 20]
];
echo json_encode($response);
?>
(2)前端 AJAX 請求(與普通 AJAX 無差異)

html

預覽

<button id="corsBtn">發起 CORS 請求</button>
<div id="corsResult"></div><script>
document.getElementById("corsBtn").onclick = function() {const xhr = new XMLHttpRequest();// 跨域請求:前端 http://localhost:5500 請求后端 http://localhost:3000xhr.open("POST", "http://localhost:3000/api/user", true);// 設置請求頭(需與后端 Access-Control-Allow-Headers 匹配)xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");// 發送請求(POST 參數)xhr.send("username=張三");// 處理響應xhr.onreadystatechange = function() {if (xhr.readyState === 4 && xhr.status === 200) {const result = JSON.parse(xhr.responseText);document.getElementById("corsResult").innerText = JSON.stringify(result, null, 2);}};
};
</script>
2.3 CORS 的優缺點
優點缺點
支持所有 HTTP 方法(GET/POST/PUT/DELETE)后端需額外配置(但配置簡單,一次配置全局生效)
安全性高(可精確控制允許的域名、方法)部分舊瀏覽器不支持(如 IE 8/9,需兼容時可用 JSONP)
支持攜帶 Cookie(需配置 withCredentials)復雜請求會多一次預檢請求(OPTIONS),輕微影響性能

3. 其他跨域方案(補充)

除了 JSONP 和 CORS,實際開發中還可能用到以下方案:

  • Nginx 反向代理:前端請求本地 Nginx 服務器,Nginx 將請求轉發到后端(因 Nginx 是服務器端,不受同源策略限制)。
  • PostMessage:用于兩個非同源頁面之間的通信(如 iframe 父子頁面),通過?window.postMessage()?發送數據,window.addEventListener("message")?接收數據。
  • WebSocket:WebSocket 是全雙工通信協議,一旦建立連接,不受同源策略限制(適合實時通信場景,如聊天、直播)。

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

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

相關文章

前端形態與樣式風格:從古典到現代的視覺語言演進

目錄前端形態與樣式風格&#xff1a;從古典到現代的視覺語言演進概述1. 前端形態的演進&#xff1a;四種核心范式1.1 古典范式&#xff1a;語義化HTML與CSS1.2 組件化范式&#xff1a;模塊化與復用1.3 響應式范式&#xff1a;多端適配1.4 動態范式&#xff1a;狀態驅動視圖2. 樣…

用戶系統從0到1:登錄、權限、積分一網打盡

&#x1f464; 用戶系統從0到1&#xff1a;登錄、權限、積分一網打盡 副標題&#xff1a;Flask-Login 多級權限 積分會員系統實戰 項目原型&#xff1a;https://madechango.com 難度等級&#xff1a;???☆☆ 預計閱讀時間&#xff1a;20分鐘 &#x1f3af; 引子&#xff1…

Java 大視界 -- Java 大數據在智能安防視頻監控系統中的視頻內容理解與智能預警升級

Java 大視界 -- Java 大數據在智能安防視頻監控系統中的視頻內容理解與智能預警升級引言&#xff1a;正文&#xff1a;一、傳統安防監控的 “三重困局”&#xff1a;看不全、看不懂、反應慢1.1 人工盯屏 “力不從心”1.1.1 攝像頭密度與人力的矛盾1.1.2 錄像調閱 “馬后炮”1.2…

OpenHarmony包管理子系統核心源碼深度解讀:從BundleManager到AMS,徹底打通應用安裝、卸載與沙箱機制全鏈路

目錄 架構概覽 核心組件詳解 包安裝流程分析 包卸載流程分析 包更新流程分析 包信息存儲機制 Launcher界面管控 開機默認系統應用安裝機制<

簡單聊聊神經網絡中的反向傳播

參考文章&#xff1a; 一文弄懂神經網絡中的反向傳播法——BackPropagation - Charlotte77 - 博客園 反向傳播求偏導原理簡單理解_反向傳播偏導-CSDN博客 這篇文章是筆者在讀完上述兩篇參考文章后的整理或者說按照自己的理解進行的一些補充&#xff0c;強烈推薦先閱讀上述兩篇文…

JSP自駕游管理系統46u2v--(程序+源碼+數據庫+調試部署+開發環境)

本系統&#xff08;程序源碼數據庫調試部署開發環境&#xff09;帶論文文檔1萬字以上&#xff0c;文末可獲取&#xff0c;系統界面在最后面。系統程序文件列表開題報告內容一、研究背景與意義 近年來&#xff0c;自駕游因自由度高、個性化強成為國內旅游市場增長最快的領域&…

通過 SQL 快速使用 OceanBase 向量檢索學習筆記

背景 AI時代離不開向量數據庫&#xff0c;向量數據庫簡單說就是在數據庫中用多維向量存儲某類事物的特征&#xff0c;通過公式計算各個向量在空間坐標系中的位置關系&#xff0c;以此來判斷事物之間的相似性。相關基礎概念如下: ● Embedding ● 距離/相似性度量 ○ Cosine dis…

PromptAD:首次引入提示學習,實現精準工業異常檢測,1張正常樣本即可超越現有方法

近年來&#xff0c;工業異常檢測&#xff08;Anomaly Detection&#xff09;在智能制造、質量監控等領域扮演著越來越重要的角色。傳統方法通常依賴大量正常樣本進行訓練&#xff0c;而在實際生產中&#xff0c;異常樣本稀少甚至不存在&#xff0c;能否僅憑少量正常樣本就實現精…

算法 --- 字符串

字符串 字符串算法題目主要處理文本的查找、匹配、比較、變換和統計問題&#xff0c;其核心特點是輸入數據為字符序列&#xff0c;解題關鍵在于利用其連續性、前綴性、字典序等特性&#xff0c;并常借助哈希、自動機、指針滑動、動態規劃等技巧高效處理。 詳細分類型與適用場景…

SpringBoot中 Gzip 壓縮的兩種開啟方式:GeoJSON 瘦身實戰

目錄 前言 一、GZIP壓縮知識簡介 1、什么是Gzip 2、Gzip特點 3、Gzip在GIS方面的應用 二、SpringBoot中開啟Gzip的方式 1、在SpringBoot中開啟Gzip的知識簡介 2、SpringBoot中GeoJSON的實例 三、全局開啟Gzip實現 1、實現原理 2、實現效果 四、局部約定配置 1、實現…

PPTist+cpolar:開源演示文稿的遠程創作方案

文章目錄前言【視頻教程】1. 本地安裝PPTist2. PPTist 使用介紹3. 安裝Cpolar內網穿透4. 配置公網地址6. 配置固定公網地址前言 PPTist作為開源在線演示文稿工具&#xff0c;提供媲美PowerPoint的核心功能&#xff0c;支持多頁面編輯、圖表插入、音視頻嵌入和動畫效果設置。特…

服務注冊/服務發現-Eureka

目的&#xff1a;解決微服務在調用遠程服務時URL寫死的問題注冊中心服務提供者&#xff08;Server&#xff09;&#xff1a;一次業務中&#xff0c;被其他微服務調用的服務&#xff0c;也就是提供接口給其他微服務。服務消費者&#xff08;Client&#xff09;:一次業務中&#…

cuda stream

基本概念 cuda stream表示GPU的一個操作隊列&#xff0c;操作在隊列中按照一定的順序執行&#xff0c;也可以向流中添加一定的操作如核函數的啟動、內存的復制、事件的啟動和結束等 一個流中的不同操作有著嚴格的順序&#xff0c;但是不同流之間沒有任何限制 cuda stream中排隊…

數據結構:完全二叉樹

完全二叉樹 定義&#xff1a; 按層序遍歷&#xff08;從上到下&#xff0c;從左到右&#xff09;填充節點。 除了最后一層外&#xff0c;其余各層必須全滿。 最后一層的節點必須 連續靠左。 完全二叉樹不一定是滿二叉樹。 滿二叉樹 (Full Binary Tree)&#xff1a;每個節點都有…

【Java初學基礎】?Object()頂級父類與它的重要方法equals()

object類常見方法/*** native 方法&#xff0c;用于返回當前運行時對象的 Class 對象&#xff0c;使用了 final 關鍵字修飾&#xff0c;故不允許子類重寫。*/ public final native Class<?> getClass() /*** native 方法&#xff0c;用于返回對象的哈希碼&#xff0c;主…

用深度學習(LSTM)實現時間序列預測:從數據到閉環預測全解析

用深度學習&#xff08;LSTM&#xff09;實現時間序列預測&#xff1a;從數據到閉環預測全解析 時間序列預測是工業、金融、環境等領域的核心需求——小到預測設備溫度波動&#xff0c;大到預測股價走勢&#xff0c;都需要從歷史數據中挖掘時序規律。長短期記憶網絡&#xff08…

gpu-z功能介紹,安裝與使用方法

GPU-Z 功能介紹、安裝與使用方法 一、核心功能 硬件信息檢測 識別顯卡型號、制造商、核心架構&#xff08;如NVIDIA Ada Lovelace、AMD RDNA 3&#xff09;、制造工藝&#xff08;如5nm、7nm&#xff09;。顯示顯存類型&#xff08;GDDR6X、HBM2e&#xff09;、容量、帶寬及顯…

數據搬家后如何處理舊 iPhone

每年&#xff0c;蘋果都會推出新款 iPhone&#xff0c;激發了人們升級到 iPhone 17、iPhone 17 Pro、iPhone 17 Pro Max 或 iPhone Air 等新機型的熱情。但在獲得新 iPhone 之前&#xff0c;有一件重要的事情要做&#xff1a;將數據從舊 iPhone 轉移到新設備。雖然許多用戶都能…

Java關鍵字深度解析(上)

這是一份全面的Java關鍵字實戰指南 目錄 1.數據類型關鍵字:內存布局與性能優化 1.1 基礎類型的內存密碼 byte-內存的極簡主義者 int-Java世界的萬能鑰匙 long - 時間與ID的守護者 1.2 引用類型的架構設計 String-不是關鍵字但勝于關鍵字 2.訪問修飾符:企業級權限控制 …

C語言深度解析:指針數組與數組指針的區別與應用

目錄 1 引言&#xff1a;從名字理解本質區別 2 指針數組&#xff1a;靈活管理多個指針 2.1 基本概念與聲明方式 2.2 內存布局與特性 2.3 典型應用場景&#xff1a;字符串數組與多維度數據管理 2.3.1 靜態分配示例&#xff1a;字符串數組 2.3.2 動態分配示例&#xff1a;…