【前端每天一题】🔥第 22 题:HTTP vs HTTPS、TCP vs UDP 的区别

下面是 第 22 题:HTTP 与 HTTPS、TCP 与 UDP 的区别

这是前端 + 全栈都必考的经典网络题。

我会用:详细版 + 简明对比 + 图解思维 + 速记卡 来讲解。


✅ 第 22 题:HTTP vs HTTPS、TCP vs UDP 的区别


📘 一、HTTP 与 HTTPS 的区别


1. 协议层面

协议 名称 安全性
HTTP 超文本传输协议 ❌ 明文传输,不安全
HTTPS HTTP + SSL/TLS ✔️ 加密传输,安全

HTTPS =
HTTP(应用层) + SSL/TLS(安全层) + TCP(传输层)


2. 安全性区别

HTTP(不安全)

  • 明文传输
  • 数据容易被窃听
  • 容易被中间人攻击(MITM)

HTTPS(安全)

  • 加密(防窃听)
  • 校验完整性(防篡改)
  • 服务器身份验证(防伪造)

3. 端口区别

协议 默认端口
HTTP 80
HTTPS 443

4. 性能区别

HTTPS 因为需要加密 / 握手,会略慢,但现代优化(HTTP2 / TLS1.3)已经几乎无感。


5. 握手区别(重点)

HTTP:

无握手 → 直接发请求。

HTTPS:

要进行 TLS 握手

  • 验证服务器证书
  • 协商加密算法
  • 使用对称加密传输数据

面试官爱问:HTTPS 为什么安全?
因为用非对称加密交换对称密钥,然后用对称加密通信。


📘 二、TCP 与 UDP 的区别


1. 是否连接

协议 是否面向连接
TCP ✔️ 面向连接(必须三次握手)
UDP ❌ 无连接

2. 可靠性

协议 是否可靠 机制
TCP ✔️ 可靠 重传、滑动窗口、流量控制、拥塞控制
UDP ❌ 不可靠 不保证顺序、不保证送达

3. 速度

协议 速度
TCP 较慢(保证可靠性)
UDP 快(无需握手,无需重传)

4. 是否有序

协议 是否有序
TCP ✔️ 有序
UDP ❌ 无序

5. 使用场景

TCP(稳定传输)

需要"正确数据"的使用场景:

  • HTTP / HTTPS
  • 文件上传下载
  • 邮件发送
  • 数据可靠性强的业务

UDP(实时性优先)

不要求100%可靠,但要快:

  • 视频会议
  • 直播
  • 游戏实时同步
  • DNS(UDP + 53 端口)

📘 三、HTTP vs HTTPS vs TCP vs UDP(总对比表)

比较项 HTTP HTTPS TCP UDP
安全性 ✔️ ✔️(传输可靠)
使用加密 ✔️ ❌(可加密但非默认)
面向连接 --- --- ✔️
速度 略慢 较慢 最快
使用场景 Web 非敏感 Web 敏感业务 可靠传输 实时传输
默认端口 80 443 --- ---

📘 四、面试官常问的衍生问题(背住必加分)


① 为什么 HTTPS 需要证书?

为了:

  • 验证服务器身份
  • 防止中间人伪造
  • 公钥由权威 CA 签名

② HTTPS 为什么安全?

一句话:

用非对称加密交换对称密钥,用对称加密传输数据。


③ 为什么 TCP 要三次握手?

防止历史连接造成误触发(防止旧包被误认为是新连接)。

三次握手是为了确保双方都具备收发能力


④ TCP 为什么四次挥手?

因为关闭连接需要双方独立确认:

  • 甲:我不发了
  • 乙:收到,但我还要发
  • 乙:好了我发完了
  • 甲:再见

📘 五、速记卡片(10 秒记忆版)

ini 复制代码
HTTP:明文,不安全,80
HTTPS:加密安全,443,TLS握手

TCP:面向连接,可靠,有序,慢
UDP:无连接,不可靠,无序,快

HTTPS = HTTP + TLS + TCP

TCP 用于可靠场景(Web / 文件)
UDP 用于实时场景(直播 / 游戏)

补充:

跨域(CORS / JSONP / 代理)------更详细的一把梳理(面试 & 实战都能用)

下面把跨域相关的概念、原理、常见方案、服务器/前端示例、常见坑与排查方法都尽量讲清楚(含代码片段),方便你面试和工程中直接套用。


一、先复习:同源策略(Same-Origin Policy)

  • 什么叫同源? 协议(scheme)、主机(host)、端口(port)三者都相同则同源。
    例如 http://example.com:80https://example.com 不是 同源(协议不同)。
  • 同源策略的目的:防止跨站窃取敏感数据(浏览器安全沙箱)。它限制了文档/脚本从一个源去读取另一个源的资源(比如读取响应内容)。

二、现代方案(推荐)------CORS(Cross-Origin Resource Sharing)原理

  • 浏览器在跨域请求时遵循 CORS,服务器通过响应头声明允许哪些跨域访问,浏览器根据这些头决定是否允许 JS 访问响应。

关键响应头(服务器设置)

  • Access-Control-Allow-Origin: 必需,指定允许来源。可以是具体域 https://foo.com,也可以 *(表示允许任意来源,但与凭证不兼容)。
  • Access-Control-Allow-Methods: 允许的方法(GET, POST, PUT, DELETE, OPTIONS
  • Access-Control-Allow-Headers: 允许的自定义请求头(例如 Content-Type, X-Requested-With
  • Access-Control-Allow-Credentials: true 表示允许带 cookie/认证信息(注意:当此为 true 时,Access-Control-Allow-Origin 不能为 *,必须为明确域名)
  • Access-Control-Expose-Headers: 指示哪些响应头可以被 JS 访问(默认只有简单头可见)
  • Vary: Origin:建议设置,缓存代理根据不同 Origin 保存不同响应

请求类型

  1. 简单请求(Simple Request) :浏览器直接发送实际请求(GET/POST 若 Content-Type 是 text/plain, application/x-www-form-urlencoded, multipart/form-data),不会发预检(preflight)。
  2. 需预检请求(Preflight) :当使用非简单方法或自定义头(例如 Content-Type: application/json 或自定义 X-Token)时,浏览器先发 OPTIONS 请求询问服务器是否允许(即"预检"),若允许再发送真实请求。

预检流程

  1. 浏览器发送 OPTIONS(带 OriginAccess-Control-Request-MethodAccess-Control-Request-Headers)。
  2. 服务器返回允许的头/方法/是否允许凭证。
  3. 浏览器若允许则继续发送实际请求。

浏览器端举例(fetch)

javascript 复制代码
fetch('https://api.example.com/data', {
  method: 'POST',
  credentials: 'include', // 想带 cookie/凭证必须加这一项
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ a: 1 })
})
.then(r => r.json())
.then(data => console.log(data))

服务器端简易示例(Node/Express)

javascript 复制代码
// 最简单(允许所有来源,但不能与 credentials 一起用)
app.use((req, res, next) => {
  res.setHeader('Access-Control-Allow-Origin', '*');
  res.setHeader('Access-Control-Allow-Methods', 'GET,POST,PUT,DELETE,OPTIONS');
  res.setHeader('Access-Control-Allow-Headers', 'Content-Type,Authorization');
  next();
});

// 带 credentials(必须指定具体域)
app.use((req, res, next) => {
  res.setHeader('Access-Control-Allow-Origin', 'https://your.site.com');
  res.setHeader('Access-Control-Allow-Credentials', 'true');
  // 预检请求要快速返回 204 或 200
  if (req.method === 'OPTIONS') {
    res.status(204).end();
    return;
  }
  next();
});

Nginx 配置示例(允许跨域并支持凭证)

rust 复制代码
location /api/ {
  if ($request_method = 'OPTIONS') {
    add_header 'Access-Control-Allow-Origin' 'https://your.site.com';
    add_header 'Access-Control-Allow-Credentials' 'true';
    add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
    add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization';
    return 204;
  }
  add_header 'Access-Control-Allow-Origin' 'https://your.site.com';
  add_header 'Access-Control-Allow-Credentials' 'true';
  proxy_pass http://backend;
}

三、老办法 / 兼容方案(历史与限制)

  1. JSONP(仅限 GET)

    • 原理:<script src="..."> 不受同源限制,服务器返回一段 JS(通常调用传入的回调函数),从而绕过同源限制读取数据。

    • 限制:只支持 GET,安全性差(执行远端 JS),无法携带请求头。

    • 示例(前端):

      xml 复制代码
      <script>
        function cb(data) { console.log(data); }
      </script>
      <script src="https://api.example.com/data?callback=cb"></script>
    • 服务器返回:cb({ a: 1 })

  2. 代理转发(推荐在开发与生产中使用)

    • 开发环境 :使用 webpack-dev-server / Vite / create-react-app 的 devServer proxy,把 /api 转发到 https://api.example.com,浏览器认为是同源请求。
    • 生产 :用 Nginx 做 reverse proxy,将前端域名下的 /api 转发到后端服务(对外只暴露同源域名)。
    • 优点:不改后端、不受浏览器 CORS 限制,性能和安全可控。

    webpack devServer 示例

    yaml 复制代码
    devServer: {
      proxy: {
        '/api': {
          target: 'https://api.example.com',
          changeOrigin: true,
          secure: false
        }
      }
    }
  3. window.postMessage(跨窗口/跨iframe 通信)

    • 场景:父窗口与嵌入的跨域 iframe 通信。

    • 安全使用需检查 event.origin

    • 示例:

      javascript 复制代码
      // 父页面发送
      iframe.contentWindow.postMessage({ type: 'hello' }, 'https://other.com');
      // 子页面监听
      window.addEventListener('message', (e) => {
        if (e.origin !== 'https://your.trusted.origin') return;
        // 处理 e.data
      });
  4. document.domain(仅限同一级域名,已较少使用)

    • 只能把两端都设置成共同的较高一级域(比如 a.example.comb.example.com 都设置 document.domain = 'example.com'),现代安全和 iframe 政策使其使用已减少。
  5. WebSocket

    • WebSocket 握手不是典型的 XHR,建立一条持久连接后可以跨域传输数据(服务器需响应握手),适合双向通信场景。

四、常见问题 / 常见报错与排查

  • Access-Control-Allow-Origin 缺失 → 浏览器控制台直接报跨域错误,服务器根本没有返回允许头。
  • 使用 credentials: 'include' 时,Access-Control-Allow-Origin 不能是 * ;必须是具体域。
  • 预检 OPTIONS 返回 404/500 → 浏览器拒绝发实际请求。解决:服务器对 OPTIONS 单独返回允许头并 204。
  • 自定义请求头(如 X-Token)未出现在 Access-Control-Allow-Headers → 预检被拒。
  • 想让 JS 能读自定义响应头,要在服务器设置 Access-Control-Expose-Headers: X-My-Header
  • 浏览器缓存与 Vary:当不同 Origin 应该返回不同内容时,后端应加 Vary: Origin,否则 CDN/代理可能返回错误的缓存。
  • 使用代理时注意 changeOrigin(是否修改 Host header)。

五、安全注意事项

  • 尽量不要用 Access-Control-Allow-Origin: * 配合 Allow-Credentials: true(浏览器会禁止)。
  • 小心 JSONP------它执行远端任意 JS,可能被用作 XSS。
  • 对允许跨域的来源列白名单,不要把后端随意开放给任意来源,尤其当带有凭证(cookie、token)时。
  • 预检机制存在的目的就是在不安全操作前询问服务器,别绕过它。

六:面试/答题速记卡(10 秒)

bash 复制代码
同源策略:协议+主机+端口相同
主流跨域:CORS(浏览器与服务器配合)
  - 简单请求 vs 预检(OPTIONS)
  - 核心头:Access-Control-Allow-Origin/Methods/Headers/Credentials/Expose-Headers
老办法:JSONP(仅 GET),代理(devServer/nginx),postMessage/iframe,WebSocket
关键坑:
  - credentials + '*' 不行
  - 预检要返回 200/204 并带允许头
  - 自定义头需出现在 Allow-Headers
相关推荐
前端一课1 小时前
第 26 题:浏览器与 Node.js 的事件循环有什么区别?
前端·面试
前端一课1 小时前
【前端每天一题】🔥 第 24 题:Virtual DOM 中 diff 算法的核心流程(详细版
前端·面试
掘金012 小时前
根据提供的表格动态渲染多个表单,每个配置项包含 label、prop、type 和 placeholder 等属性。
前端
用户4445543654262 小时前
自定义viewgroup
前端
ohyeah2 小时前
用 Coze 打造你的教育智能客服:从想法到前端集成的完整实践
前端·coze·trae
雨雨雨雨雨别下啦2 小时前
【从0开始学前端】 Git版本控制系统
前端·git
前端一课2 小时前
【前端每天一题】 第 15 题:CSS 水平垂直居中高频方案(Flex / Grid / transform 等)
前端·面试
前端一课2 小时前
【前端每天一题】🔥 第 19 题:什么是重排(Reflow)和重绘(Repaint)?有什么区别?如何减少?
前端·面试
前端一课2 小时前
【前端每天一题】🔥 第 14 题:Promise.then 链式调用执行顺序
前端·面试