Node | res.setHeader()和res.writeHead()的区别

res.setHeader()和res.writeHead()的区别

📋 文章摘要:

本文详细解析了 Node.js 中 res.setHeader()res.writeHead() 的核心区别与使用场景:

  1. 本质区别setHeader 是内存中的准备操作,可多次修改;writeHead 是立即发送操作,一旦调用即锁定头部
  2. 协作顺序:必须先 setHeaderwriteHead,反之会报错
  3. 使用建议:动态头部用 setHeader,固定头部用 writeHead,流式响应必须先用 writeHead
  4. 核心原则setHeader 用于"幕后准备",writeHead 用于"前台开演"

在 Node.js 原生 http 模块中,res.setHeader()res.writeHead() 都用于设置响应头,但它们的核心本质区别在于:setHeader 是“写在内存里”的准备操作,而 writeHead 是“真正发出去”的发送操作。

你可以把响应头想象成一封即将寄出的信:

  • res.setHeader():像往信封上贴便签(准备信息),可以随时贴、反复贴,但只要没交给邮局,就还能修改。
  • res.writeHead():像把信封递进邮筒并盖上邮戳(状态码 + 头部),一旦投递,信封内容(头部)就锁死了,无法再更改。

1. 核心区别详解

对比维度res.setHeader(name, value)res.writeHead(statusCode[, statusMessage][, headers])
主要职责仅设置/修改单个响应头的值一次性发送状态码和所有响应头(开启响应流)
是否处理状态码❌ 不处理,只关心 Header 字段✅ 必须传入状态码(如 200、404)
调用次数可以多次调用,分别设置不同字段通常只能调用一次(因为调用后头部就发送了)
发送时机(关键)只修改内存中的 _headers 对象,不立即发送。头部会在第一次调用 res.write()res.end()隐式发送立即将状态行和头部数据写入网络套接字(显式发送),标志着响应头阶段结束。
调用后的影响调用后仍可通过再次 setHeader 覆盖同名头部调用后,若再调用 setHeader 会抛出 Error: Cannot set headers after they are sent

2. 二者的协作顺序(重要场景)

它们并非互斥,经常搭配使用,但顺序决定结果

  • setHeader,后 writeHead(推荐)
    setHeader 设置的头部会暂存在内存中,当调用 writeHead 时,会将所有已设置的头部(包括之前的)连同状态码一起发送出去。此时 writeHead 中的 headers 对象如果与之前同名,会覆盖之前的设置。

    res.setHeader('Content-Type', 'text/plain');
    res.setHeader('X-Custom', 'Hello');
    res.writeHead(200, { 'X-Custom': 'World' }); // 最终 X-Custom 为 'World',Content-Type 仍为 'text/plain'
    
  • writeHead,后 setHeader(报错)
    一旦 writeHead 执行完毕,头部已被发出,此时再调用 setHeader 会直接触发 Node.js 的 ERR_HTTP_HEADERS_SENT 错误。


3. 实战选择建议

场景推荐做法
需要动态添加多个头部(如根据逻辑判断是否加 Cache-Controlres.setHeader() 逐一设置,最后用 res.writeHead(200) 发送状态码(无头部参数),或直接 res.end() 让头部自动隐式发送。
需要设置状态码,且头部固定不变(如重定向)直接用 res.writeHead(302, { Location: '/new' }) 一步到位,代码最简洁。
流式传输大文件(需先发完头部再慢慢写 body)务必先用 res.writeHead() 显式发送头部,再用 res.write() 分块传输数据,确保客户端提前知晓头部信息。

💎 一句话总结

res.setHeader() 是“幕后准备”(可多次修改,最后统一发送),而 res.writeHead() 是“前台开演”(立即发送状态码+头部,一旦开演就谢绝改词)。
日常开发中,如果不需要严格区分发送时机,只用 res.setHeader() + res.end() 或直接 res.writeHead() 一步到位均可;但如果涉及流式响应,则必须先用 writeHead 发送头部,再用 write 推送数据体。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

儒雅的烤地瓜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值