面试备战录

184 阅读4分钟

1、什么是预检请求(OPTIONS)?什么时候会触发?

答:预检请求是浏览器在跨域请求前自动发送的一次HTTP OPTIONS 请求,用来确认服务端是否允许真正的跨域请求。它不会携带实际的业务数据,只是一个安全检查。比如浏览器发请求时,先问服务器:“我打算用 POST 方法,带着 application/json 这种 Content-Type,访问你的接口,你允许吗?”,服务器必须返回一些响应头(如Access-Control-Allow-Origin),浏览器确认后,才会继续发真正的请求。

  • 不是所有跨域请求都会预检,只有非简单请求才会。
  • 简单请求(不会触发预检):满足以下三个条件的才算“简单”:
    • 方法:只允许GET、HEAD、POST
    • 请求头:只能是浏览器默认的一些安全字段(如Accept、Content-Type: application/x-www-form-urlencoded | multipart/form-data | text/plain
    • 简单请求浏览器直接发,不预检。
  • 非简单请求(会触发预检)
    • 只要不符合上面的条件,就会触发OPTIONS 预检请求,常见情况有:
      • 使用了PUT、DELETE、PATCH等方法
      • 请求头里带了自定义字段,比如Authorization、X-Custom-Header
      • Content-Type不是三种简单类型之一,比如:application/jsontext/xml

怎么减少预检请求?

  • 避免非简单请求
    • 比如能用application/x-www-form-urlencoded就别用application/json
  • 服务端设置Access-Control-Max-Age 让浏览器缓存预检结果,比如 10 分钟内相同的跨域请求就不再预检
  • 合理设计 API:比如把不必要的PUT/DELETE改为POST

2、Content-Type 类型有哪些?常见表单上传分别用什么类型?

答:常见的Content-Type类型:

  • 文本类型
    • text/html —— HTML文档
    • text/plain —— 普通文本
    • text/css —— CSS文件
    • text/javascript / application/javascript —— JS脚本
  • JSON / XML
    • application/json —— JSON数据(常见于AJAX请求)
    • application/xml / text/xml —— XML格式
  • 表单类型
    • application/x-www-form-urlencoded
      • 默认的HTML <form>提交方式
      • 数据会编码为key1=value1&key2=value2;比如:username=Tom&age=18
    • multipart/form-data
      • 上传文件二进制数据时用
      • 表单数据会被分割成多部分(每个字段一块),支持文件上传
      • 常见于 <form enctype="multipart/form-data">
    • text/plain
      • 也是表单支持的类型(<form enctype="text/plain">
      • 直接以纯文本发送,不常用
  • 文件 / 二进制
    • application/octet-stream 二进制流,通用文件下载时常用(不知道文件类型时的兜底类型)
    • image/png、image/jpeg、image/gif
    • video/mp4、audio/mpeg

表单上传常见Content-Type

  • 普通表单提交(默认)
    • Content-Type: application/x-www-form-urlencoded适合纯文本数据,比如用户名、密码。
  • 文件上传(带input type="file"
    • Content-Type: multipart/form-data必须加enctype="multipart/form-data"才行,否则文件内容不会被上传。
  • Ajax JSON提交
    • Content-Type: application/json常见于fetchaxios提交JSON格式请求体
  • 纯文本上传
    • Content-Type: text/plain几乎不用,除非就是发个纯字符串。

3、一次完整的 HTTP 请求过程包含哪些步骤?

答:一次完整的HTTP请求主要有以下几个过程:URL解析 → DNS解析 → TCP连接 → TLS握手 → 发送HTTP请求 → 服务器处理 → 响应返回 → 浏览器渲染 → 缓存/复用

  • URL 解析:浏览器收到URL,比如:https://www.example.com:443/path/file.html?query=1#hash;会拆解成:协议(Scheme):https;域名(Host):www.example.com;端口(Port):443(HTTPS 默认);路径(Path):/path/file.html;查询参数(Query):?query=1;锚点(Fragment):#hash,不发送给服务器
  • DNS 解析
    • 浏览器检查本地DNS 缓存 → 主机文件 → 操作系统缓存 → 递归 DNS 查询
    • 最终获取服务器 IP 地址
    • 优化手段:dns-prefetch提前解析域名;CDN / Anycast加速解析
  • TCP连接
    • 浏览器向服务器IP建立TCP连接(三次握手)
    • HTTP/1.x每个域名多个连接(浏览器通常 6 个)
    • HTTP/2/HTTP/3多路复用减少连接数量(一个 TCP 连接可以承载多个请求)
  • TLS/SSL握手(HTTPS)
    • 如果是 HTTPS:
      • 客户端发送 ClientHello
      • 服务端返回 ServerHello + 证书
      • 客户端验证证书 → 协商加密密钥
      • 双方用对称密钥加密后续通信
    • HTTP/3 基于 QUIC (UDP + TLS 1.3),握手更快
  • 发送 HTTP 请求
    • 构建请求行 + 请求头 + 可选请求体
    • 浏览器发送到服务器
  • 服务器处理请求
    • 服务器接收到请求:
      • 路由匹配 → 找到对应资源/接口
      • 可能经过中间件(CDN、负载均衡)
      • 返回响应头 + 响应体
  • 浏览器接收响应
    • 状态码:200 / 304 / 404 / 500
    • 响应头:Cache-Control, Set-Cookie, Content-Type
    • 响应体:HTML / JSON / 图片 / JS
  • 浏览器渲染页面
    • 解析HTML → 构建DOM
    • 解析CSS → 构建CSSOM
    • 生成Render Tree → 布局 → 绘制
    • 执行JS → 更新DOM / CSSOM / Layout
  • 缓存 & 连接复用
    • 浏览器根据响应头判断是否缓存
    • TCP/QUIC连接可能保持复用,用于后续请求