📘 第四章 返回结果的HTTP状态码
📄 一句话概括

204 表示成功,但本来就没有内容给你。它不能有正文,客户端也不会去解析正文。

📝 本节和前面几节的关系

上一节是「有内容」的 200,这一节是「没内容」的 204。 两者的差别看着小,实际影响客户端行为和框架解析。

一、三个使用场景

删除:DELETE /item/1 成功,没什么可返回的。 提交:表单处理完,不需要返回到页面(不过更常见的是 303)。 心跳:探活接口只关心「活着吗」,不关心返回什么。 共同点:客户端不需要响应内容,只需要知道「成了」。

二、硬规矩:不能有正文

204 的响应里不能有正文,也不该带 Content-Length(带了必须是 0)或 Transfer-Encoding。 带了就是协议错误。 Demo 里 204 响应整段 81 字节,正文 0 字节; 对照的 200 空正文是 83 字节——只差 2 字节,但语义完全不同。 为什么要在意这 2 字节的差别?因为客户端处理不同:对 204 它不会去读正文、不会渲染、不会跳转; 对 200 空正文,它可能还会尝试解析 JSON,然后报「空响应」错误。

三、204 与 205、304 的区别

205 Reset Content 要求客户端重置视图(清空表单),很少用。 304 Not Modified 也是无正文,但它是缓存协商的结果,意思是「用你本地那份」, 不是「没有内容」。 这三个都无正文,只有 204 是「操作成功且无需返回」。 看码别只看有没有正文——这是读抓包时最容易误判的地方。

四、动手 Demo:204 与 200 空正文的对照

先发一个 DELETE 拿 204,再发一个 GET 拿 200 空正文,两份响应并列看字节数与首部。

def resp(raw, st):
    return (u'HTTP/1.1 204 No Content', [(u'X-Why', u'deleted')], b'')
got = _one(resp, _req(u'DELETE', u'/item/1'))
print(len(got))       # 整段只有首部

实跑输出:

--------------------------------------------------------------------
204 No Content:成功,但没有东西给你
--------------------------------------------------------------------
  状态行                     HTTP/1.1 204 No Content
  正文长度                   0 字节
  Content-Length             0
  整段响应                   81 字节

  对照:200 空正文           HTTP/1.1 200 OK,83 字节

  204 的用途                 操作成功但无需返回内容(删除、提交、心跳)
  204 的硬规矩               **不能有正文**,也不能带 Content-Length 以外的实体首部
  204 vs 200 空正文          204 是「本来就没有」,200 空是「有但空」
  用 204 的好处:客户端不会去解析正文,浏览器也不会跳转,
  省掉一次无意义的渲染,也避免了「空正文被当成错误」的误判。

正文长度 0 字节、Content-Length 0、整段响应 81 字节。81 字节全是首部——这就是 204 的形态。 对照:200 空正文 83 字节。差的 2 字节就是状态行里 OK 与 No Content 的长度差。 204 vs 200 空正文 204 是「本来就没有」,200 空是「有但空」——这一句是本节的结论。 它不是文字游戏,客户端行为真的不一样。

30 秒实验

  1. 给 204 塞一个非空正文,看客户端会不会读(会读到,但那是协议错误)。
  2. 给 204 加 Content-Length: 5,看客户端会不会等 5 个字节(会,然后超时)。
  3. 想想:删除接口回 204 好,还是回 200 加 {"deleted": true} 好?

常见误区

  1. 「204 就是空的 200」——语义不同,客户端处理路径也不同。
  2. 「204 可以带正文」——不能,带了就是协议错误。
  3. 「304 也是没有内容」——304 的意思是「用你缓存里那份」,不是「没有」。
自测三问(点开对答案) 1. 204 能不能带正文? —— 不能。带了就是协议错误,客户端可能报错或直接忽略。 2. 204 和 200 空正文有什么实际差别? —— 语义不同:204 表示本来就没有,客户端不会尝试解析;200 空正文可能被解析并报错。 3. 304 为什么也没有正文? —— 它的意思是「你本地那份还有效」,所以只需要首部,不需要重新传内容。

204 没有内容。下一节看「只给一部分内容」的那个码。

相关笔记