计算机“十万个为什么”之跨域

本文是计算机“十万个为什么”系列的第五篇,主要是介绍跨域的相关知识。

作者:无限大

推荐阅读时间: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浏览器…