Skip to content

res.writeHead和res.setHeader区别 #240

Open
@yaofly2012

Description

@yaofly2012

res.writeHead PK res.setHeader

先看看headheader区别:
http模块的类型方法命名中有headheaderheader,他们含义不用:

  1. head表示HTTP报文首部(包含:状态码,状态描述,首部字段)
  2. header表示指定的首部字段;
  3. headers表示所有的首部字段。

req图示
image

res图示
image

可能是因为这两个方法都可以设置报文首部字段,所以经常拿来对比两者的区别。本质上讲两者没有任何可比性,单独从功能上区分即可。

  1. setHeader只是单纯的设置报文头部字段;
  2. writeHead则是发送报文首部数据,并且可以顺便设置首部数据(除了首部字段headers外,还有状态码,状态描述)。
    如果更新header并在后续还要获取,则使用setHeader更新。

res.headersSent

哪些操作使得headersSent = true

  1. res.writeHead
  2. res.write
  3. res.end

方式1是显示地发送报文头部,方式2,3隐式的(隐式header模式)发送报文头。

res.headersSent = true

不能做什么:

  1. res.setHeader
  2. res.writeHead
  3. res.removeHeader

即发送headers后,不能再对header进行写的操作(新增,编辑,删除)。

能做什么:

  1. res.write
  2. res.end

即可以操作报文负载数据(payload)。

res.writableEnded & res.end的行为

writableEnded标记res.end是否已经执行。
res.end必须调用。

writableEnded = true之后

不能再写入数据了,否则报错ERR_STREAM_WRITE_AFTER_END。还可以继续调用res.end但是都是无效的,但是最好不要这样做。

res.writableEndedres.writableFinished区别?

res.writableEnded表示是否已经调用了res.end方法。
res.writableFinished表示数据是否已经发送完毕。

响应报文处理流程

一般情况下响应报文会经过这个处理流程:

  1. res.setHeader
  2. res.writeHead
  3. res.write
  4. res.end
  5. ...

隐式header模式(implicit header mode)?

即没有显示的调用writeHead设置报文首部就开始发送数据的场景。Nodejs会有默认的生成报文首部的逻辑。

  1. 状态码取res.statusCode属性(默认200)
  2. 状态描述取res.statusMessage属性,如果res.statusMessage没有值则取STATUS_CODES预定义的。
  3. 构建首部字段。

具体见ServerResponse.prototype._implicitHeader实现(即内部也是调用writeHead):

ServerResponse.prototype._implicitHeader = function _implicitHeader() {
  this.writeHead(this.statusCode);
};

参考

  1. Node.js response.setHeader() Method
  2. Node.js v12.22.7 Documentation
  3. Node.js v12.4.x _http_server.js
  4. How to use stream.pipe

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions