HTTP无状态协议?别急,通过Cookie记住用户

94 阅读3分钟

为什么需要“存储”?

前端为什么要存储数据? 前端(浏览器)是用户直接操作的地方,为了记住一些信息(比如登录状态、购物车内容),就需要把数据存在本地。

后端为什么要存储数据? 后端负责处理业务逻辑和长期保存重要数据,比如用户的注册信息、订单记录等。

前端有哪些存储方式?

存储方式特点用途
Cookie小文本文件,每次请求会自动带上记录身份信息(如登录状态)
localStorage永久保存,容量大用户偏好设置、缓存数据
sessionStorage关闭页面就消失临时数据(如表单填写)
IndexedDB浏览器数据库,支持结构化数据离线应用、复杂数据

HTTP 协议的发展:从无状态到有状态识别

HTTP 0.9

  • 最早的版本,无状态协议
  • 每次请求都是独立的,服务器不记得你是谁
  • 请求1次或1000次,返回的内容都一样

🔍 举个例子:

你去超市买东西,但收银员每天换人,没人记得你昨天买过什么。

HTTP 1.0 / 1.1

  • 引入了 请求头(Header)
  • 可以在 Header 中加一些“私货”,比如:
    • Content-Type: 数据类型
    • Authorization: 身份验证信息
    • Cookie: 用户身份标识

🔧 所以现在虽然还是无状态协议,但可以携带额外信息来“模拟有状态”。

Cookie 是怎么工作的?

Cookie 的本质:

  • 一段小文本存储在浏览器
  • 包含关键的身份信息(如 UID、token)

Cookie 的工作流程:

  1. 前端发送用户名和密码给后端接口 /login
  2. 后端收到请求,验证成功,设置cookie,如:Set-Cookie: uid=123456
  3. 后端响应返回浏览器,浏览器就把这个cookie存起来
  4. 下次访问其他接口(再访问/login会重新设置 cookie 时,浏览器会自动在请求头带上这个cookie:Cookie: uid=123456
  5. 访问其他接口时,后端会解析cookie得知用户是谁。

用户状态:未登录 vs 已登录

状态表现如何判断
未登录看不到个人信息、不能下单前端检查是否有 token 或 cookie
已登录显示用户名、历史订单等服务器根据 cookie 解析出用户 ID
主动登出清除 cookie前端删除 cookie 或让其失效

前后端联调流程详解

1. 前端提交登录表单

<form id="loginForm">
    <input type="text" id="username" placeholder="Username" required />
    <input type="text" id="password" placeholder="Password" required />
    <button type="submit">login</button>
</form>
const loginForm = document.getElementById('loginForm');
loginForm.addEventListener('submit', async function(event) {
    event.preventDefault(); // 阻止表单的默认提交行为
    const username = document.getElementById('username').value.trim();
    const password = document.getElementById('password').value.trim();
    console.log(username,password);
    
    try {
        const response = await fetch('/login', {
            method: 'POST', // 请求方法为POST
            headers: { // 请求头,指定请求的内容类型为application/json
                'Content-Type': 'application/json'
            },
            body: JSON.stringify({ username, password }) // 请求体,将用户名和密码转换为JSON字符串,只能发送字符串,要序列化         
        })
        const data = await response.json(); // 解析响应体为JSON对象
        console.log(data);
    }catch (error) {
        console.error('登录失败');
    }
})

2. 后端接收请求 /login

// Node.js 示例
const http = require('http'); // 引入核心模块

const server = http.createServer((req, res) => { 
    if(req.method == 'POST' && req.url == '/login'){
        res.writeHead(200,{
            // 服务器端设置的 
            // 在请求头设置cookie,浏览器会自动把cookie保存起来,下次请求的时候会自动带上cookie
            'Set-Cookie': "user=admin;", //假设前端传来的是admin
            'Content-Type': "application/json"
        }); // 响应头
        res.end(
            JSON.stringify({
                success: true,
                msg: "登录成功"
            })
        ); // 登录成功 
    }

3.下一次请求会自动带上 Cookie

比如访问 /user/profile 接口时:

fetch('/user/profile')
  .then(res => res.json())
  .then(profile => {
    console.log(profile);
  });

浏览器会自动带上:

Cookie: uid=admin

后端接收到后就可以知道是哪个用户。

总结一句话:

HTTP 协议本身是无状态的,但通过 Cookie,我们可以让它“记住”用户是谁。