前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
  • HTTP

    • 基础篇

      • HTTP的前世今生
      • HTTP是什么
      • HTTP世界全览
      • HTTP分层
      • 键入网址到回车发生什么
      • HTTP报文是什么样子的
      • 理解请求方法
      • URI
      • 响应状态码
      • HTTP有哪些特点
      • HTTP优缺点
      • HTTP的实体数据
      • HTTP传输大文件
      • HTTP的连接管理
      • HTTP的重定向
      • HTTP的Cookie机制
      • HTTP的缓存控制
      • HTTP的代理服务
      • HTTP的缓存代理
    • 高级篇

    • 扩展篇

  • 浏览器相关

  • 计算机基础

# HTTP的Cookie机制

30 秒速记

  • Cookie = 服务器让浏览器替它记的小纸条,给无状态的 HTTP 补上「记性」
  • 流程:响应 Set-Cookie 下发 → 浏览器存起来 → 之后匹配的请求自动带 Cookie 头
  • 属性三类:有效期 Expires/Max-Age,作用域 Domain/Path,安全 HttpOnly/Secure/SameSite
  • HttpOnly 防 JS 读、Secure 只走 HTTPS、SameSite 管跨站带不带;它们都不加密 Cookie 本身
  • 用途:登录会话(最常见)、广告追踪(第三方 Cookie,各家浏览器在收紧)

Cookie 就是服务器托浏览器保管的一张小纸条,之后每次请求浏览器都自动带上,服务器就能认出你是谁。 HTTP 本身不记事,第一次来服务器用 Set-Cookie 发一张纸条,浏览器存下来,后面发请求自动塞进 Cookie 头。纸条在浏览器手里,所以要靠属性约束它:多久过期、发给哪些域名和路径、JS 能不能读、只能走 HTTPS、跨站时带不带。实际项目里 Cookie 一般只放一个随机的 sessionId,用户信息存在服务端,别把敏感数据直接写进去。

面试官追问

追问 1用户换了个浏览器就得重新登录,原来的浏览器还登着,说明服务端会话被删了吗?
参考回答

不说明。Cookie 是存在每个浏览器自己的存储里的,新浏览器没有那张纸条,服务端自然认不出。原浏览器还能用,恰好说明服务端会话还在。

追问 2登录接口响应里有 Set-Cookie,是不是就能确定登录成功了?
参考回答

不一定。还要看浏览器有没有存下来,DevTools 的 Application 面板里能看到;再看下一个请求有没有带上。跨域请求没加 credentials: 'include',或者 SameSite=None 没配 Secure,都会被浏览器直接丢掉。

追问 3登录凭证能被 document.cookie 读到,加个 Secure 能解决吗?
参考回答

不能。Secure 只限制走 HTTPS 发送,跟 JS 能不能读无关。要禁止脚本读取得加 HttpOnly,这样 XSS 注入的脚本拿不到会话凭证。

追问 4想让手机和电脑共享登录状态,直接把 Cookie 复制过去行不行?
参考回答

技术上能用,但这就是会话劫持的做法,泄露一次别人就能冒充你。正经做法是扫码登录:手机确认后服务端给电脑单独签一个新会话,两边各自持有、可以分别撤销。

# Cookie 的工作过程

30 秒速记

  • 第一次访问:服务器在响应里放 Set-Cookie: sid=abc,浏览器存下来
  • 之后请求:浏览器自动把匹配的 Cookie 放进请求头,服务器拿 sid 认人
  • 多个值:响应里可以有多个 Set-Cookie 头,请求里合成一行 Cookie: a=1; b=2
  • Cookie 存在浏览器里,换浏览器、换设备、开无痕都不共享
  • 服务器通常只把 Cookie 当索引,用 sid 去服务端会话里查用户,别把权限直接写在 Cookie 里

Cookie 的工作过程就是一来一回:服务器用 Set-Cookie 发纸条,浏览器在之后的请求里用 Cookie 头把纸条交回去。 下发的时候一个 Set-Cookie 头只能写一个键值,要发多个就写多个头;浏览器回传时不分开写,全部用分号拼在一个 Cookie 头里。这张纸条是浏览器在管,不是操作系统,所以换个浏览器服务器就不认识你了。实际开发中服务器一般只发一个随机的会话 ID,真正的用户信息放在服务端,Cookie 只是钥匙。

当用户通过浏览器第一次访问服务器的时候,服务器肯定是不知道他的身份的。所以,就要创建一个独特的身份标识数据,格式是“key=value”,然后放进 Set-Cookie 字段里,随着响应报文一同发给浏览器。

浏览器收到响应报文,看到里面有 Set-Cookie,知道这是服务器给的身份标识,于是就保存起来,下次再请求的时候就自动把这个值放进 Cookie 字段里发给服务器。

因为第二次请求里面有了 Cookie 字段,服务器就知道这个用户不是新人,之前来过,就可以拿出 Cookie 里的值,识别出用户的身份,然后提供个性化的服务。

不过因为服务器的“记忆能力”实在是太差,一张小纸条经常不够用。所以,服务器有时会在响应头里添加多个 Set-Cookie,存储多个“key=value”。但浏览器这边发送时不需要用多个 Cookie 字段,只要在一行里用“;”隔开就行

从这张图中我们也能够看到,Cookie 是由浏览器负责存储的,而不是操作系统。所以,它是“浏览器绑定”的,只能在本浏览器内生效。

如果你换个浏览器或者换台电脑,新的浏览器里没有服务器对应的 Cookie,就好像是脱掉了贴着纸条的衣服,“健忘”的服务器也就认不出来了,只能再走一遍 Set-Cookie 流程

原理拆解: Cookie 循环包含下发、保存、匹配和回传四步。服务器用 Set-Cookie 分别创建记录;浏览器按来源及属性保存,并在后续请求的主机、路径、安全条件匹配时生成 Cookie 请求头。服务器通常只把其中的随机会话标识当作索引,再到会话存储中查询用户资料,而不是把可信权限直接交给客户端决定。

最小验证: 运行以下 Node.js 程序,再访问 http://localhost:3000/。输入是连续两次浏览器请求,要验证第一次响应下发 sid,刷新后浏览器自动回传。

const http = require('node:http');

http.createServer((req, res) => {
  const cookies = Object.fromEntries(
    (req.headers.cookie || '').split('; ')
      .filter(Boolean)
      .map(item => {
        const i = item.indexOf('=');
        return [item.slice(0, i), item.slice(i + 1)];
      })
  );

  if (!cookies.sid) {
    res.setHeader('Set-Cookie', [
      'sid=a8f31; Path=/; HttpOnly; SameSite=Lax',
      'theme=dark; Path=/; SameSite=Lax'
    ]);
  }
  res.setHeader('Content-Type', 'text/plain; charset=utf-8');
  res.end(cookies.sid ? `recognized:${cookies.sid}` : 'first visit');
}).listen(3000, () => console.log('http://localhost:3000/'));
@前端进阶之旅: 代码已经复制到剪贴板

首次页面显示 first visit,刷新后预期显示 recognized:a8f31。数组中的两个值会生成两个 Set-Cookie 响应字段;浏览器回传时通常形成类似 sid=a8f31; theme=dark 的请求头。解析时以第一个 = 为分界,避免值中存在 = 时被错误截断。

边界与排查: 浏览器只发送满足作用域和策略的记录,因此“已经保存”不保证每个请求都携带。隐私模式、清除站点数据、更换浏览器或设备都会打断关联;禁用或拦截 Cookie 也会让示例持续停留在首次访问。可在开发者工具的 Network 中分别检查响应的 Set-Cookie 和下一次请求的 Cookie,再到站点存储面板核对域、路径、有效期及阻止原因。服务端还应把未知、过期或伪造的会话标识视为未登录。

面试官追问

追问 1服务端要同时下发 sid 和 theme 两个 Cookie,能写在一个 Set-Cookie 里用逗号隔开吗?
参考回答

不能。一个 Set-Cookie 只对应一个 Cookie,日期里本身就有逗号,合并会解析错。Node 里写 res.setHeader('Set-Cookie', ['sid=abc; HttpOnly', 'theme=dark']),传数组会生成两个头。

追问 2Cookie 里能直接放 role=admin 来判断权限吗?
参考回答

不能,Cookie 在用户手里,改个值就提权了。要么只放随机 sid,权限去服务端查;要么用签名的 token,服务端验签,但也只是防篡改,敏感信息照样别放。

追问 3Set-Cookie 明明返回了,下一个请求却没带上,按什么顺序查?
参考回答

先去 Application 面板看有没有存下来,没存的话 Network 里那条响应的 Cookies 标签会有黄色感叹号说明被拦截的原因;存了没带,就对照请求的域名、路径、协议、是否跨站和过期时间逐个比。

追问 4Cookie 每个请求都带,体积有讲究吗?
参考回答

有。单个 Cookie 上限大约 4KB,而且同域所有请求都会带,图片、脚本也不例外。一个域名下塞了 3KB 的 Cookie,页面 100 个请求就白传 300KB,所以静态资源常放到不带 Cookie 的独立域名上。

# Cookie 的属性

30 秒速记

  • 有效期:Expires 是绝对时间,Max-Age 是秒数,同时存在以 Max-Age 为准;都不写就是会话 Cookie,关浏览器就没
  • 删除 Cookie:同名、同 Domain、同 Path 再下发一次,Max-Age=0
  • 作用域:Domain 不写只发给当前主机,写了会连子域名一起发;Path 按前缀匹配
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
  • HTTP

    • 基础篇

      • HTTP的前世今生
      • HTTP是什么
      • HTTP世界全览
      • HTTP分层
      • 键入网址到回车发生什么
      • HTTP报文是什么样子的
      • 理解请求方法
      • URI
      • 响应状态码
      • HTTP有哪些特点
      • HTTP优缺点
      • HTTP的实体数据
      • HTTP传输大文件
      • HTTP的连接管理
      • HTTP的重定向
      • HTTP的Cookie机制
        • Cookie 的工作过程
        • Cookie 的属性
        • Cookie 的应用
        • 小结
      • HTTP的缓存控制
      • HTTP的代理服务
      • HTTP的缓存代理
    • 高级篇

    • 扩展篇

  • 浏览器相关

  • 计算机基础

完整面试题地址:
作者:程序员poetry
扫码关注作者公众号:「前端进阶之旅」 每天分享技术干货
前端进阶之旅公众号二维码

HTTP的Cookie机制|HTTP协议篇

# HTTP的Cookie机制

30 秒速记

  • Cookie = 服务器让浏览器替它记的小纸条,给无状态的 HTTP 补上「记性」
  • 流程:响应 Set-Cookie 下发 → 浏览器存起来 → 之后匹配的请求自动带 Cookie 头
  • 属性三类:有效期 Expires/Max-Age,作用域 Domain/Path,安全 HttpOnly/Secure/SameSite
  • HttpOnly 防 JS 读、Secure 只走 HTTPS、SameSite 管跨站带不带;它们都不加密 Cookie 本身
  • 用途:登录会话(最常见)、广告追踪(第三方 Cookie,各家浏览器在收紧)

Cookie 就是服务器托浏览器保管的一张小纸条,之后每次请求浏览器都自动带上,服务器就能认出你是谁。 HTTP 本身不记事,第一次来服务器用 Set-Cookie 发一张纸条,浏览器存下来,后面发请求自动塞进 Cookie 头。纸条在浏览器手里,所以要靠属性约束它:多久过期、发给哪些域名和路径、JS 能不能读、只能走 HTTPS、跨站时带不带。实际项目里 Cookie 一般只放一个随机的 sessionId,用户信息存在服务端,别把敏感数据直接写进去。

面试官追问

追问 1用户换了个浏览器就得重新登录,原来的浏览器还登着,说明服务端会话被删了吗?
参考回答

不说明。Cookie 是存在每个浏览器自己的存储里的,新浏览器没有那张纸条,服务端自然认不出。原浏览器还能用,恰好说明服务端会话还在。

追问 2登录接口响应里有 Set-Cookie,是不是就能确定登录成功了?
参考回答

不一定。还要看浏览器有没有存下来,DevTools 的 Application 面板里能看到;再看下一个请求有没有带上。跨域请求没加 credentials: 'include',或者 SameSite=None 没配 Secure,都会被浏览器直接丢掉。

追问 3登录凭证能被 document.cookie 读到,加个 Secure 能解决吗?
参考回答

不能。Secure 只限制走 HTTPS 发送,跟 JS 能不能读无关。要禁止脚本读取得加 HttpOnly,这样 XSS 注入的脚本拿不到会话凭证。

追问 4想让手机和电脑共享登录状态,直接把 Cookie 复制过去行不行?
参考回答

技术上能用,但这就是会话劫持的做法,泄露一次别人就能冒充你。正经做法是扫码登录:手机确认后服务端给电脑单独签一个新会话,两边各自持有、可以分别撤销。

# Cookie 的工作过程

30 秒速记

  • 第一次访问:服务器在响应里放 Set-Cookie: sid=abc,浏览器存下来
  • 之后请求:浏览器自动把匹配的 Cookie 放进请求头,服务器拿 sid 认人
  • 多个值:响应里可以有多个 Set-Cookie 头,请求里合成一行 Cookie: a=1; b=2
  • Cookie 存在浏览器里,换浏览器、换设备、开无痕都不共享
  • 服务器通常只把 Cookie 当索引,用 sid 去服务端会话里查用户,别把权限直接写在 Cookie 里

Cookie 的工作过程就是一来一回:服务器用 Set-Cookie 发纸条,浏览器在之后的请求里用 Cookie 头把纸条交回去。 下发的时候一个 Set-Cookie 头只能写一个键值,要发多个就写多个头;浏览器回传时不分开写,全部用分号拼在一个 Cookie 头里。这张纸条是浏览器在管,不是操作系统,所以换个浏览器服务器就不认识你了。实际开发中服务器一般只发一个随机的会话 ID,真正的用户信息放在服务端,Cookie 只是钥匙。

当用户通过浏览器第一次访问服务器的时候,服务器肯定是不知道他的身份的。所以,就要创建一个独特的身份标识数据,格式是“key=value”,然后放进 Set-Cookie 字段里,随着响应报文一同发给浏览器。

浏览器收到响应报文,看到里面有 Set-Cookie,知道这是服务器给的身份标识,于是就保存起来,下次再请求的时候就自动把这个值放进 Cookie 字段里发给服务器。

因为第二次请求里面有了 Cookie 字段,服务器就知道这个用户不是新人,之前来过,就可以拿出 Cookie 里的值,识别出用户的身份,然后提供个性化的服务。

不过因为服务器的“记忆能力”实在是太差,一张小纸条经常不够用。所以,服务器有时会在响应头里添加多个 Set-Cookie,存储多个“key=value”。但浏览器这边发送时不需要用多个 Cookie 字段,只要在一行里用“;”隔开就行

从这张图中我们也能够看到,Cookie 是由浏览器负责存储的,而不是操作系统。所以,它是“浏览器绑定”的,只能在本浏览器内生效。

如果你换个浏览器或者换台电脑,新的浏览器里没有服务器对应的 Cookie,就好像是脱掉了贴着纸条的衣服,“健忘”的服务器也就认不出来了,只能再走一遍 Set-Cookie 流程

原理拆解: Cookie 循环包含下发、保存、匹配和回传四步。服务器用 Set-Cookie 分别创建记录;浏览器按来源及属性保存,并在后续请求的主机、路径、安全条件匹配时生成 Cookie 请求头。服务器通常只把其中的随机会话标识当作索引,再到会话存储中查询用户资料,而不是把可信权限直接交给客户端决定。

最小验证: 运行以下 Node.js 程序,再访问 http://localhost:3000/。输入是连续两次浏览器请求,要验证第一次响应下发 sid,刷新后浏览器自动回传。

const http = require('node:http');

http.createServer((req, res) => {
  const cookies = Object.fromEntries(
    (req.headers.cookie || '').split('; ')
      .filter(Boolean)
      .map(item => {
        const i = item.indexOf('=');
        return [item.slice(0, i), item.slice(i + 1)];
      })
  );

  if (!cookies.sid) {
    res.setHeader('Set-Cookie', [
      'sid=a8f31; Path=/; HttpOnly; SameSite=Lax',
      'theme=dark; Path=/; SameSite=Lax'
    ]);
  }
  res.setHeader('Content-Type', 'text/plain; charset=utf-8');
  res.end(cookies.sid ? `recognized:${cookies.sid}` : 'first visit');
}).listen(3000, () => console.log('http://localhost:3000/'));
@前端进阶之旅: 代码已经复制到剪贴板

首次页面显示 first visit,刷新后预期显示 recognized:a8f31。数组中的两个值会生成两个 Set-Cookie 响应字段;浏览器回传时通常形成类似 sid=a8f31; theme=dark 的请求头。解析时以第一个 = 为分界,避免值中存在 = 时被错误截断。

边界与排查: 浏览器只发送满足作用域和策略的记录,因此“已经保存”不保证每个请求都携带。隐私模式、清除站点数据、更换浏览器或设备都会打断关联;禁用或拦截 Cookie 也会让示例持续停留在首次访问。可在开发者工具的 Network 中分别检查响应的 Set-Cookie 和下一次请求的 Cookie,再到站点存储面板核对域、路径、有效期及阻止原因。服务端还应把未知、过期或伪造的会话标识视为未登录。

面试官追问

追问 1服务端要同时下发 sid 和 theme 两个 Cookie,能写在一个 Set-Cookie 里用逗号隔开吗?
参考回答

不能。一个 Set-Cookie 只对应一个 Cookie,日期里本身就有逗号,合并会解析错。Node 里写 res.setHeader('Set-Cookie', ['sid=abc; HttpOnly', 'theme=dark']),传数组会生成两个头。

追问 2Cookie 里能直接放 role=admin 来判断权限吗?
参考回答

不能,Cookie 在用户手里,改个值就提权了。要么只放随机 sid,权限去服务端查;要么用签名的 token,服务端验签,但也只是防篡改,敏感信息照样别放。

追问 3Set-Cookie 明明返回了,下一个请求却没带上,按什么顺序查?
参考回答

先去 Application 面板看有没有存下来,没存的话 Network 里那条响应的 Cookies 标签会有黄色感叹号说明被拦截的原因;存了没带,就对照请求的域名、路径、协议、是否跨站和过期时间逐个比。

追问 4Cookie 每个请求都带,体积有讲究吗?
参考回答

有。单个 Cookie 上限大约 4KB,而且同域所有请求都会带,图片、脚本也不例外。一个域名下塞了 3KB 的 Cookie,页面 100 个请求就白传 300KB,所以静态资源常放到不带 Cookie 的独立域名上。

# Cookie 的属性

30 秒速记

  • 有效期:Expires 是绝对时间,Max-Age 是秒数,同时存在以 Max-Age 为准;都不写就是会话 Cookie,关浏览器就没
  • 删除 Cookie:同名、同 Domain、同 Path 再下发一次,Max-Age=0
  • 作用域:Domain 不写只发给当前主机,写了会连子域名一起发;Path 按前缀匹配
  • HttpOnly 禁止 document.cookie 读写,防 XSS 偷凭证;Secure 只在 HTTPS 下发送,但存储本身不加密
  • SameSite:Strict 跨站一律不带,Lax 只在跨站顶层 GET 跳转时带,None 都带但必须配 Secure;Chrome 默认按 Lax

Cookie 的属性就是在回答三个问题:存多久、发给谁、怎么防偷。 存多久用 Expires 或 Max-Age,两个都有时听 Max-Age 的,都不写就是关浏览器即失效。发给谁用 Domain 和 Path,坑在 Domain:不写反而最严格,只发给当前主机;写了 example.com 就连所有子域名一起发。防偷靠三个:HttpOnly 让 JS 读不到,Secure 只走 HTTPS,SameSite 控制跨站请求带不带,现在 Chrome 默认是 Lax,大部分 CSRF 就被挡掉了。登录态我一般直接写 HttpOnly; Secure; SameSite=Lax。

← HTTP的重定向HTTP的缓存控制 →

fe