Http

# http

要使用 HTTP 服务器与客户端,需要 require('http')

Node.js 中的 HTTP 接口被设计成支持协议的许多特性。 比如,大块编码的消息。 这些接口不缓冲完整的请求或响应,用户能够以流的形式处理数据。

HTTP 消息头由一个对象表示,例如:

{
    'content-length': '123',
    'content-type': 'text/plain',
    'connection': 'keep-alive',
    'host': 'mysite.com',
    'accept': '*/*'
}

键名是小写的,键值不能修改。

为了支持各种可能的 HTTP 应用,Node.js 的 HTTP API 是非常底层的。 它只涉及流处理与消息解析。 它把一个消息解析成消息头和消息主体,但不解析具体的消息头或消息主体。

查看 message.headers 了解如何处理重复的消息头。

接收到的原始消息头保存在 rawHeaders 属性中,它是一个 [key, value, key2, value2, ...] 数组。 例如,上面的消息头对象有一个类似以下的 rawHeaders 列表:

[
    'ConTent-Length', '123456',
    'content-LENGTH', '123',
    'content-type', 'text/plain',
    'CONNECTION', 'keep-alive',
    'Host', 'mysite.com',
    'accepT', '*/*'
]

# http.Agent 类

# http.ClientRequest 类

# http.Server 类

# http.ServerResponse 类

# response.setHeader(name, value)

为一个隐式的响应头设置值。 如果该响应头已存在,则值会被覆盖。 如果要发送多个名称相同的响应头,则使用字符串数组。

例子:

response.setHeader('Content-Type', 'text/html');

response.setHeader('Set-Cookie', ['type=ninja', 'language=javascript']);

如果响应头字段的名称或值包含无效字符,则抛出 TypeError 错误。

response.setHeader() 设置的响应头会与 response.writeHead() 设置的响应头合并,且 response.writeHead() 的优先。

// 返回 content-type = text/plain
const server = http.createServer((req, res) => {
  res.setHeader('Content-Type', 'text/html');
  res.setHeader('X-Foo', 'bar');
  res.writeHead(200, { 'Content-Type': 'text/plain' });
  res.end('ok');
});

# response.end([data][, encoding][, callback])

该方法会通知服务器,所有响应头和响应主体都已被发送,即服务器将其视为已完成。

每次响应都必须调用 response.end() 方法

如果指定了 data,则相当于调用 response.write(data, encoding) 之后再调用 response.end(callback)

如果指定了 callback,则当响应流结束时被调用。

# response.write(chunk[, encoding][, callback])

如果该方法被调用且 response.writeHead() 没有被调用,则它会切换到隐式响应头模式并刷新隐式响应头。

该方法会发送一块响应主体。 它可被多次调用,以便提供连续的响应主体片段。

请注意在http模块中,当请求是HEAD请求时,响应主体被省略。 类似地,204304响应 不能 包括消息体。

chunk 可以是一个字符串或一个 buffer。 如果 chunk 是一个字符串,则第二个参数指定如何将它编码成一个字节流。 encoding 默认为 'utf8'。 当数据块被刷新时,callback 会被调用。

注意:这是原始的 HTTP 主体,且与可能被使用的高级主体编码无关。

response.write() 首次被调用时,会发送缓冲的响应头信息和响应主体的第一块数据到客户端。 response.write() 第二次被调用时,Node.js 能够确定数据会被接收,于是开始传输新数据。 也就是说,响应的完成取决于响应主体的第一块数据。

如果全部数据被成功刷新到内核缓冲区,则返回 true。 如果全部或部分数据还在内存中排队,则返回 false。 当缓冲区再次空闲时,则触发 'drain' 事件。

# response.writeHead(statusCode[, statusMessage][, headers])

发送一个响应头给请求。 状态码是一个三位数的 HTTP 状态码,如 404。 最后一个参数 headers 是响应头。 第二个参数 statusMessage 是可选的状态描述。

例子:

const body = 'hello world';
response.writeHead(200, {
  'Content-Length': Buffer.byteLength(body),
  'Content-Type': 'text/plain' });

该方法在消息中只能被调用一次,且必须在 response.end() 被调用之前调用。

如果在调用该方法之前调用 response.write()response.end(),则隐式的响应头会被处理并调用该函数。

response.setHeader() 设置的响应头会与 response.writeHead() 设置的响应头合并,且 response.writeHead() 的优先。

// 返回 content-type = text/plain
const server = http.createServer((req, res) => {
  res.setHeader('Content-Type', 'text/html');
  res.setHeader('X-Foo', 'bar');
  res.writeHead(200, { 'Content-Type': 'text/plain' });
  res.end('ok');
});

注意,Content-Length 是以字节(而不是字符)为单位的。 上面的例子行得通是因为字符串 'hello world' 只包含单字节字符。 如果响应主体包含高级编码的字符,则应使用 Buffer.byteLength() 来确定在给定编码中的字节数。 Node.js 不会检查 Content-Length 与已发送的响应主体的长度是否相同。

如果响应头字段的名称或值包含无效字符,则抛出 TypeError 错误。