前端一面:HTTP 缓存、本地存储与跨域基础

网络相关问题也是前端一面的高频考点。这一篇选三块最常被问到的:HTTP 缓存策略、本地存储方式的对比,以及同源策略与跨域的基本处理方式,并给出几道典型题的参考答案。

浏览器缓存大致可以分成两类:

  • 强缓存(不会发请求)

    • 通过 Expires(HTTP/1.0)或 Cache-Control: max-age 等响应头控制;
    • 在缓存未过期时,直接从本地缓存读取资源,不与服务器交互。
  • 协商缓存(会发请求)

    • 通过 Last-Modified / If-Modified-SinceETag / If-None-Match 这对头部实现;
    • 浏览器发请求时带上条件头,服务器根据资源是否变化决定返回 304 Not Modified(继续用本地缓存)还是 200 和新内容。

在一面中,考察重点通常在:

  • 能不能说清“强缓存 vs 协商缓存”的区别;
  • 知不知道常见的几个头分别起什么作用;
  • 能不能简单讲讲在前端工程里如何利用/控制缓存。

常见的几种浏览器端存储方式:

  • Cookie

    • 初衷是“让 HTTP 有状态”,典型用途是保存会话标识;
    • 会默认在同源请求中携带,大小通常限制在几 KB;
    • 可以设置过期时间、作用域(domain/path)、安全属性(SecureHttpOnlySameSite)。
  • localStorage

    • 同源下长期保存(除非手动清理),容量比 Cookie 大得多(通常几 MB 级);
    • 只能在前端 JS 读写,不会自动随请求发给服务器;
    • 适合保存一些用户偏好配置、简单缓存数据。
  • sessionStorage

    • 生命周期与当前标签页会话一致,关闭标签页即清空;
    • 同样是同源隔离,API 和 localStorage 类似。
  • IndexedDB

    • 浏览器内的 NoSQL 数据库,适合存结构化数据、离线缓存等;
    • API 相对复杂,实际多通过封装库使用。

一面里常见问题是“几种存储方式的区别和适用场景”,回答时重点强调:
Cookie 会随请求发送,更适合做会话相关信息;local/sessionStorage 则更偏前端本地状态和缓存。

同源策略 限制了脚本从一个源去读取另一个源的敏感资源。所谓“同源”,需要:

  • 协议(protocol)相同;
  • 域名(host)相同;
  • 端口(port)相同。

只要三者有一项不同,就被认为是“跨源”,直接用 XHR/fetch 访问时会受到同源策略限制。

现代前端最常用的跨域解决方案是 CORS。
核心思想是:让服务器通过响应头显式声明“哪些源可以访问我”:

  • Access-Control-Allow-Origin:允许的源(可以是具体域名或 *);
  • Access-Control-Allow-Credentials:是否允许发送 Cookie 等凭证;
  • 预检请求(OPTIONS)用来在真正发送敏感请求前协商权限。

前端通常只需要正确配置 fetch/XHR 是否携带凭证,真正的跨域策略由后端/网关控制。

一面偶尔会问到一些历史方案:

  • JSONP(只支持 GET,请求脚本);
  • 反向代理(开发环境常见,通过 devServer/Nginx 转发);
  • postMessagewindow.namedocument.domain 等。

现在主流答案通常还是以 CORS 为主,其它方案简单一两句点到即可。

参考答案要点:

  • 强缓存:

    • 浏览器在缓存未过期时直接用本地副本,不发请求;
    • 主要通过 Cache-Control: max-age=... 和(旧的)Expires 控制。
  • 协商缓存:

    • 浏览器仍会发请求,但带上条件头;
    • 服务器判断资源是否修改,如果没变返回 304,让浏览器继续用本地缓存;
    • 通过 Last-Modified / If-Modified-SinceETag / If-None-Match 实现。

回答时可以顺带提一下工程实践,比如:

  • 静态资源用强缓存 + 文件名 hash,更新时走新 URL;
  • HTML 页面通常只做协商缓存甚至不缓存,保证能及时拿到最新版本。

参考答案要点:

  • Cookie:

    • 会默认随同源 HTTP 请求发送,适用于会话标识、登录态等;
    • 容量较小,读写 API 相对麻烦;
    • 可以设置 HttpOnly/Secure/SameSite,有安全属性支持。
  • localStorage:

    • 不会自动随请求发送,主要在前端使用;
    • 容量更大,适合存放用户偏好、简单缓存;
    • 同源隔离,关闭浏览器不会自动清除。

可以补一句“登录态类信息更适合存 Cookie 或安全方案,而不是 localStorage 里随便放 token”,体现安全意识。

参考答案要点:

  • 跨域:当协议/域名/端口任一不同,就被认为是跨源,请求会受到浏览器同源策略限制;
  • CORS 的解决方案:
    • 服务器在响应头里加上 Access-Control-Allow-Origin,指定允许的源;
    • 如需发送 Cookie,需要同时设置 Access-Control-Allow-Credentials: true,并把 Allow-Origin 设为具体域名;
    • 对“非简单请求”会有预检 OPTIONS 请求,提前协商允许的方法、头部等。

回答时可以强调“前端一般只需要按需设置 withCredentials,跨域是否允许主要靠后端/网关配置”,把责任边界说清楚。