計算機“十萬個為什么”之跨域

計算機“十萬個為什么”之跨域

本文是計算機“十萬個為什么”系列的第五篇,主要是介紹跨域的相關知識。

作者:無限大

推薦閱讀時間:10 分鐘

一、引言:為什么會有跨域這個“攔路虎”?

想象你正在參觀一座戒備森嚴的城堡 🏰

🚪 城堡大門 = 瀏覽器安全機制

📜 訪客通行證 = 同源策略

🔄 沒有通行證卻想進入其他城堡的訪客 = 跨域請求

在 Web 世界中,跨域就像城堡之間的訪問限制,是瀏覽器為保護用戶數據安全而設置的重要防線。但為什么需要這樣的限制?當我們訪問不同網站時到底發生了什么?這篇文章將帶你深入探索跨域的奧秘,從基礎概念到高級解決方案,全面理解這個 Web 開發中不可避免的技術挑戰。


二、跨域的本質:瀏覽器的“安全守門人”

🧐 什么是同源策略?

同源策略(Same-Origin Policy) 是瀏覽器實施的核心安全策略,它要求網頁只能請求與其自身協議、域名、端口完全相同的資源。這就像現實生活中,你家的鑰匙只能打開你家的門,不能打開鄰居家的門一樣,是一種最基本的安全邊界。

🔍 同源判斷標準(三要素)
要素說明示例
協議通信協議必須相同httphttps 不同
域名主域名和子域名都必須相同www.example.comapi.example.com 不同
端口網絡端口號必須相同808080 不同

注意:IE 瀏覽器在判斷同源時存在例外,它不檢查端口,并且允許主域名相同的不同子域之間通信。這是歷史遺留問題,現代瀏覽器已修復此行為。

🚫 典型跨域場景示例
當前頁面 URL請求資源 URL是否跨域原因
http://www.example.comhttps://www.example.com/api? 是協議不同 (http vs https)
http://www.example.comhttp://www.baidu.com? 是域名不同
http://www.example.com:80http://www.example.com:8080? 是端口不同
http://www.example.comhttp://api.example.com? 是子域名不同
http://www.example.comhttp://www.example.com/path? 否完全同源

💡 為什么需要同源策略?

同源策略看似“限制重重”,實則是保護用戶安全的重要屏障。它通過嚴格的邊界控制,構建了 Web 安全的第一道防線。沒有它,互聯網將變成危機四伏的“狂野西部”。

🔍 沒有同源策略的安全災難

想象一個沒有門禁系統的辦公樓——任何人都可以自由進出任何辦公室,翻閱文件柜,甚至冒充員工簽署文件。同源策略正是 Web 世界的門禁系統,防止以下三類致命攻擊:

1. Cookie 劫持攻擊:身份盜竊的溫床

攻擊原理:Cookie 通常存儲用戶登錄憑證。沒有同源限制,惡意網站可通過 document.cookie直接讀取其他網站的 Cookie,獲取你的銀行賬戶、郵箱、社交平臺等登錄狀態。

真實案例:2018 年 Facebook 劍橋分析事件中,第三方應用通過獲取用戶 Cookie 數據,在未經許可情況下訪問了 8700 萬用戶的個人信息。

防護機制:同源策略禁止不同源頁面訪問 Cookie,配合 HttpOnly屬性可進一步防止 JavaScript 讀取敏感 Cookie。

2. DOM 篡改攻擊:視覺欺詐的陷阱

攻擊原理:惡意網站可通過 JavaScript 操作其他網站的 DOM 結構,例如在銀行頁面上覆蓋虛假的登錄表單,或修改電商網站的支付金額。

典型場景:當你同時打開 yourbank.comfakebank.com時,后者可修改前者頁面內容,將轉賬金額從 100 元改為 10000 元,而你完全無法察覺。

防護機制:同源策略禁止跨域 DOM 訪問,確保每個網站的頁面內容只能被自身 JavaScript 操控。

3. 跨站請求偽造(CSRF):身份冒用的武器

攻擊原理:惡意網站可偽造請求,利用你已登錄的身份向其他網站發送操作指令。例如,當你登錄網銀后訪問惡意網站,它可自動發起轉賬請求。

技術實現

<!-- 惡意網站隱藏表單 -->
<form action="https://yourbank.com/transfer" method="POST" id="stealForm"><input type="hidden" name="toAccount" value="attackerAccount" /><input type="hidden" name="amount" value="10000" />
</form>
<script>// 自動提交表單document.getElementById("stealForm").submit();
</script>

防護機制:同源策略限制跨域請求,結合 CSRF Token、Referer 驗證等機制可有效防范。


🌰 生動案例:一次未遂的銀行搶劫

假設你同時打開了兩個標簽頁:

  • https://yourbank.com(已登錄網銀)
  • https://malicious.com(惡意網站)

沒有同源策略時:

  1. 惡意網站讀取你銀行頁面的 Cookie,獲取登錄狀態
  2. 修改銀行頁面 DOM,添加隱藏轉賬表單
  3. 自動提交表單,將你的資金轉移到攻擊者賬戶

同源策略如何防護:

? 阻止讀取銀行 Cookie

? 禁止修改銀行頁面 DOM

? 限制跨域請求發送

這就是為什么瀏覽器會嚴格執行同源策略——它不是技術限制,而是保護你數字財產的安全衛士。


三、跨域的表現:瀏覽器如何“攔截”請求?

很多開發者第一次遇到跨域問題時都會感到困惑:明明網絡請求成功了,服務器也返回了數據,為什么前端就是拿不到?要理解這個問題,我們需要深入了解瀏覽器攔截跨域請求的完整流程和技術細節。

  • 網絡面板:顯示真實的請求和響應狀態(如 200 OK),因為這是服務器實際返回的狀態
  • 控制臺:顯示 CORS 錯誤,因為瀏覽器攔截了響應,前端無法訪問數據

🔍 跨域錯誤的典型表現

當跨域請求被瀏覽器攔截時,控制臺會出現類似以下的錯誤信息(不同瀏覽器措辭略有差異):

常見錯誤類型及示例
  1. 缺少 CORS 頭部錯誤(最常見)
Access to fetch at 'http://api.example.com/data' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
  1. 憑據不允許錯誤
Access to fetch at 'http://api.example.com/data' from origin 'http://localhost:3000' has been blocked by CORS policy: 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'.
  1. 方法不允許錯誤
Access to fetch at 'http://api.example.com/data' from origin 'http://localhost:3000' has been blocked by CORS policy: Method PUT is not allowed by Access-Control-Allow-Methods in preflight response.

🕵??♂? 關鍵真相:請求已發送,響應被攔截

重要理解:跨域請求實際已發送到服務器,服務器也已處理并返回響應,但瀏覽器在將響應交給前端 JavaScript 之前進行了攔截檢查。這個過程包含三個關鍵步驟:

瀏覽器攔截流程示意圖
驗證失敗
驗證通過
檢查通過
檢查失敗
前端發送跨域請求
是否為簡單請求?
直接發送請求并添加Origin頭
先發送預檢請求OPTIONS
服務器驗證預檢請求
返回錯誤響應
服務器處理請求并返回響應
瀏覽器檢查CORS響應頭
將響應數據交給前端JavaScript
攔截響應并在控制臺拋出CORS錯誤
瀏覽器攔截的三步流程
  1. 請求發送階段

    • 瀏覽器允許請求發送到目標服務器
    • 自動添加 Origin 請求頭標識來源
    • 對于非簡單請求,先發送預檢請求(OPTIONS)
  2. 服務器響應階段

    • 服務器處理請求并返回響應
    • 若服務器未正確配置 CORS 頭部,響應中會缺少必要的允許信息
    • 即使服務器返回 200 狀態碼,瀏覽器仍可能攔截響應
  3. 瀏覽器檢查階段

    • 瀏覽器檢查響應中的 CORS 頭部
    • 若檢查不通過,丟棄響應數據并拋出控制臺錯誤
    • 若檢查通過,將響應數據交給前端 JavaScript

這就是為什么你在網絡面板(Network)中能看到 200 狀態碼的響應,卻在控制臺看到 CORS 錯誤的原因。瀏覽器充當了“安全門衛”的角色,即使服務器已提供數據,也會基于安全策略決定是否將數據交給前端。


四、跨域解決方案全景:從基礎到高級

面對跨域問題,開發者們探索出了多種解決方案。選擇哪種方案取決于你的具體場景:

是開發環境還是生產環境?

是簡單的 GET 請求還是復雜的交互?

是否有權限修改服務器配置?

🅰? 方案一:CORS(跨域資源共享)—— 官方標準方案

CORS(Cross-Origin Resource Sharing) 通過服務器設置 HTTP 響應頭來告訴瀏覽器允許跨域請求,是 W3C 推薦的標準解決方案。

🔧 基本原理
  1. 瀏覽器發送請求時自動添加 Origin頭,表明請求來源
  2. 服務器返回 Access-Control-Allow-Origin等響應頭,表明是否允許該來源訪問 3.瀏覽器檢查響應頭,決定是否將數據交給前端
📝 核心響應頭配置

CORS 通過以下關鍵響應頭控制跨域訪問權限,每個頭部都有特定的用途和安全考量:

  1. Access-Control-Allow-Origin

    • 允許值:具體的源 URL(如 https://example.com)或通配符 *
    • 作用:指定允許訪問資源的外部域
    • 安全約束:生產環境中應明確指定源,避免使用 *通配符;當請求需要攜帶憑據(如 Cookie)時,不能使用 *
    • 示例Access-Control-Allow-Origin: https://your-frontend.com
  2. Access-Control-Allow-Methods

    • 允許值:逗號分隔的 HTTP 方法列表(如 GET, POST, PUT, DELETE
    • 作用:指定允許的 HTTP 請求方法
    • 安全約束:應僅開放必要的方法,遵循最小權限原則
    • 示例Access-Control-Allow-Methods: GET, POST, PUT, DELETE
  3. Access-Control-Allow-Headers

    • 允許值:逗號分隔的請求頭列表(如 Content-Type, Authorization
    • 作用:指定允許的自定義請求頭
    • 注意事項:對于非簡單請求頭(如 Authorization),必須顯式聲明
    • 示例Access-Control-Allow-Headers: Content-Type, Authorization
  4. Access-Control-Allow-Credentials

    • 允許值:布爾值 true(僅當允許憑據時)
    • 作用:指示是否允許跨域請求攜帶憑據(如 Cookie、HTTP 認證信息)
    • 安全考量:啟用此選項會增加安全風險,需確保源驗證嚴格
    • 示例Access-Control-Allow-Credentials: true
  5. Access-Control-Max-Age

    • 允許值:正整數(單位:秒)
    • 作用:指定預檢請求(OPTIONS)結果的緩存時間
    • 優化建議:合理設置緩存時間(如 86400 秒=24 小時)可減少預檢請求次數
    • 示例Access-Control-Max-Age: 86400

這些響應頭需要配合使用,共同構成完整的 CORS 安全策略。服務器必須正確配置這些頭部才能使跨域請求正常工作。

💻 CORS 實現代碼示例

Node.js/Express 實現

const express = require("express");
const app = express();// 全局CORS中間件
app.use((req, res, next) => {// 允許指定源訪問res.setHeader("Access-Control-Allow-Origin", "https://your-frontend.com");// 允許的方法res.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");// 允許的請求頭res.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");// 允許攜帶Cookieres.setHeader("Access-Control-Allow-Credentials", "true");// 處理預檢請求if (req.method === "OPTIONS") {res.statusCode = 204; // 預檢請求不需要響應體return res.end();}next();
});// API路由
app.get("/data", (req, res) => {res.json({ message: "跨域請求成功!" });
});app.listen(3000, () => {console.log("服務器運行在端口3000");
});

Nginx 配置:

server {listen       ;server_name  api.example.com;location / {# 允許跨域add_header Access-Control-$allow_origin https://example.com;add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE;add_header Access-Control-Allow-Headers Content-Type,Authorization;add_header Access-Control-Allow-Credentials true;# 預檢請求直接返回204if ($request_method = 'OPTIONS') {return ;}proxy_pass http://localhost:3000;}
}
?? CORS 安全最佳實踐
  1. 避免使用 *通配符: 在生產環境中應明確指定允許訪問的源
  2. 限制允許的方法:只開放必要 HTTP 方法
  3. 謹慎啟用 Credentials:允許 Cookie 跨域傳輸會增加安全風險
  4. 合理設置 Max-Age:減少預檢請求次數提升性能

🅱? 方案二:JSONP —— 古老但仍在使用的技巧

JSONP (JSON with Padding) 是一種利用 <script>標簽不受同源策略限制特性的跨域方案,雖然古老但在一些兼容性要求高的場景仍有應用。

🔧 工作原理
  1. 前端創建 <script>標簽并指定服務器 URL,附帶回調函數名
  2. 服務器返回 JavaScript 代碼,格式為 回調函數名(數據)
  3. 瀏覽器執行返回的 JavaScript,調用回調函數處理數據
💻 JSONP 實現代碼示例

前端實現:

// 創建回調函數
function handleResponse(data) {console.log("JSONP 返回數據:", data);
}// 動態創建 script 標簽
function fetchDataWithJSONP() {const script = document.createElement("script");// 傳遞回調函數名給服務器script.src = "http://api.example.com/data?callback=handleResponse";document.body.appendChild(script);// 使用后移除 script 標簽script.onload = () => {document.body.removeChild(script);};
}// 調用函數發起請求
fetchDataWithJSONP();

服務器實現(Node.js):

const http = require('http');
const url = require('url');const server = http.createServer((req,const query = url.parse(req.url,const callback = query.callback;const data = JSON.stringify({ message: 'JSONP請求成功' });// 返回JavaScript代碼,調用回調函數res.writeHead(res.end(`${callback}(${data})`);
});server.listen(3000);
?? JSONP 的局限性

1.僅支持 GET 請求:無法發送 POST 等復雜請求

2.安全風險:可能遭受 XSS 攻擊

3.錯誤處理困難:缺乏標準的錯誤處理機制

4.無法設置請求頭:難以實現認證等功能

JSONP 已逐漸被 CORS 取代,但在需要兼容極低版本瀏覽器的場景仍有使用價值。


🅲? 方案三: 代理服務器 —— 前端無感方案

代理服務器通過在同域服務器端轉發請求來繞過瀏覽器同源限制,是開發環境中最常用方案之一。

🔧 工作原理

代理服務器充當中間人,將跨域請求轉發到目標服務器,前端只與同域代理服務器通信,瀏覽器不會觸發跨域限制。

瀏覽器
同域請求
轉發請求
響應數據
返回數據
代理服務器
前端應用
目標服務器
  1. 前端將請求發送到同域代理服務器

  2. 代理服務器轉發請求到目標服務器

  3. 目標服務器返回響應給代理服務器

  4. 代理服務器將響應返回給前端

由于前端只與同域代理服務器通信瀏覽器不會觸發跨域限制

💻 開發環境代理配置

Vite 配置:

// vite.config.js
export default {server: {proxy: {"/api": {target: "http://api.example.com", //目標服務器changeOrigin: true, // 更改請求源rewrite: (path) => path.replace(/^\/api/, ""), // 可選重寫路徑},},},
};

Webpack 配置:

// webpack.config.js
module.exports = {devServer: {proxy:'/api': {target: 'http://api.example.com',changeOrigin: true,pathRewrite: {'^/api': ''}}}}
🚀 生產環境代理(Nginx)
server {listen       ;server_name  example.com;# 靜態資源location / {root   /usr/share/nginx/html;index  index.html;}# API代理location /api/ {proxy_pass http://api.example.com/; #轉發到目標服務器proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;}
}
?? 代理服務器的局限性
  • 開發環境依賴:需要配置代理服務器,生產環境可能不適用
  • 性能開銷:增加了請求轉發的延遲
  • 安全風險:代理服務器可能成為攻擊目標,需加強安全配置
  • 跨域限制:仍需服務器端配合,無法完全解決跨域問題

🅳? 方案四:WebSocket ——實時通信跨域方案

WebSocket 協議是 HTML5 引入的全雙工通信協議它不受同源策略限制,特別適合實時通信場景。

🔧 工作原理

WebSocket 通過一次握手建立持久連接之后的通信不再受同源策略限制。

💻 WebSocket 實現代碼

前端實現:

// 創建 WebSocket 連接
const socket = new WebSocket('ws://api.example.com/chat');// 連接建立時觸發
socket.addEventListener('open', (event) => {console.log('WebSocket 連接已建立');socket.send('Hello Server!'); // 發送消息
});// 接收服務器消息
socket.addEventListener('message', (event) => {console.log('收到消息:', event.data);
});// 連接關閉時觸發
socket.addEventListener('close', (event) => {console.log('WebSocket 連接已關閉');
});// 發生錯誤時觸發
socket.addEventListener('error', (event) => {console.error('WebSocket 錯誤:', event);
});

服務器實現(Node.js with ws 庫):

const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 8080 });// 監聽連接
wss.on('connection', (ws) => {console.log('新客戶端連接');// 接收客戶端消息ws.on('message', (message) => {console.log('收到:', message.toString());ws.send('服務器已收到: ' + message.toString());});// 連接關閉ws.on('close', () => {console.log('客戶端已斷開');});
});

🅴? 其他跨域方案

方案適用場景原理優缺點
postMessage跨窗口/iframe 通信窗口間通過 postMessage方法傳遞數據靈活但僅限窗口間通信
document.domain同主域不同子域顯式設置 document.domain為相同主域簡單但僅限同主域場景
location.hashiframe 通信利用 URL 哈希值傳遞數據兼容性好但數據量有限
window.nameiframe 通信利用 window.name 屬性存儲數據可存儲大量數據但實現復雜

五、深度解析:CORS 預檢請求

很多開發者在使用 CORS 時會遇到一個困惑為什么明明只發送了一個請求,瀏覽器網絡面板卻顯示兩個請求?這就是 CORS 的預檢請求機制在起作用。

🕵??♂? 什么是預檢請求?

預檢請求(Preflight Request) 是瀏覽器在發送某些跨域請求前,先發送一個 OPTIONS方法請求到服務器,以確定服務器 是否允許實際請求。

🚦 觸發預檢請求的條件

當請求滿足以下任一條件時瀏覽器會自動發送預檢請求:

1. 使用非簡單方法

簡單方法包括:GETHEADPOST

非簡單方法包括:PUTDELETECONNECTOPTIONSTRACEPATCH

2. 使用非簡單請求頭

簡單請求頭包括:

  • Accept
  • Accept-Language
  • Content-Language
  • Content-Type (僅允許值為 application/x-www-form-urlencodedmultipart/form-datatext/plain)

非簡單請求頭示例:

  • Authorization (認證令牌)
  • Content-Type: application/json (JSON 格式數據)
  • X-Custom-Header (自定義頭)
🔍 簡單請求完整示例

滿足以下條件的請求不會觸發預檢:

// 簡單GET請求示例
fetch("https://api.example.com/data", {method: "GET",headers: {Accept: "application/json","Accept-Language": "zh-CN",},
});
🔍 預檢請求完整示例

以下請求會觸發預檢:

// 帶自定義頭的POST請求(會觸發預檢)
fetch("https://api.example.com/data", {method: "POST",headers: {"Content-Type": "application/json", // 非簡單Content-TypeAuthorization: "Bearer token123", // 非簡單請求頭"X-User-ID": "12345", // 自定義頭},body: JSON.stringify({ name: "跨域請求" }),
});
預檢請求/響應流程:
  1. 預檢請求(OPTIONS):瀏覽器自動發送
OPTIONS /data HTTP/1.1
Origin: https://example.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: Content-Type,Authorization,X-User-ID
  1. 預檢響應:服務器返回
HTTP/1.1 204 No Content
Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Methods: POST
Access-Control-Allow-Headers: Content-Type,Authorization,X-User-ID
Access-Control-Max-Age: 86400
  1. 實際請求:預檢通過后發送真實請求

?? 預檢請求優化

頻繁的預檢請求會影響性能,可通過以下方式優化:

  1. 設置合理的 Max-Age:緩存預檢結果(單位:秒)
  2. 避免使用自定義頭:優先使用簡單請求頭
  3. 合并請求:減少跨域請求次數
  4. 使用 GET 替代 POST:GET 請求通常為簡單請求

六、總結

CORS 預檢請求機制是為了確保跨域請求的安全性而引入的。開發者在使用 CORS 時需要注意觸發預檢請求的條件,以及合理配置服務器端響應頭。通過合理優化預檢請求,能夠提升應用的性能和用戶體驗。

希望本文能夠幫助你理解跨域的本質、同源策略的作用,以及如何通過 CORS、JSONP、代理等多種方式解決跨域問題。跨域雖然是 Web 開發中的一個挑戰,但也是提升應用安全性和用戶體驗的重要環節,好好利用可以讓你的應用程序更加高效。😉

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

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

相關文章

C語言:20250719筆記

字符數組在C語言中&#xff0c;支持字符串常量&#xff0c;不支持字符串變量。如果想要實現類似的字符串變量&#xff0c;C語言提供了兩種實現方式&#xff1a;字符數組&#xff1a;char name[] “哪吒”&#xff1b;字符指針&#xff1a;char *name "娜吒"&#x…

decltype是什么,什么作用?

基本概念decltype 是 C11 引入的關鍵字&#xff0c;用于推導表達式的類型&#xff0c;且會完整保留類型的細節&#xff08;包括 const、引用 &、指針 * 等&#xff09;。語法:decltype(表達式) 變量名核心特點1.推導依據是表達式本身&#xff0c;而非表達式的結果&#xff…

RPC 與 Feign 的區別筆記

一、基本概念 1.1 RPC&#xff08;Remote Procedure Call&#xff09; 定義&#xff1a;遠程過程調用&#xff0c;允許像調用本地方法一樣調用遠程服務的方法。 本質&#xff1a;跨進程通信&#xff0c;隱藏了底層網絡通信的復雜性。 常見實現&#xff1a; Java 原生 RMIDub…

高防IP能夠防御CC攻擊嗎?它具備哪些顯著優勢?

摘要&#xff1a; 面對日益復雜的網絡攻擊&#xff0c;高防IP作為重要的安全工具&#xff0c;不僅能防御常見的DDoS攻擊&#xff0c;還能有效應對CC攻擊。本文將解析高防IP防御CC攻擊的原理及其核心優勢&#xff0c;幫助讀者了解其在網絡安全中的關鍵作用。一、高防IP能否防御C…

TypeScript 類型注解(一)

一、TypeScript 類型注解1、什么是TpyeScript類型注解- 是否還記得TypeScript的兩個重要特性&#xff1f;- 類型系統、適用于任何規模- 可以說&#xff0c;TS的類型系統是TS最重要的功能&#xff1b;那么什么是類型注解呢&#xff1f;其實就是在聲明變量時&#xff0c;將變量的…

弗蘭肯斯坦式的人工智能與GTM策略的崩潰

2025 年上半年已經明確了一件事&#xff1a;B2B 市場營銷團隊被工具淹沒&#xff0c;但缺乏策略。人工智能無處不在。收入領導者在進行無休止的試點。營銷團隊拼湊各種點解決方案&#xff0c;希望能實現規模擴張。然而&#xff0c;銷售線索的增長停滯不前。信譽正在受損。曾經承…

NAND閃存(NAND Flash)是什么?

NAND閃存(NAND Flash)是什么? NAND閃存(NAND Flash)詳解 NAND閃存是一種非易失性存儲介質(斷電不丟失數據),廣泛應用于SSD、U盤、手機存儲等設備中。NAND Flash 的全稱是 “Negative-AND Flash”(與非型閃存),其名稱源自其底層存儲單元的電路結構——基于**“與非門…

Android性能優化之UI渲染優化

一、UI渲染核心瓶頸深度解析 1. 渲染管線關鍵階段階段CPU工作GPU工作潛在卡頓點Measure計算View尺寸-嵌套布局多次測量Layout計算View位置-頻繁重排(Relayout)Draw構建DisplayList指令集-復雜自定義View.onDraw()Sync & Upload資源上傳到GPU內存紋理上傳大圖/未壓縮資源Ras…

基于Spring AI Alibaba的智能知識助手系統:從零到一的RAG實戰開發

&#x1f4d6; 項目概述 在人工智能快速發展的今天&#xff0c;RAG&#xff08;Retrieval-Augmented Generation&#xff09;技術已成為構建智能問答系統的核心技術。本文將詳細介紹一個基于Spring AI Alibaba DashScope深度集成的智能知識助手系統的完整開發過程&#xff0c;…

VirtualBox + CentOS:啟用 DHCP 獲取 IPv4 地址

標題&#xff1a; VirtualBox CentOS&#xff1a;啟用 DHCP 獲取 IPv4 地址 日期&#xff1a; 2025-07-18 一、問題現象 最小化安裝的 CentOS 7 虛擬機里敲&#xff1a; ip addr輸出只有 lo 的 127.0.0.1 以及 enp0s3 的 IPv6 鏈路本地地址&#xff0c;沒有 IPv4&#xff0…

Git

Git簡介Git 是一個分布式版本控制工具&#xff0c;通常用來對軟件開發過程中的源代碼文件進行管理。通過Git 倉庫來存儲和管理這些文件&#xff0c;Git 倉庫分為兩種:本地倉庫:開發人員自己電腦上的 Git倉庫。遠程倉庫:遠程服務器上的 Git 倉庫。commit: 提交, 將本地文件和版本…

通信算法之294:LTE系統中的整數倍頻偏估計

在LTE系統中&#xff0c;整數倍頻偏估計主要通過以下方法實現&#xff1a;一、最大似然估計法&#xff08;ML&#xff09;通過遍歷預設的整數倍頻偏范圍&#xff08;如30kHz&#xff09;&#xff0c;將接收信號與本地的PSS序列在不同頻偏點上進行相關運算&#xff0c;選擇相關峰…

數字人直播:開啟直播行業新紀元?

?原始尺寸更換圖片p9-flow-imagex-sign.byteimg.com??在科技日新月異的當下&#xff0c;直播行業正經歷著一場深刻變革&#xff0c;數字人直播的興起&#xff0c;宛如一顆璀璨新星&#xff0c;照亮了直播領域的新征程。數字人直播&#xff0c;是利用先進的人工智能技術&…

朝鮮升級供應鏈惡意軟件XORIndex,再次瞄準npm生態系統

Socket威脅研究團隊最新披露&#xff0c;朝鮮國家支持的黑客組織在"傳染性面試"攻擊活動中采用了新型惡意軟件加載器XORIndex&#xff0c;該惡意程序專門通過npm軟件包注冊表滲透軟件供應鏈。攻擊規模與持續性此次攻擊并非孤立事件&#xff0c;而是針對開發者、求職者…

Windows 下 VS2019 編譯 libevent-2.1.10 庫

1. 你需要VS2019 編譯好openssl-1.1.1 &#xff0c;這個具體編譯或者下載可以參考我的博客openssl生成的庫是這兩個文件接下來&#xff0c;打開CMake &#xff0c;主要是下面的需要設置好最后Config Generate即可&#xff1b;全部成功生成 22個然后INSTALL右鍵生成 最后看下生…

Vim多列操作指南

我們在使用 Vim 時&#xff0c;經常需要同時編輯多個文件&#xff0c;或者同一個文件的不同部分。Vim 提供了分割窗口&#xff08;split&#xff09;和垂直分割窗口&#xff08;vsplit&#xff09;的功能&#xff0c;允許我們在同一個 Vim 會話中查看多個緩沖區&#xff08;buf…

Python網絡爬蟲實現selenium對百度識圖二次開發以及批量保存Excel

一.百度識圖自動上傳圖片from selenium import webdriver from selenium.webdriver.edge.options import Options from selenium.webdriver.common.by import By edge_options Options() edge_options.binary_location r"C:\Program Files (x86)\Microsoft\Edge\Applica…

Vue中的refs字段使用記錄

這段代碼是 Vue.js 中結合 Element UI 等 UI 庫的典型表單驗證寫法&#xff0c;具體含義如下&#xff1a;代碼拆解 this.$refs.fromData.validate((valid) > {// 驗證后的回調邏輯 })this.$refs.fromData $refs 是 Vue 提供的特殊屬性&#xff0c;用于訪問模板中通過 ref&qu…

多方案對比分析:后端數據加密策略及實踐

多方案對比分析&#xff1a;后端數據加密策略及實踐 隨著互聯網業務對用戶隱私和數據安全的要求不斷提升&#xff0c;后端系統中對敏感數據的加密保護已成為必備需求。從對稱加密、非對稱加密到數據庫透明加密、應用層字段加密&#xff0c;各種方案各有特點。本文將以方案對比分…

《Java語言程序設計》1.4 復習題

1.4.1 什么是操作系統?列出一些流行的操作系統?操作系統(Operating System)是運行在計算機上的最重要的程序。操作系統管理和控制計算機的活動。通用計算機的流行操作系統有Microsoft Windows、Mac OS以及Linux。如果沒有在計算機上安裝和運行操作系統&#xff0c;像Web瀏覽器…