HTTP#

穩定性:2 - 穩定

原始碼: lib/http.js

若要使用 HTTP 伺服器和用戶端,必須 require('node:http')

Node.js 中的 HTTP 介面旨在支援協定的許多功能,而這些功能傳統上難以使用。特別是大型、可能分塊編碼的訊息。介面會小心地從不快取整個請求或回應,因此使用者可以串流資料。

HTTP 訊息標頭以類似下列物件表示

{ "content-length": "123",
  "content-type": "text/plain",
  "connection": "keep-alive",
  "host": "example.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', 'example.com',
  'accepT', '*/*' ] 

類別:http.Agent#

Agent 負責管理 HTTP 伺服器的連線持續性及重複使用。它會維護特定主機和埠的待處理要求佇列,重複使用單一 Socket 連線,直到佇列為空為止,此時 Socket 會被銷毀或放入池中,以供再次用於對相同主機和埠的要求。是否銷毀或放入池中取決於 keepAlive 選項

已放入池的連線已啟用 TCP Keep-Alive,但伺服器仍可能關閉閒置連線,此時連線會從池中移除,並在對該主機和埠進行新的 HTTP 要求時建立新的連線。伺服器也可能拒絕允許透過同一連線進行多個要求,此時連線必須針對每個要求重新建立,而且無法放入池中。Agent 仍會對該伺服器進行要求,但每個要求都會透過新的連線進行。

當連線由用戶端或伺服器關閉時,會從池中移除。池中所有未使用的 socket 都會解除參考,以避免在沒有未完成要求時讓 Node.js 程序繼續執行。(請參閱 socket.unref())。

在不再使用 Agent 執行個體時,建議 destroy() 該執行個體,因為未使用的 socket 會消耗作業系統資源。

當 socket 發出 'close' 事件或 'agentRemove' 事件時,會從 agent 中移除 socket。如果打算讓一個 HTTP 要求長時間保持開啟,但又不希望將其保留在 agent 中,可以執行類似下列的動作

http.get(options, (res) => {
  // Do stuff
}).on('socket', (socket) => {
  socket.emit('agentRemove');
}); 

也可以將 agent 用於個別要求。透過提供 {agent: false} 作為 http.get()http.request() 函式的選項,將會使用一次性的 Agent(採用預設選項)來進行用戶端連線。

agent:false:

http.get({
  hostname: 'localhost',
  port: 80,
  path: '/',
  agent: false,  // Create a new agent just for this one request
}, (res) => {
  // Do stuff with response
}); 

new Agent([options])#

  • options <Object> 可設定的選項組,用於設定 agent。可以包含下列欄位
    • keepAlive <布林> 即使沒有未完成的要求,也保留 Socket,以便在未來要求時使用,而無需重新建立 TCP 連線。請勿與 Connection 標頭的 keep-alive 值混淆。使用代理伺服器時,總是會傳送 Connection: keep-alive 標頭,除非明確指定 Connection 標頭,或將 keepAlivemaxSockets 選項分別設定為 falseInfinity,這種情況下將使用 Connection: close預設:false
    • keepAliveMsecs <數字> 使用 keepAlive 選項時,指定 TCP Keep-Alive 封包的初始延遲。當 keepAlive 選項為 falseundefined 時,將忽略此選項。預設:1000
    • maxSockets <數字> 允許每個主機使用的最大 Socket 數。如果同一個主機開啟多個同時連線,每個要求都會使用新的 Socket,直到達到 maxSockets 值。如果主機嘗試開啟的連線數超過 maxSockets,額外的要求將進入待處理要求佇列,並在現有連線終止時進入主動連線狀態。這可確保在任何時間點,來自特定主機的活躍連線數最多為 maxSockets預設:Infinity
    • maxTotalSockets <數字> 允許所有主機使用的最大 Socket 總數。每個要求都會使用新的 Socket,直到達到最大值。預設:Infinity
    • maxFreeSockets <數字> 允許每個主機保留在空閒狀態的最大 Socket 數。僅在 keepAlive 設定為 true 時才相關。預設:256
    • scheduling <字串> 選擇下一個可用的 socket 時套用的排程策略。可以是 'fifo''lifo'。兩種排程策略的主要差異在於 'lifo' 會選擇最近使用的 socket,而 'fifo' 會選擇最久未使用過的 socket。如果每秒請求率低,'lifo' 排程會降低選擇可能因閒置而被伺服器關閉的 socket 的風險。如果每秒請求率高,'fifo' 排程會將開啟的 socket 數量最大化,而 'lifo' 排程會將其保持在最低限度。預設值:'lifo'
    • timeout <數字> Socket 超時(毫秒)。這會在建立 socket 時設定超時。

socket.connect() 中的 options 也受支援。

http.request() 使用的預設 http.globalAgent 會將所有這些值設定為其各自的預設值。

若要設定其中任何一個,必須建立自訂 http.Agent 執行個體。

import { Agent, request } from 'node:http';
const keepAliveAgent = new Agent({ keepAlive: true });
options.agent = keepAliveAgent;
request(options, onResponseCallback);const http = require('node:http');
const keepAliveAgent = new http.Agent({ keepAlive: true });
options.agent = keepAliveAgent;
http.request(options, onResponseCallback);

agent.createConnection(options[, callback])#

產生要使用於 HTTP 請求的 socket/串流。

預設情況下,此函式與 net.createConnection() 相同。不過,自訂代理可能會覆寫此方法,以求更大的彈性。

可以透過兩種方式提供 socket/串流:從此函式傳回 socket/串流,或將 socket/串流傳遞給 callback

此方法保證回傳 <net.Socket> 類別的實例,<stream.Duplex> 的子類別,除非使用者指定 <net.Socket> 以外的 socket 類型。

callback 的簽章為 (err, stream)

agent.keepSocketAlive(socket)#

socket 從請求中分離出來,且可以由 Agent 持續存在時呼叫。預設行為為

socket.setKeepAlive(true, this.keepAliveMsecs);
socket.unref();
return true; 

此方法可以由特定的 Agent 子類別覆寫。如果此方法回傳假值,則會銷毀 socket,而不是持續存在以供下一個請求使用。

socket 參數可以是 <net.Socket> 的實例,<stream.Duplex> 的子類別。

agent.reuseSocket(socket, request)#

socket 附加到 request 之後,因為 keep-alive 選項而持續存在時呼叫。預設行為為

socket.ref(); 

此方法可以由特定的 Agent 子類別覆寫。

socket 參數可以是 <net.Socket> 的實例,<stream.Duplex> 的子類別。

agent.destroy()#

銷毀目前由 agent 使用中的任何 socket。

通常不需要執行此操作。但是,如果使用啟用 `keepAlive` 的代理程式,最好在不再需要時明確關閉代理程式。否則,在伺服器終止它們之前,Socket 可能會保持開啟很長一段時間。

agent.freeSockets#

一個物件,其中包含 Socket 陣列,這些 Socket 目前在啟用 `keepAlive` 時等待代理程式使用。請勿修改。

freeSockets 清單中的 Socket 將在 `'timeout'` 時自動銷毀並從陣列中移除。

agent.getName([options])#

  • options <Object> 提供用於產生名稱的資訊的一組選項
    • host <string> 要向其發出請求的伺服器的網域名稱或 IP 位址
    • port <number> 遠端伺服器的連接埠
    • localAddress <string> 在發出請求時用於網路連線的本機介面
    • family <integer> 如果不等於 `undefined`,則必須為 4 或 6。
  • 傳回:<string>

取得一組要求選項的唯一名稱,以確定是否可以重複使用連線。對於 HTTP 代理程式,這會傳回 host:port:localAddresshost:port:localAddress:family。對於 HTTPS 代理程式,名稱包括 CA、憑證、加密法和其他決定 socket 可重複使用性的 HTTPS/TLS 特定選項。

agent.maxFreeSockets#

預設設定為 256。對於啟用 keepAlive 的代理程式,這會設定將在空閒狀態下保持開啟的 socket 的最大數量。

agent.maxSockets#

預設設定為 Infinity。決定代理程式在每個來源可以開啟多少個並行 socket。來源是 agent.getName() 的傳回值。

agent.maxTotalSockets#

預設設定為 Infinity。決定代理程式可以開啟多少個並行 socket。與 maxSockets 不同,這個參數適用於所有來源。

agent.requests#

包含尚未指定給 socket 的要求佇列的物件。請勿修改。

agent.sockets#

包含目前由代理程式使用的 socket 陣列的物件。請勿修改。

類別:http.ClientRequest#

這個物件會在內部建立,並從 http.request() 傳回。它表示標頭已排入佇列的正在進行中要求。標頭仍然可以使用 setHeader(name, value)getHeader(name)removeHeader(name) API 進行變更。實際標頭會與第一個資料區塊一起傳送,或在呼叫 request.end() 時傳送。

若要取得回應,請為請求物件新增 'response' 的監聽器。'response' 會在收到回應標頭時從請求物件發出。 'response' 事件會執行一個引數,其為 http.IncomingMessage 的執行個體。

'response' 事件期間,可以為回應物件新增監聽器;特別是監聽 'data' 事件。

如果未新增 'response' 處理常式,則會完全捨棄回應。不過,如果新增 'response' 事件處理常式,則必須使用回應物件中的資料,方法是每當有 'readable' 事件時呼叫 response.read(),或新增 'data' 處理常式,或呼叫 .resume() 方法。在使用資料之前,'end' 事件不會觸發。此外,在讀取資料之前,它會使用記憶體,最終可能導致「處理序記憶體不足」錯誤。

為了向後相容,res 只有在註冊 'error' 監聽器時才會發出 'error'

設定 Content-Length 標頭以限制回應主體大小。如果 response.strictContentLength 設為 true,則不符合 Content-Length 標頭值會導致擲回 Error,由 code: 'ERR_HTTP_CONTENT_LENGTH_MISMATCH' 識別。

Content-Length 值應以位元組為單位,而非字元。使用 Buffer.byteLength() 來判斷主體的位元組長度。

事件:'abort'#

穩定性:0 - 已棄用。請改為監聽 'close' 事件。

當請求已被用戶端中止時觸發。此事件僅在第一次呼叫 abort() 時觸發。

事件:'close'#

表示請求已完成,或其底層連線已過早終止(在回應完成之前)。

事件:'connect'#

每當伺服器以 CONNECT 方法回應請求時觸發。如果未監聽此事件,則接收 CONNECT 方法的用戶端將關閉其連線。

此事件保證會傳遞 <net.Socket> 類別的執行個體,它是 <stream.Duplex> 的子類別,除非使用者指定 <net.Socket> 以外的 socket 類型。

用戶端和伺服器配對,展示如何監聽 'connect' 事件

import { createServer, request } from 'node:http';
import { connect } from 'node:net';
import { URL } from 'node:url';

// Create an HTTP tunneling proxy
const proxy = createServer((req, res) => {
  res.writeHead(200, { 'Content-Type': 'text/plain' });
  res.end('okay');
});
proxy.on('connect', (req, clientSocket, head) => {
  // Connect to an origin server
  const { port, hostname } = new URL(`http://${req.url}`);
  const serverSocket = connect(port || 80, hostname, () => {
    clientSocket.write('HTTP/1.1 200 Connection Established\r\n' +
                    'Proxy-agent: Node.js-Proxy\r\n' +
                    '\r\n');
    serverSocket.write(head);
    serverSocket.pipe(clientSocket);
    clientSocket.pipe(serverSocket);
  });
});

// Now that proxy is running
proxy.listen(1337, '127.0.0.1', () => {

  // Make a request to a tunneling proxy
  const options = {
    port: 1337,
    host: '127.0.0.1',
    method: 'CONNECT',
    path: 'www.google.com:80',
  };

  const req = request(options);
  req.end();

  req.on('connect', (res, socket, head) => {
    console.log('got connected!');

    // Make a request over an HTTP tunnel
    socket.write('GET / HTTP/1.1\r\n' +
                 'Host: www.google.com:80\r\n' +
                 'Connection: close\r\n' +
                 '\r\n');
    socket.on('data', (chunk) => {
      console.log(chunk.toString());
    });
    socket.on('end', () => {
      proxy.close();
    });
  });
});const http = require('node:http');
const net = require('node:net');
const { URL } = require('node:url');

// Create an HTTP tunneling proxy
const proxy = http.createServer((req, res) => {
  res.writeHead(200, { 'Content-Type': 'text/plain' });
  res.end('okay');
});
proxy.on('connect', (req, clientSocket, head) => {
  // Connect to an origin server
  const { port, hostname } = new URL(`http://${req.url}`);
  const serverSocket = net.connect(port || 80, hostname, () => {
    clientSocket.write('HTTP/1.1 200 Connection Established\r\n' +
                    'Proxy-agent: Node.js-Proxy\r\n' +
                    '\r\n');
    serverSocket.write(head);
    serverSocket.pipe(clientSocket);
    clientSocket.pipe(serverSocket);
  });
});

// Now that proxy is running
proxy.listen(1337, '127.0.0.1', () => {

  // Make a request to a tunneling proxy
  const options = {
    port: 1337,
    host: '127.0.0.1',
    method: 'CONNECT',
    path: 'www.google.com:80',
  };

  const req = http.request(options);
  req.end();

  req.on('connect', (res, socket, head) => {
    console.log('got connected!');

    // Make a request over an HTTP tunnel
    socket.write('GET / HTTP/1.1\r\n' +
                 'Host: www.google.com:80\r\n' +
                 'Connection: close\r\n' +
                 '\r\n');
    socket.on('data', (chunk) => {
      console.log(chunk.toString());
    });
    socket.on('end', () => {
      proxy.close();
    });
  });
});

事件:'continue'#

當伺服器傳送「100 繼續」HTTP 回應時觸發,通常是因為請求包含「Expect: 100-continue」。這項指令表示用戶端應傳送請求主體。

事件:'finish'#

當請求已傳送時觸發。更具體來說,此事件在回應標頭和主體的最後一段已傳遞給作業系統,以透過網路傳輸時觸發。這並不表示伺服器已收到任何內容。

事件:'information'#

當伺服器傳送 1xx 中間回應(排除 101 Upgrade)時觸發。此事件的監聽器會收到一個包含 HTTP 版本、狀態碼、狀態訊息、鍵值標頭物件,以及陣列(其中包含原始標頭名稱及其各自的值)的物件。

import { request } from 'node:http';

const options = {
  host: '127.0.0.1',
  port: 8080,
  path: '/length_request',
};

// Make a request
const req = request(options);
req.end();

req.on('information', (info) => {
  console.log(`Got information prior to main response: ${info.statusCode}`);
});const http = require('node:http');

const options = {
  host: '127.0.0.1',
  port: 8080,
  path: '/length_request',
};

// Make a request
const req = http.request(options);
req.end();

req.on('information', (info) => {
  console.log(`Got information prior to main response: ${info.statusCode}`);
});

由於 101 Upgrade 狀態會中斷傳統的 HTTP 請求/回應鏈(例如 WebSocket、原地的 TLS 升級或 HTTP 2.0),因此不會觸發此事件。若要接收 101 Upgrade 通知,請改為監聽 'upgrade' 事件。

事件:'response'#

當此請求收到回應時觸發。此事件只會觸發一次。

事件:'socket'#

此事件保證會傳遞 <net.Socket> 類別的執行個體,它是 <stream.Duplex> 的子類別,除非使用者指定 <net.Socket> 以外的 socket 類型。

事件:'timeout'#

當基礎 socket 因閒置而逾時時發出。這只會通知 socket 已閒置。必須手動銷毀請求。

另請參閱:request.setTimeout()

事件:'upgrade'#

每當伺服器以升級回應請求時發出。如果未偵聽此事件,且回應狀態碼為 101 切換協定,則接收升級標頭的客戶端會關閉其連線。

此事件保證會傳遞 <net.Socket> 類別的執行個體,它是 <stream.Duplex> 的子類別,除非使用者指定 <net.Socket> 以外的 socket 類型。

一個客戶端伺服器配對,展示如何偵聽 'upgrade' 事件。

import http from 'node:http';
import process from 'node:process';

// Create an HTTP server
const server = http.createServer((req, res) => {
  res.writeHead(200, { 'Content-Type': 'text/plain' });
  res.end('okay');
});
server.on('upgrade', (req, socket, head) => {
  socket.write('HTTP/1.1 101 Web Socket Protocol Handshake\r\n' +
               'Upgrade: WebSocket\r\n' +
               'Connection: Upgrade\r\n' +
               '\r\n');

  socket.pipe(socket); // echo back
});

// Now that server is running
server.listen(1337, '127.0.0.1', () => {

  // make a request
  const options = {
    port: 1337,
    host: '127.0.0.1',
    headers: {
      'Connection': 'Upgrade',
      'Upgrade': 'websocket',
    },
  };

  const req = http.request(options);
  req.end();

  req.on('upgrade', (res, socket, upgradeHead) => {
    console.log('got upgraded!');
    socket.end();
    process.exit(0);
  });
});const http = require('node:http');

// Create an HTTP server
const server = http.createServer((req, res) => {
  res.writeHead(200, { 'Content-Type': 'text/plain' });
  res.end('okay');
});
server.on('upgrade', (req, socket, head) => {
  socket.write('HTTP/1.1 101 Web Socket Protocol Handshake\r\n' +
               'Upgrade: WebSocket\r\n' +
               'Connection: Upgrade\r\n' +
               '\r\n');

  socket.pipe(socket); // echo back
});

// Now that server is running
server.listen(1337, '127.0.0.1', () => {

  // make a request
  const options = {
    port: 1337,
    host: '127.0.0.1',
    headers: {
      'Connection': 'Upgrade',
      'Upgrade': 'websocket',
    },
  };

  const req = http.request(options);
  req.end();

  req.on('upgrade', (res, socket, upgradeHead) => {
    console.log('got upgraded!');
    socket.end();
    process.exit(0);
  });
});

request.abort()#

穩定性:0 - 已棄用:改用 request.destroy()

將請求標記為中止。呼叫此函式會導致回應中剩餘資料被捨棄,且 socket 被銷毀。

request.aborted#

穩定性:0 - 已棄用。改檢查 request.destroyed

如果請求已中止,則 request.aborted 屬性會為 true

request.connection#

穩定性:0 - 已棄用。改用 request.socket

請參閱 request.socket

request.cork()#

請參閱 writable.cork()

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

完成傳送要求。如果主體的任何部分尚未傳送,它會將其沖刷到串流。如果要求是分塊的,這將傳送終止的 '0\r\n\r\n'

如果指定 data,它等於呼叫 request.write(data, encoding),然後是 request.end(callback)

如果指定 callback,它會在要求串流完成時呼叫。

request.destroy([error])#

  • error <Error> 選擇性,一個要與 'error' 事件發出的錯誤。
  • 傳回:<this>

銷毀請求。選擇性地發出 'error' 事件,並發出 'close' 事件。呼叫此函式將導致回應中剩餘的資料被捨棄,並銷毀 socket。

請參閱 writable.destroy() 以取得進一步的詳細資料。

request.destroyed#

在呼叫 request.destroy() 之後為 true

請參閱 writable.destroyed 以取得進一步的詳細資料。

request.finished#

穩定性:0 - 已標示為不建議使用。請使用 request.writableEnded

如果已呼叫 request.end()request.finished 屬性將為 true。如果請求是透過 http.get() 啟動,request.end() 將自動呼叫。

request.flushHeaders()#

刷新請求標頭。

基於效率考量,Node.js 通常會緩衝請求標頭,直到呼叫 request.end() 或寫入第一個區塊的請求資料。然後,它會嘗試將請求標頭和資料封裝成單一的 TCP 封包。

這通常是需要的(它可以節省 TCP 回應時間),但如果第一個資料直到很後才傳送,則不然。request.flushHeaders() 會繞過最佳化並啟動請求。

request.getHeader(name)#

讀取請求中的標頭。名稱不分大小寫。傳回值的類型取決於提供給 request.setHeader() 的參數。

request.setHeader('content-type', 'text/html');
request.setHeader('Content-Length', Buffer.byteLength(body));
request.setHeader('Cookie', ['type=ninja', 'language=javascript']);
const contentType = request.getHeader('Content-Type');
// 'contentType' is 'text/html'
const contentLength = request.getHeader('Content-Length');
// 'contentLength' is of type number
const cookie = request.getHeader('Cookie');
// 'cookie' is of type string[] 

request.getHeaderNames()#

傳回陣列,其中包含目前傳出標頭的唯一名稱。所有標頭名稱皆為小寫。

request.setHeader('Foo', 'bar');
request.setHeader('Cookie', ['foo=bar', 'bar=baz']);

const headerNames = request.getHeaderNames();
// headerNames === ['foo', 'cookie'] 

request.getHeaders()#

傳回目前傳出標頭的淺層拷貝。由於使用淺層拷貝,陣列值可以在未另外呼叫 http 模組方法的情況下進行變異。傳回物件的鍵為標頭名稱,值為對應的標頭值。所有標頭名稱皆為小寫。

request.getHeaders() 方法傳回的物件不會由 JavaScript Object 原型繼承。這表示典型的 Object 方法,例如 obj.toString()obj.hasOwnProperty() 等未定義,且無法使用

request.setHeader('Foo', 'bar');
request.setHeader('Cookie', ['foo=bar', 'bar=baz']);

const headers = request.getHeaders();
// headers === { foo: 'bar', 'cookie': ['foo=bar', 'bar=baz'] } 

request.getRawHeaderNames()#

傳回陣列,其中包含目前傳出原始標頭的唯一名稱。標頭名稱會傳回其確切大小寫。

request.setHeader('Foo', 'bar');
request.setHeader('Set-Cookie', ['foo=bar', 'bar=baz']);

const headerNames = request.getRawHeaderNames();
// headerNames === ['Foo', 'Set-Cookie'] 

request.hasHeader(name)#

如果由 name 識別的標頭目前在傳出的標頭中設定,則傳回 true。標頭名稱比對不區分大小寫。

const hasContentType = request.hasHeader('content-type'); 

request.maxHeadersCount#

限制最大回應標頭數量。如果設定為 0,則不套用限制。

request.path#

request.method#

request.host#

request.protocol#

request.removeHeader(name)#

移除已定義在標頭物件中的標頭。

request.removeHeader('Content-Type'); 

request.reusedSocket#

  • <boolean> 請求是否透過重複使用的 Socket 傳送。

透過啟用保持連線的代理伺服器傳送請求時,可能會重複使用基礎 Socket。但是,如果伺服器在不恰當的時間關閉連線,客戶端可能會遇到「ECONNRESET」錯誤。

import http from 'node:http';

// Server has a 5 seconds keep-alive timeout by default
http
  .createServer((req, res) => {
    res.write('hello\n');
    res.end();
  })
  .listen(3000);

setInterval(() => {
  // Adapting a keep-alive agent
  http.get('https://127.0.0.1:3000', { agent }, (res) => {
    res.on('data', (data) => {
      // Do nothing
    });
  });
}, 5000); // Sending request on 5s interval so it's easy to hit idle timeoutconst http = require('node:http');

// Server has a 5 seconds keep-alive timeout by default
http
  .createServer((req, res) => {
    res.write('hello\n');
    res.end();
  })
  .listen(3000);

setInterval(() => {
  // Adapting a keep-alive agent
  http.get('https://127.0.0.1:3000', { agent }, (res) => {
    res.on('data', (data) => {
      // Do nothing
    });
  });
}, 5000); // Sending request on 5s interval so it's easy to hit idle timeout

透過標記請求是否重複使用 Socket,我們可以根據此自動重試錯誤。

import http from 'node:http';
const agent = new http.Agent({ keepAlive: true });

function retriableRequest() {
  const req = http
    .get('https://127.0.0.1:3000', { agent }, (res) => {
      // ...
    })
    .on('error', (err) => {
      // Check if retry is needed
      if (req.reusedSocket && err.code === 'ECONNRESET') {
        retriableRequest();
      }
    });
}

retriableRequest();const http = require('node:http');
const agent = new http.Agent({ keepAlive: true });

function retriableRequest() {
  const req = http
    .get('https://127.0.0.1:3000', { agent }, (res) => {
      // ...
    })
    .on('error', (err) => {
      // Check if retry is needed
      if (req.reusedSocket && err.code === 'ECONNRESET') {
        retriableRequest();
      }
    });
}

retriableRequest();

request.setHeader(name, value)#

為標頭物件設定單一標頭值。如果此標頭已存在於待傳送標頭中,其值將會被取代。在此處使用字串陣列以傳送具有相同名稱的多個標頭。非字串值將會儲存而不修改。因此,request.getHeader() 可能會傳回非字串值。但是,非字串值將會轉換為字串以進行網路傳輸。

request.setHeader('Content-Type', 'application/json'); 

request.setHeader('Cookie', ['type=ninja', 'language=javascript']); 

當值為字串時,如果它包含 latin1 編碼以外的字元,將會擲回例外。

如果您需要在值中傳遞 UTF-8 字元,請使用 RFC 8187 標準對值進行編碼。

const filename = 'Rock 🎵.txt';
request.setHeader('Content-Disposition', `attachment; filename*=utf-8''${encodeURIComponent(filename)}`); 

request.setNoDelay([noDelay])#

一旦將 socket 指定給此要求並連接,就會呼叫 socket.setNoDelay()

request.setSocketKeepAlive([enable][, initialDelay])#

一旦將 socket 指定給此要求並連接,就會呼叫 socket.setKeepAlive()

request.setTimeout(timeout[, callback])#

一旦將 socket 指定給此要求並連接,就會呼叫 socket.setTimeout()

request.socket#

參考基礎 socket。通常使用者不會想要存取此屬性。特別是,socket 因為協定剖析器如何附加到 socket 而不會發出 'readable' 事件。

import http from 'node:http';
const options = {
  host: 'www.google.com',
};
const req = http.get(options);
req.end();
req.once('response', (res) => {
  const ip = req.socket.localAddress;
  const port = req.socket.localPort;
  console.log(`Your IP address is ${ip} and your source port is ${port}.`);
  // Consume response object
});const http = require('node:http');
const options = {
  host: 'www.google.com',
};
const req = http.get(options);
req.end();
req.once('response', (res) => {
  const ip = req.socket.localAddress;
  const port = req.socket.localPort;
  console.log(`Your IP address is ${ip} and your source port is ${port}.`);
  // Consume response object
});

此屬性保證是 <net.Socket> 類別的執行個體,<stream.Duplex> 的子類別,除非使用者指定 <net.Socket> 以外的 socket 類型。

request.uncork()#

請參閱 writable.uncork()

request.writableEnded#

在呼叫 request.end() 之後為 true。此屬性不會指出資料是否已快取,請改用 request.writableFinished

request.writableFinished#

如果所有資料已快取至基礎系統,則在發出 'finish' 事件之前立即為 true

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

傳送主體區塊。此方法可以呼叫多次。如果未設定 Content-Length,資料將自動以 HTTP 分塊傳輸編碼編碼,以便伺服器知道資料何時結束。會新增 Transfer-Encoding: chunked 標頭。呼叫 request.end() 是完成傳送要求的必要步驟。

encoding 參數是選用的,且僅在 chunk 是字串時套用。預設為 'utf8'

callback 參數是選用的,且僅在快取此區塊資料時呼叫,但前提是區塊非空值。

如果已將所有資料成功沖刷到核心緩衝區,則傳回 true。如果所有或部分資料已排入使用者記憶體中,則傳回 false。當緩衝區再次可用時,將發出 'drain'

當使用空字串或緩衝區呼叫 write 函式時,它不會執行任何動作,並等待更多輸入。

類別:http.Server#

事件:'checkContinue'#

每當收到具有 HTTP Expect: 100-continue 的要求時,就會發出此事件。如果未偵聽此事件,伺服器將自動適當地回應 100 Continue

處理此事件涉及呼叫 response.writeContinue()(如果客戶端應繼續傳送要求主體),或產生適當的 HTTP 回應(例如 400 錯誤要求),如果客戶端不應繼續傳送要求主體。

當此事件發出並處理時,將不會發出 'request' 事件。

事件:'checkExpectation'#

每次收到具有 HTTP Expect 標頭的請求時發出,其中值不是 100-continue。如果未偵聽此事件,伺服器會自動適當地回應 417 Expectation Failed

當此事件發出並處理時,將不會發出 'request' 事件。

事件:'clientError'#

如果客戶端連線發出 'error' 事件,會轉發到這裡。此事件的偵聽器負責關閉/銷毀基礎 socket。例如,有人可能希望使用自訂 HTTP 回應更優雅地關閉 socket,而不是突然切斷連線。在偵聽器結束之前,socket 必須關閉或銷毀

此事件保證會傳遞 <net.Socket> 類別的執行個體,它是 <stream.Duplex> 的子類別,除非使用者指定 <net.Socket> 以外的 socket 類型。

預設行為是嘗試使用 HTTP '400 錯誤的請求' 關閉 socket,或在 HPE_HEADER_OVERFLOW 錯誤的情況下使用 HTTP '431 請求標頭欄位過大'。如果 socket 不可寫入或已傳送目前附加的 http.ServerResponse 的標頭,則會立即銷毀。

socket 是錯誤來源的 net.Socket 物件。

import http from 'node:http';

const server = http.createServer((req, res) => {
  res.end();
});
server.on('clientError', (err, socket) => {
  socket.end('HTTP/1.1 400 Bad Request\r\n\r\n');
});
server.listen(8000);const http = require('node:http');

const server = http.createServer((req, res) => {
  res.end();
});
server.on('clientError', (err, socket) => {
  socket.end('HTTP/1.1 400 Bad Request\r\n\r\n');
});
server.listen(8000);

'clientError' 事件發生時,沒有 requestresponse 物件,因此任何傳送的 HTTP 回應,包括回應標頭和酬載,必須直接寫入 socket 物件。必須小心確保回應是格式正確的 HTTP 回應訊息。

errError 的一個實例,具有兩個額外欄位

  • bytesParsed:Node.js 可能已正確解析的請求封包的位元組計數;
  • rawPacket:目前請求的原始封包。

在某些情況下,用戶端已收到回應和/或套接字已毀損,例如在 ECONNRESET 錯誤的情況下。在嘗試將資料傳送至套接字之前,最好檢查它是否仍可寫入。

server.on('clientError', (err, socket) => {
  if (err.code === 'ECONNRESET' || !socket.writable) {
    return;
  }

  socket.end('HTTP/1.1 400 Bad Request\r\n\r\n');
}); 

事件:'close'#

伺服器關閉時發出。

事件:'connect'#

每次用戶端要求 HTTP CONNECT 方法時發出。如果未偵聽此事件,則要求 CONNECT 方法的用戶端將關閉其連線。

此事件保證會傳遞 <net.Socket> 類別的執行個體,它是 <stream.Duplex> 的子類別,除非使用者指定 <net.Socket> 以外的 socket 類型。

發出此事件後,請求的套接字將沒有 'data' 事件偵聽器,這表示需要繫結它才能處理在該套接字上傳送至伺服器的資料。

事件:'connection'#

建立新的 TCP 串流時發出此事件。socket 通常是 net.Socket 類型的物件。通常,使用者不希望存取此事件。特別是,由於通訊協定剖析器附加至套接字的方式,套接字不會發出 'readable' 事件。也可以在 request.socket 存取 socket

此事件也可由使用者明確發出,以將連線注入 HTTP 伺服器。在這種情況下,可以傳遞任何 Duplex 串流。

如果在此呼叫 socket.setTimeout(),當 socket 已提供服務要求時,逾時時間將會以 server.keepAliveTimeout 取代(如果 server.keepAliveTimeout 非零)。

此事件保證會傳遞 <net.Socket> 類別的執行個體,它是 <stream.Duplex> 的子類別,除非使用者指定 <net.Socket> 以外的 socket 類型。

事件:'dropRequest'#

當 socket 上的要求數量達到 server.maxRequestsPerSocket 的臨界值時,伺服器將會捨棄新的要求,並發出 'dropRequest' 事件,然後傳送 503 給用戶端。

事件:'request'#

每次有要求時發出。每個連線可能有多個要求(在 HTTP Keep-Alive 連線的情況下)。

事件:'upgrade'#

每次用戶端要求 HTTP 升級時發出。傾聽此事件是可選的,用戶端無法堅持變更協定。

發出此事件後,請求的套接字將沒有 'data' 事件偵聽器,這表示需要繫結它才能處理在該套接字上傳送至伺服器的資料。

此事件保證會傳遞 <net.Socket> 類別的執行個體,它是 <stream.Duplex> 的子類別,除非使用者指定 <net.Socket> 以外的 socket 類型。

server.close([callback])#

停止伺服器接受新連線,並關閉所有連線到此伺服器但未傳送要求或正在等待回應的連線。請參閱 net.Server.close()

server.closeAllConnections()#

關閉所有連線到此伺服器的連線。

server.closeIdleConnections()#

關閉所有連接到此伺服器但未傳送請求或等待回應的連線。

server.headersTimeout#

限制剖析器接收完整 HTTP 標頭的時間。

如果逾時,伺服器會回應狀態 408,而不會將請求轉發給請求監聽器,然後關閉連線。

必須設定為非零值(例如 120 秒),以防範潛在的阻斷服務攻擊,以防在伺服器前面未部署反向代理伺服器的情況下。

server.listen()#

啟動 HTTP 伺服器以監聽連線。此方法與 server.listen()net.Server 相同。

server.listening#

  • <boolean> 指示伺服器是否正在監聽連線。

server.maxHeadersCount#

限制最大傳入標頭數量。如果設定為 0,則不會套用限制。

server.requestTimeout#

設定從客戶端接收完整要求的逾時值(毫秒)。

如果逾時,伺服器會回應狀態 408,而不會將請求轉發給請求監聽器,然後關閉連線。

必須設定為非零值(例如 120 秒),以防範潛在的阻斷服務攻擊,以防在伺服器前面未部署反向代理伺服器的情況下。

server.setTimeout([msecs][, callback])#

設定 Socket 的逾時值,並在 Server 物件上發出 'timeout' 事件,如果發生逾時,則傳遞 Socket 作為引數。

如果 Server 物件上有 'timeout' 事件監聽器,則會呼叫它,並將逾時的 Socket 作為引數。

預設情況下,Server 沒有 Socket 逾時。但是,如果將 callback 指定給 Server 的 'timeout' 事件,則必須明確處理逾時。

server.maxRequestsPerSocket#

  • <數字> 每個 Socket 的要求。預設:0(無限制)

在關閉保持連線之前,Socket 可以處理的最大要求數。

0 的值會停用限制。

當達到限制時,它會將 Connection 標頭值設為 close,但不會實際關閉連線,在達到限制後傳送的後續要求會收到 503 服務無法使用 作為回應。

server.timeout#

  • <數字> 以毫秒為單位的逾時時間。預設值:0(無逾時)

在假設 Socket 已逾時的毫秒數。

0 的值會停用傳入連線的逾時行為。

Socket 逾時邏輯是在連線時設定的,因此變更此值只會影響伺服器的**新**連線,不會影響任何現有的連線。

server.keepAliveTimeout#

  • <數字> 以毫秒為單位的逾時時間。預設值:5000(5 秒)。

在伺服器完成寫入最後回應後,伺服器需要等待額外傳入資料的毫秒數,才會銷毀 Socket。如果伺服器在 keep-alive 逾時發生前收到新資料,它會重設一般非活動逾時,亦即 server.timeout

0 的值會停用傳入連線的 keep-alive 逾時行為。0 的值會讓 http 伺服器的行為類似於 8.0.0 之前的 Node.js 版本,這些版本沒有 keep-alive 逾時。

Socket 逾時邏輯是在連線時設定的,因此變更此值只會影響伺服器的**新**連線,不會影響任何現有的連線。

server[Symbol.asyncDispose]()#

穩定性:1 - 實驗性

呼叫 server.close() 並傳回一個 Promise,在伺服器關閉時完成。

類別:http.ServerResponse#

此物件是由 HTTP 伺服器在內部建立的,而非使用者建立。它會傳遞為 'request' 事件的第二個參數。

事件:'close'#

表示回應已完成,或其底層連線已過早終止(在回應完成之前)。

事件:'finish'#

在回應已傳送時發出。更具體地說,此事件在回應標頭和主體的最後一段已傳遞給作業系統以透過網路傳輸時發出。這並不表示客戶端已收到任何內容。

response.addTrailers(headers)#

此方法將 HTTP 拖曳標頭(標頭,但位於訊息結尾)新增到回應。

僅當對回應使用分段編碼時,才會發出拖曳標頭;如果沒有(例如,如果要求為 HTTP/1.0),則會靜默捨棄。

HTTP 要求傳送 Trailer 標頭才能發出拖曳標頭,其值中包含標頭欄位的清單。例如,

response.writeHead(200, { 'Content-Type': 'text/plain',
                          'Trailer': 'Content-MD5' });
response.write(fileData);
response.addTrailers({ 'Content-MD5': '7895bf4b8828b55ceaf47747b4bca667' });
response.end(); 

嘗試設定包含無效字元的標頭欄位名稱或值會導致擲出 TypeError

response.connection#

穩定性:0 - 已棄用。使用 response.socket

請參閱 response.socket

response.cork()#

請參閱 writable.cork()

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

此方法會對伺服器發出訊號,表示所有回應標頭和主體都已傳送;伺服器應將此訊息視為已完成。必須在每個回應上呼叫此方法 response.end()

如果指定 data,其效果類似於呼叫 response.write(data, encoding),接著呼叫 response.end(callback)

如果指定 callback,則會在回應串流完成時呼叫它。

response.finished#

穩定性:0 - 已過時。請使用 response.writableEnded

如果已呼叫 response.end(),則 response.finished 屬性會為 true

response.flushHeaders()#

強制輸出回應標頭。另請參閱:request.flushHeaders()

response.getHeader(name)#

讀取已排入佇列但尚未傳送給客戶端的標頭。此名稱不區分大小寫。傳回值的類型取決於提供給 response.setHeader() 的引數。

response.setHeader('Content-Type', 'text/html');
response.setHeader('Content-Length', Buffer.byteLength(body));
response.setHeader('Set-Cookie', ['type=ninja', 'language=javascript']);
const contentType = response.getHeader('content-type');
// contentType is 'text/html'
const contentLength = response.getHeader('Content-Length');
// contentLength is of type number
const setCookie = response.getHeader('set-cookie');
// setCookie is of type string[] 

response.getHeaderNames()#

傳回陣列,其中包含目前傳出標頭的唯一名稱。所有標頭名稱皆為小寫。

response.setHeader('Foo', 'bar');
response.setHeader('Set-Cookie', ['foo=bar', 'bar=baz']);

const headerNames = response.getHeaderNames();
// headerNames === ['foo', 'set-cookie'] 

response.getHeaders()#

傳回目前傳出標頭的淺層拷貝。由於使用淺層拷貝,陣列值可以在未另外呼叫 http 模組方法的情況下進行變異。傳回物件的鍵為標頭名稱,值為對應的標頭值。所有標頭名稱皆為小寫。

response.getHeaders() 方法傳回的物件不會從 JavaScript Object 原型繼承。這表示典型的 Object 方法(例如 obj.toString()obj.hasOwnProperty() 等)未定義,而且無法使用

response.setHeader('Foo', 'bar');
response.setHeader('Set-Cookie', ['foo=bar', 'bar=baz']);

const headers = response.getHeaders();
// headers === { foo: 'bar', 'set-cookie': ['foo=bar', 'bar=baz'] } 

response.hasHeader(name)#

如果由 name 識別的標頭目前在傳出的標頭中設定,則傳回 true。標頭名稱比對不區分大小寫。

const hasContentType = response.hasHeader('content-type'); 

response.headersSent#

布林值 (唯讀)。如果已傳送標頭,則為 True,否則為 False。

response.removeHeader(name)#

移除排隊準備隱式傳送的標頭。

response.removeHeader('Content-Encoding'); 

response.req#

指向原始 HTTP request 物件的參考。

response.sendDate#

如果標頭中尚未存在 Date 標頭,則為 True 時,系統會自動產生 Date 標頭並在回應中傳送。預設為 True。

這只應停用於測試;HTTP 在回應中需要 Date 標頭。

response.setHeader(name, value)#

傳回回應物件。

設定隱式標頭的單一標頭值。如果此標頭已存在於待傳送標頭中,其值將被取代。在此處使用字串陣列可傳送具有相同名稱的多個標頭。非字串值將儲存而不修改。因此,response.getHeader() 可能傳回非字串值。不過,非字串值將轉換為字串以進行網路傳輸。相同的回應物件會傳回給呼叫者,以啟用呼叫串接。

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

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

嘗試設定包含無效字元的標頭欄位名稱或值會導致擲出 TypeError

已使用 response.setHeader() 設定標頭後,這些標頭會與傳遞給 response.writeHead() 的任何標頭合併,優先順序為傳遞給 response.writeHead() 的標頭。

// Returns 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.writeHead() 方法,而尚未呼叫此方法,它會直接將提供的標頭值寫入網路頻道,而不會在內部快取,而標頭上的 response.getHeader() 將不會產生預期的結果。如果需要漸進式填充標頭,並可能在未來擷取和修改,請使用 response.setHeader() 代替 response.writeHead()

response.setTimeout(msecs[, callback])#

將 Socket 的逾時值設定為 msecs。如果提供回呼,則會將它新增為回應物件上 'timeout' 事件的監聽器。

如果未將 'timeout' 監聽器新增至要求、回應或伺服器,則 Socket 會在逾時時毀損。如果已將處理常式指派給要求、回應或伺服器的 'timeout' 事件,則必須明確處理逾時的 Socket。

response.socket#

參考基礎 Socket。通常使用者不會想要存取這個屬性。特別是,由於通訊協定剖析器附加到 Socket 的方式,Socket 因此不會發出 'readable' 事件。在 response.end() 之後,屬性會變為空值。

import http from 'node:http';
const server = http.createServer((req, res) => {
  const ip = res.socket.remoteAddress;
  const port = res.socket.remotePort;
  res.end(`Your IP address is ${ip} and your source port is ${port}.`);
}).listen(3000);const http = require('node:http');
const server = http.createServer((req, res) => {
  const ip = res.socket.remoteAddress;
  const port = res.socket.remotePort;
  res.end(`Your IP address is ${ip} and your source port is ${port}.`);
}).listen(3000);

此屬性保證是 <net.Socket> 類別的執行個體,<stream.Duplex> 的子類別,除非使用者指定 <net.Socket> 以外的 socket 類型。

response.statusCode#

當使用隱含標頭(未明確呼叫 response.writeHead())時,此屬性會控制在標頭被清除時傳送至客戶端的狀態碼。

response.statusCode = 404; 

在回應標頭傳送至客戶端後,此屬性會指出已傳送出的狀態碼。

response.statusMessage#

當使用隱含標頭(未明確呼叫 response.writeHead())時,此屬性控制在標頭沖刷時傳送給用戶端的狀態訊息。如果將此屬性保留為 undefined,則會使用狀態碼的標準訊息。

response.statusMessage = 'Not found'; 

在回應標頭傳送給用戶端後,此屬性會指出已傳送的狀態訊息。

response.strictContentLength#

如果設為 true,Node.js 會檢查 Content-Length 標頭值和主體大小(以位元組為單位)是否相等。如果 Content-Length 標頭值不符,則會引發 Error,其識別碼為 code: 'ERR_HTTP_CONTENT_LENGTH_MISMATCH'

response.uncork()#

請參閱 writable.uncork()

response.writableEnded#

在呼叫 response.end() 後為 true。此屬性不會指出資料是否已沖刷,請改用 response.writableFinished

response.writableFinished#

如果所有資料已快取至基礎系統,則在發出 'finish' 事件之前立即為 true

response.write(區塊[, 編碼][, 回呼函式])#

如果呼叫此方法且尚未呼叫 response.writeHead(),它將切換至隱式標頭模式並刷新隱式標頭。

這會傳送回應主體區塊。此方法可以多次呼叫,以提供主體的後續部分。

當要求方法或回應狀態不支援內容時,不允許寫入主體。如果嘗試寫入 HEAD 要求的主體或作為 204304 回應的一部分,將會擲出具有程式碼 ERR_HTTP_BODY_NOT_ALLOWED 的同步 Error

chunk 可以是字串或緩衝區。如果 chunk 是字串,第二個參數會指定如何將其編碼成位元組串流。當這區塊資料被刷新時,將會呼叫 callback

這是原始 HTTP 主體,與可能會使用的較高層級多部分主體編碼無關。

第一次呼叫 response.write() 時,它會將緩衝的標頭資訊和主體的第一個區塊傳送給用戶端。第二次呼叫 response.write() 時,Node.js 會假設資料會以串流方式傳輸,並分別傳送新資料。也就是說,回應會緩衝到主體的第一個區塊。

如果已將所有資料成功沖刷到核心緩衝區,則傳回 true。如果所有或部分資料已排入使用者記憶體中,則傳回 false。當緩衝區再次可用時,將發出 'drain'

response.writeContinue()#

傳送 HTTP/1.1 100 Continue 訊息給用戶端,表示應該傳送要求主體。請參閱 Server 上的 'checkContinue' 事件。

response.writeEarlyHints(hints[, callback])#

傳送 HTTP/1.1 103 早期提示訊息到用戶端,並附上 Link 標頭,表示使用者代理程式可以預先載入/預先連線連結的資源。hints 是包含早期提示訊息標頭值的物件。當回應訊息已寫入時,會呼叫選用的 callback 參數。

範例

const earlyHintsLink = '</styles.css>; rel=preload; as=style';
response.writeEarlyHints({
  'link': earlyHintsLink,
});

const earlyHintsLinks = [
  '</styles.css>; rel=preload; as=style',
  '</scripts.js>; rel=preload; as=script',
];
response.writeEarlyHints({
  'link': earlyHintsLinks,
  'x-trace-id': 'id for diagnostics',
});

const earlyHintsCallback = () => console.log('early hints message sent');
response.writeEarlyHints({
  'link': earlyHintsLinks,
}, earlyHintsCallback); 

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

傳送回應標頭到請求。狀態碼是 3 位數的 HTTP 狀態碼,例如 404。最後一個參數 headers 是回應標頭。選擇性地,可以提供人類可讀的 statusMessage 作為第二個參數。

headers 可以是 Array,其中鍵和值在同一個清單中。它不是元組清單。因此,偶數偏移量是鍵值,而奇數偏移量是關聯的值。陣列格式與 request.rawHeaders 相同。

傳回對 ServerResponse 的參考,以便可以串接呼叫。

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

此方法只能在訊息上呼叫一次,且必須在呼叫 response.end() 之前呼叫。

如果在呼叫此方法之前呼叫 response.write()response.end(),則會計算隱含式/可變動標頭並呼叫此函式。

已使用 response.setHeader() 設定標頭後,這些標頭會與傳遞給 response.writeHead() 的任何標頭合併,優先順序為傳遞給 response.writeHead() 的標頭。

如果呼叫此方法,且尚未呼叫 response.setHeader(),則會直接將提供的標頭值寫入網路頻道,而不會在內部進行快取,且標頭上的 response.getHeader() 將不會產生預期的結果。如果希望逐步填入標頭,並可能在未來進行擷取和修改,請改用 response.setHeader()

// Returns 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 是以位元組為單位讀取,而非字元。請使用 Buffer.byteLength() 來判斷主體的長度(以位元組為單位)。Node.js 會檢查 Content-Length 和已傳輸主體的長度是否相等。

嘗試設定包含無效字元的標頭欄位名稱或值,將會導致擲回 [Error][]。

response.writeProcessing()#

傳送 HTTP/1.1 102 Processing 訊息給用戶端,表示應傳送要求主體。

類別:http.IncomingMessage#

IncomingMessage 物件是由 http.Serverhttp.ClientRequest 建立,並分別作為 'request''response' 事件的第一個引數傳遞。它可用於存取回應狀態、標頭和資料。

與其 socket 值(為 <stream.Duplex> 的子類別)不同,IncomingMessage 本身會延伸 <stream.Readable>,並會個別建立以分析和發出接收到的 HTTP 標頭和酬載,因為在維持連線的情況下,底層 socket 可能會重複使用多次。

事件:'aborted'#

穩定性:0 - 已標示為不建議使用。請改為偵聽 'close' 事件。

在要求已中斷時發出。

事件:'close'#

在要求已完成時發出。

message.aborted#

穩定性:0 - 已標示為不建議使用。請從 <stream.Readable> 檢查 message.destroyed

如果要求已中斷,message.aborted 屬性會為 true

message.complete#

如果已收到並成功分析完整的 HTTP 訊息,message.complete 屬性會為 true

這個屬性特別適用於判斷在連線終止前,客戶端或伺服器是否已完整傳輸訊息

const req = http.request({
  host: '127.0.0.1',
  port: 8080,
  method: 'POST',
}, (res) => {
  res.resume();
  res.on('end', () => {
    if (!res.complete)
      console.error(
        'The connection was terminated while the message was still being sent');
  });
}); 

message.connection#

穩定性:0 - 已棄用。請使用 message.socket

message.socket 的別名。

message.destroy([error])#

在收到 IncomingMessage 的 socket 上呼叫 destroy()。如果提供 error,則會在 socket 上發出 'error' 事件,並將 error 傳遞為事件中任何監聽器的引數。

message.headers#

請求/回應標頭物件。

標頭名稱和值的關鍵字值對。標頭名稱以小寫字母表示。

// Prints something like:
//
// { 'user-agent': 'curl/7.22.0',
//   host: '127.0.0.1:8000',
//   accept: '*/*' }
console.log(request.headers); 

重複的原始標頭會根據標頭名稱以下列方式處理

  • ageauthorizationcontent-lengthcontent-typeetagexpiresfromhostif-modified-sinceif-unmodified-sincelast-modifiedlocationmax-forwardsproxy-authorizationrefererretry-afterserveruser-agent 的重複項會被捨棄。若要允許合併上述標頭的重複值,請在 http.request()http.createServer() 中使用選項 joinDuplicateHeaders。有關更多資訊,請參閱 RFC 9110 第 5.3 節。
  • set-cookie 永遠都是陣列。重複項會新增到陣列中。
  • 對於重複的 cookie 標頭,其值會以 ; 連接在一起。
  • 對於所有其他標頭,其值會以 , 連接在一起。

message.headersDistinct#

類似於 message.headers,但沒有連接邏輯,且值永遠都是字串陣列,即使標頭只收到一次。

// Prints something like:
//
// { 'user-agent': ['curl/7.22.0'],
//   host: ['127.0.0.1:8000'],
//   accept: ['*/*'] }
console.log(request.headersDistinct); 

message.httpVersion#

在伺服器要求的情況下,為用戶端傳送的 HTTP 版本。在用戶端回應的情況下,為連線伺服器的 HTTP 版本。可能是 '1.1''1.0'

另外,message.httpVersionMajor 為第一個整數,而 message.httpVersionMinor 為第二個整數。

message.method#

僅對從 http.Server 取得的要求有效。

要求方法,為字串。唯讀。範例:'GET''DELETE'

message.rawHeaders#

原始要求/回應標頭清單,與接收時完全相同。

金鑰和值在同一個清單中。它不是元組清單。因此,偶數偏移量為金鑰值,而奇數偏移量為關聯值。

標頭名稱未轉換為小寫,且重複項目未合併。

// Prints something like:
//
// [ 'user-agent',
//   'this is invalid because there can be only one',
//   'User-Agent',
//   'curl/7.22.0',
//   'Host',
//   '127.0.0.1:8000',
//   'ACCEPT',
//   '*/*' ]
console.log(request.rawHeaders); 

message.rawTrailers#

原始要求/回應預告鍵值,與接收到的內容完全相同。僅在 'end' 事件中填充。

message.setTimeout(msecs[, callback])#

呼叫 message.socket.setTimeout(msecs, callback)

message.socket#

與連線關聯的 net.Socket 物件。

使用 HTTPS 支援時,請使用 request.socket.getPeerCertificate() 取得客戶端的驗證詳細資料。

此屬性保證是 <net.Socket> 類別的執行個體,也就是 <stream.Duplex> 的子類別,除非使用者指定 <net.Socket> 以外的 socket 類型,或在內部將其設為 null。

message.statusCode#

僅對從 http.ClientRequest 取得的回應有效。

3 位數的 HTTP 回應狀態碼。例如:404

message.statusMessage#

僅對從 http.ClientRequest 取得的回應有效。

HTTP 回應狀態訊息(原因短語)。例如:OKInternal Server Error

message.trailers#

請求/回應預告物件。僅在 'end' 事件中填入。

message.trailersDistinct#

類似於 message.trailers,但沒有加入邏輯,而且值總是字串陣列,即使標頭只接收一次。僅在 'end' 事件中填入。

message.url#

僅對從 http.Server 取得的要求有效。

請求 URL 字串。這只包含實際 HTTP 請求中存在的 URL。以下為請求

GET /status?name=ryan HTTP/1.1
Accept: text/plain 

將 URL 解析成各個部分

new URL(request.url, `http://${request.headers.host}`); 

request.url'/status?name=ryan'request.headers.host'localhost:3000'

$ node
> new URL(request.url, `http://${request.headers.host}`)
URL {
  href: 'https://127.0.0.1:3000/status?name=ryan',
  origin: 'https://127.0.0.1:3000',
  protocol: 'http:',
  username: '',
  password: '',
  host: 'localhost:3000',
  hostname: 'localhost',
  port: '3000',
  pathname: '/status',
  search: '?name=ryan',
  searchParams: URLSearchParams { 'name' => 'ryan' },
  hash: ''
} 

類別:http.OutgoingMessage#

這個類別作為 http.ClientRequesthttp.ServerResponse 的父類別。從 HTTP 交易參與者的觀點來看,它是一個抽象的傳出訊息。

事件:'drain'#

當訊息的緩衝區再次釋放時發出。

事件:'finish'#

當傳輸成功完成時發出。

事件:'prefinish'#

在呼叫 outgoingMessage.end() 之後發出。當事件發出時,所有資料都已處理,但並非一定已完全清除。

outgoingMessage.addTrailers(headers)#

將 HTTP 預告(標頭,但位於訊息的結尾)新增到訊息中。

預告會在訊息是分塊編碼時發出。如果不是,預告將會在無聲中捨棄。

HTTP 要求傳送 Trailer 標頭才能發出預告,其值中包含標頭欄位名稱清單,例如

message.writeHead(200, { 'Content-Type': 'text/plain',
                         'Trailer': 'Content-MD5' });
message.write(fileData);
message.addTrailers({ 'Content-MD5': '7895bf4b8828b55ceaf47747b4bca667' });
message.end(); 

嘗試設定包含無效字元的標頭欄位名稱或值會導致擲出 TypeError

outgoingMessage.appendHeader(name, value)#

將單一標頭值附加到標頭物件。

如果值是陣列,這等於多次呼叫此方法。

如果標頭沒有先前的值,這等於呼叫 outgoingMessage.setHeader(name, value)

根據建立用戶端請求或伺服器時 options.uniqueHeaders 的值,這會導致標頭被傳送多次或只傳送一次,且值使用 ; 連結。

outgoingMessage.connection#

穩定性:0 - 已棄用:改用 outgoingMessage.socket

別名為 outgoingMessage.socket

outgoingMessage.cork()#

請參閱 writable.cork()

outgoingMessage.destroy([error])#

  • error <Error> 選擇性,一個與 error 事件一起發出的錯誤
  • 傳回:<this>

銷毀訊息。一旦一個 socket 與訊息關聯並連線,那個 socket 也會被銷毀。

outgoingMessage.end(chunk[, encoding][, callback])#

完成傳送訊息。如果訊息主體的任何部分尚未傳送,它將會將它們沖刷到底層系統。如果訊息是分塊的,它將會傳送終止分塊 0\r\n\r\n,並傳送尾端 (如果有)。

如果指定了 chunk,它等於呼叫 outgoingMessage.write(chunk, encoding),接著是 outgoingMessage.end(callback)

如果提供了 callback,它將會在訊息完成時被呼叫 (等於 'finish' 事件的監聽器)。

outgoingMessage.flushHeaders()#

沖刷訊息標頭。

出於效率的考量,Node.js 通常會緩衝訊息標頭,直到呼叫 outgoingMessage.end() 或寫入訊息資料的第一個區塊。然後它會嘗試將標頭和資料打包成一個單一的 TCP 封包。

這通常是需要的 (它可以節省一個 TCP 回合行程),但當第一個資料直到可能晚得多的時候才傳送時則不然。outgoingMessage.flushHeaders() 繞過最佳化並啟動訊息。

outgoingMessage.getHeader(name)#

取得具有指定名稱的 HTTP 標頭值。如果未設定該標頭,傳回值將為 undefined

outgoingMessage.getHeaderNames()#

傳回包含目前傳出標頭的唯一名稱的陣列。所有名稱皆為小寫。

outgoingMessage.getHeaders()#

傳回目前傳出標頭的淺層拷貝。由於使用淺層拷貝,陣列值可以在不額外呼叫各種標頭相關的 HTTP 模組方法的情況下進行變異。傳回物件的鍵是標頭名稱,值則是各自的標頭值。所有標頭名稱皆為小寫。

outgoingMessage.getHeaders() 方法傳回的物件不會從 JavaScript Object 原型繼承。這表示典型的 Object 方法(例如 obj.toString()obj.hasOwnProperty() 等)未定義且無法使用。

outgoingMessage.setHeader('Foo', 'bar');
outgoingMessage.setHeader('Set-Cookie', ['foo=bar', 'bar=baz']);

const headers = outgoingMessage.getHeaders();
// headers === { foo: 'bar', 'set-cookie': ['foo=bar', 'bar=baz'] } 

outgoingMessage.hasHeader(name)#

如果傳出標頭中目前設定由 name 識別的標頭,則傳回 true。標頭名稱不區分大小寫。

const hasContentType = outgoingMessage.hasHeader('content-type'); 

outgoingMessage.headersSent#

唯讀。如果標頭已傳送,則為 true,否則為 false

outgoingMessage.pipe()#

覆寫從舊版 Stream 類別繼承而來的 stream.pipe() 方法,http.OutgoingMessage 的父類別為 Stream

呼叫此方法會擲回 Error,因為 outgoingMessage 是唯寫串流。

outgoingMessage.removeHeader(name)#

移除已排隊準備隱式傳送的標頭。

outgoingMessage.removeHeader('Content-Encoding'); 

outgoingMessage.setHeader(name, value)#

設定單一標頭值。如果標頭已存在於待傳送標頭中,其值將會被取代。使用字串陣列來傳送具有相同名稱的多個標頭。

outgoingMessage.setHeaders(headers)#

傳回回應物件。

設定隱式標頭的多個標頭值。headers 必須是 HeadersMap 的執行個體,如果標頭已存在於待傳送標頭中,其值將會被取代。

const headers = new Headers({ foo: 'bar' });
response.setHeaders(headers); 

const headers = new Map([['foo', 'bar']]);
res.setHeaders(headers); 

當標頭已使用 outgoingMessage.setHeaders() 設定,它們會與傳遞給 response.writeHead() 的任何標頭合併,且傳遞給 response.writeHead() 的標頭優先。

// Returns content-type = text/plain
const server = http.createServer((req, res) => {
  const headers = new Headers({ 'Content-Type': 'text/html' });
  res.setHeaders(headers);
  res.writeHead(200, { 'Content-Type': 'text/plain' });
  res.end('ok');
}); 

outgoingMessage.setTimeout(msesc[, callback])#

  • msesc <number>
  • callback <Function> 當逾時發生時呼叫的選用函式。與繫結到 timeout 事件相同。
  • 傳回:<this>

一旦與訊息關聯的 socket 已經連線,socket.setTimeout() 將會使用 msecs 作為第一個參數呼叫。

outgoingMessage.socket#

參考基礎 socket。通常,使用者不會想要存取這個屬性。

在呼叫 outgoingMessage.end() 之後,這個屬性將會被設為 null。

outgoingMessage.uncork()#

請參閱 writable.uncork()

outgoingMessage.writableCorked#

呼叫 outgoingMessage.cork() 的次數。

outgoingMessage.writableEnded#

如果已呼叫 outgoingMessage.end(),則為 true。此屬性不會指出資料是否已快取。為此目的,請改用 message.writableFinished

outgoingMessage.writableFinished#

如果所有資料都已沖刷至底層系統,則為 true

outgoingMessage.writableHighWaterMark#

如果已指定,則為底層 socket 的 highWaterMark。否則,為 writable.write() 開始回傳 false 時的預設緩衝層級(16384)。

outgoingMessage.writableLength#

緩衝的位元組數。

outgoingMessage.writableObjectMode#

永遠為 false

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

傳送主體區塊。此方法可呼叫多次。

只有當 chunk 為字串時,encoding 參數才有意義。預設為 'utf8'

callback 參數為選用參數,當這區塊資料沖刷時將會呼叫此參數。

如果整個資料已成功沖刷至核心緩衝區,則傳回 true。如果所有或部分資料已在使用者記憶體中排隊,則傳回 false。當緩衝區再次可用時,將發出 'drain' 事件。

http.METHODS#

解析器支援的 HTTP 方法清單。

http.STATUS_CODES#

所有標準 HTTP 回應狀態碼的集合,以及每個狀態碼的簡短說明。例如,http.STATUS_CODES[404] === 'Not Found'

http.createServer([options][, requestListener])#

  • options <Object>

    • connectionsCheckingInterval:設定檢查不完整要求中要求和標頭逾時的時間間隔(以毫秒為單位)。預設:30000
    • headersTimeout:設定從用戶端接收完整 HTTP 標頭的逾時時間(以毫秒為單位)。有關更多資訊,請參閱 server.headersTimeout預設:60000
    • highWaterMark <number> 選擇性覆寫所有 socketreadableHighWaterMarkwritableHighWaterMark。這會影響 IncomingMessageServerResponsehighWaterMark 屬性。預設:請參閱 stream.getDefaultHighWaterMark()
    • insecureHTTPParser <boolean> 如果設為 true,它將使用啟用寬容標記的 HTTP 解析器。應避免使用不安全的解析器。有關更多資訊,請參閱 --insecure-http-parser預設:false
    • IncomingMessage <http.IncomingMessage> 指定要使用的 IncomingMessage 類別。對於擴充原始 IncomingMessage 很實用。預設:IncomingMessage
    • joinDuplicateHeaders <boolean> 如果設為 true,此選項允許將要求中多個標頭的欄位行值合併為逗號 (, ),而不是捨棄重複值。有關更多資訊,請參閱 message.headers預設:false
    • keepAlive <boolean> 如果設為 true,它會在收到新的傳入連線後立即在 socket 上啟用保持連線功能,類似於 [socket.setKeepAlive([enable][, initialDelay])][socket.setKeepAlive(enable, initialDelay)] 中執行的動作。預設:false
    • keepAliveInitialDelay <number> 如果設為正數,它會設定在閒置 socket 上傳送第一個保持連線探測之前的初始延遲。預設:0
    • keepAliveTimeout:伺服器在完成寫入最後回應後,需要等待額外傳入資料的毫秒數,才會銷毀 socket。有關詳細資訊,請參閱 server.keepAliveTimeout預設值:5000
    • maxHeaderSize <number> 針對此伺服器收到的要求,選擇性地覆寫 --max-http-header-size 的值,亦即要求標頭的最大長度(以位元組為單位)。預設值:16384(16 KiB)。
    • noDelay <boolean> 如果設為 true,它會在收到新的傳入連線後立即停用 Nagle 演算法。預設值:true
    • requestTimeout:設定從用戶端接收整個要求的逾時值(以毫秒為單位)。有關詳細資訊,請參閱 server.requestTimeout預設值:300000
    • requireHostHeader <boolean> 如果設為 true,它會強制伺服器對任何缺少 Host 標頭的 HTTP/1.1 要求訊息回應 400(錯誤的請求)狀態碼(如規格所規定)。預設值:true
    • ServerResponse <http.ServerResponse> 指定要使用的 ServerResponse 類別。這對於擴充原始的 ServerResponse 很實用。預設值:ServerResponse
    • uniqueHeaders <陣列> 應僅傳送一次的回應標頭清單。如果標頭值為陣列,則會使用 ; 將項目合併。
  • requestListener <函式>

  • 傳回:<http.Server>

傳回 http.Server 的新執行個體。

requestListener 是一個函式,會自動加入 'request' 事件。

import http from 'node:http';

// Create a local server to receive data from
const server = http.createServer((req, res) => {
  res.writeHead(200, { 'Content-Type': 'application/json' });
  res.end(JSON.stringify({
    data: 'Hello World!',
  }));
});

server.listen(8000);const http = require('node:http');

// Create a local server to receive data from
const server = http.createServer((req, res) => {
  res.writeHead(200, { 'Content-Type': 'application/json' });
  res.end(JSON.stringify({
    data: 'Hello World!',
  }));
});

server.listen(8000);
import http from 'node:http';

// Create a local server to receive data from
const server = http.createServer();

// Listen to the request event
server.on('request', (request, res) => {
  res.writeHead(200, { 'Content-Type': 'application/json' });
  res.end(JSON.stringify({
    data: 'Hello World!',
  }));
});

server.listen(8000);const http = require('node:http');

// Create a local server to receive data from
const server = http.createServer();

// Listen to the request event
server.on('request', (request, res) => {
  res.writeHead(200, { 'Content-Type': 'application/json' });
  res.end(JSON.stringify({
    data: 'Hello World!',
  }));
});

server.listen(8000);

http.get(options[, callback])#

http.get(url[, options][, callback])#

由於大多數要求都是沒有主體的 GET 要求,因此 Node.js 提供這個便利的方法。此方法與 http.request() 之間唯一的差異是,它預設將方法設定為 GET,並自動呼叫 req.end()。回呼必須注意使用回應資料,原因說明於 http.ClientRequest 區段中。

callback 會呼叫單一引數,該引數為 http.IncomingMessage 的執行個體。

JSON 擷取範例

http.get('https://127.0.0.1:8000/', (res) => {
  const { statusCode } = res;
  const contentType = res.headers['content-type'];

  let error;
  // Any 2xx status code signals a successful response but
  // here we're only checking for 200.
  if (statusCode !== 200) {
    error = new Error('Request Failed.\n' +
                      `Status Code: ${statusCode}`);
  } else if (!/^application\/json/.test(contentType)) {
    error = new Error('Invalid content-type.\n' +
                      `Expected application/json but received ${contentType}`);
  }
  if (error) {
    console.error(error.message);
    // Consume response data to free up memory
    res.resume();
    return;
  }

  res.setEncoding('utf8');
  let rawData = '';
  res.on('data', (chunk) => { rawData += chunk; });
  res.on('end', () => {
    try {
      const parsedData = JSON.parse(rawData);
      console.log(parsedData);
    } catch (e) {
      console.error(e.message);
    }
  });
}).on('error', (e) => {
  console.error(`Got error: ${e.message}`);
});

// Create a local server to receive data from
const server = http.createServer((req, res) => {
  res.writeHead(200, { 'Content-Type': 'application/json' });
  res.end(JSON.stringify({
    data: 'Hello World!',
  }));
});

server.listen(8000); 

http.globalAgent#

Agent 的全域執行個體,用作所有 HTTP 用戶端要求的預設值。

http.maxHeaderSize#

唯讀屬性,指定 HTTP 標頭的最大允許大小(以位元組為單位)。預設為 16 KiB。可使用 --max-http-header-size CLI 選項進行設定。

這可以透過傳遞 maxHeaderSize 選項來覆寫伺服器和用戶端要求。

http.request(options[, callback])#

http.request(url[, options][, callback])#

  • url <字串> | <URL>
  • options <Object>
    • agent <http.Agent> | <boolean> 控制 Agent 行為。可能的數值
      • undefined(預設):針對此主機和埠使用 http.globalAgent
      • Agent 物件:明確使用傳入的 Agent
      • false:導致使用具有預設值的全新 Agent
    • auth <string> 基本驗證('user:password')用於計算授權標頭。
    • createConnection <函式> 當未設定 agent 選項時,會產生一個用於請求的 socket/串流的函式。這可用於避免建立自訂 Agent 類別,只為了覆寫預設的 createConnection 函式。請參閱 agent.createConnection() 以取得更多詳細資料。任何 Duplex 串流都是有效的回傳值。
    • defaultPort <數字> 協定的預設埠。預設:如果使用 Agent,則為 agent.defaultPort,否則為 undefined
    • family <數字> 解析 hosthostname 時要使用的 IP 位址系列。有效值為 46。未指定時,將同時使用 IP v4 和 v6。
    • headers <物件> 包含請求標頭的物件。
    • hints <數字> 選擇性的 dns.lookup() 提示
    • host <字串> 要發出請求的伺服器之網域名稱或 IP 位址。預設:'localhost'
    • hostname <字串> host 的別名。為了支援 url.parse(),如果同時指定 hosthostname,將使用 hostname
    • insecureHTTPParser <布林值> 如果設為 true,它將使用啟用寬容標記的 HTTP 解析器。應避免使用不安全的解析器。請參閱 --insecure-http-parser 以取得更多資訊。預設:false
    • joinDuplicateHeaders <布林值> 它會將請求中多個標頭的欄位行值以 , 連結,而不是捨棄重複值。請參閱 message.headers 以取得更多資訊。預設值:false
    • localAddress <字串> 用於網路連線的本地介面。
    • localPort <數字> 用於連線的本地埠。
    • lookup <函式> 自訂查詢函式。預設值: dns.lookup()
    • maxHeaderSize <數字> 選擇性地覆寫 --max-http-header-size 的值(以位元組為單位的回應標頭最大長度),以接收來自伺服器的回應。預設值: 16384 (16 KiB)。
    • method <字串> 指定 HTTP 請求方法的字串。預設值: 'GET'
    • path <字串> 請求路徑。應包含查詢字串(如果有的話)。例如 '/index.html?page=12'。當請求路徑包含非法字元時,會擲回例外。目前,僅拒絕空白,但這可能會在未來變更。預設值: '/'
    • port <數字> 遠端伺服器的埠。預設值: 若已設定 defaultPort,則為 defaultPort,否則為 80
    • protocol <字串> 要使用的通訊協定。預設值: 'http:'
    • setHost <布林值>:指定是否自動加入 Host 標頭。預設為 true
    • signal <AbortSignal>:一個 AbortSignal,可用於中止正在進行的請求。
    • socketPath <string> Unix 域套接字。如果指定了 hostport 之一,則無法使用,因為它們指定 TCP 套接字。
    • timeout <number>:指定套接字逾時時間(毫秒)的數字。這將在套接字連線之前設定逾時時間。
    • uniqueHeaders <Array> 僅應傳送一次的請求標頭清單。如果標頭值是陣列,則會使用 ; 將項目合併。
  • callback <函式>
  • 傳回:<http.ClientRequest>

socket.connect() 中的 options 也受支援。

Node.js 每個伺服器維護多個連線以發出 HTTP 請求。此函數允許透明地發出請求。

url 可以是字串或 URL 物件。如果 url 是字串,則會自動使用 new URL() 進行解析。如果是 URL 物件,則會自動轉換為一般的 options 物件。

如果同時指定 urloptions,則會合併這些物件,其中 options 屬性優先。

可選的 callback 參數會新增為 'response' 事件的一次性監聽器。

http.request() 會傳回 http.ClientRequest 類別的執行個體。ClientRequest 執行個體是可寫入串流。如果需要使用 POST 請求上傳檔案,請寫入 ClientRequest 物件。

import http from 'node:http';
import { Buffer } from 'node:buffer';

const postData = JSON.stringify({
  'msg': 'Hello World!',
});

const options = {
  hostname: 'www.google.com',
  port: 80,
  path: '/upload',
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Content-Length': Buffer.byteLength(postData),
  },
};

const req = http.request(options, (res) => {
  console.log(`STATUS: ${res.statusCode}`);
  console.log(`HEADERS: ${JSON.stringify(res.headers)}`);
  res.setEncoding('utf8');
  res.on('data', (chunk) => {
    console.log(`BODY: ${chunk}`);
  });
  res.on('end', () => {
    console.log('No more data in response.');
  });
});

req.on('error', (e) => {
  console.error(`problem with request: ${e.message}`);
});

// Write data to request body
req.write(postData);
req.end();const http = require('node:http');

const postData = JSON.stringify({
  'msg': 'Hello World!',
});

const options = {
  hostname: 'www.google.com',
  port: 80,
  path: '/upload',
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Content-Length': Buffer.byteLength(postData),
  },
};

const req = http.request(options, (res) => {
  console.log(`STATUS: ${res.statusCode}`);
  console.log(`HEADERS: ${JSON.stringify(res.headers)}`);
  res.setEncoding('utf8');
  res.on('data', (chunk) => {
    console.log(`BODY: ${chunk}`);
  });
  res.on('end', () => {
    console.log('No more data in response.');
  });
});

req.on('error', (e) => {
  console.error(`problem with request: ${e.message}`);
});

// Write data to request body
req.write(postData);
req.end();

在範例中,呼叫了 req.end()。使用 http.request() 時,必須總是呼叫 req.end() 來表示請求結束,即使沒有資料寫入請求主體。

如果在請求期間遇到任何錯誤(可能是 DNS 解析、TCP 層級錯誤或實際 HTTP 解析錯誤),則會在傳回的請求物件上發出 'error' 事件。與所有 'error' 事件一樣,如果沒有註冊監聽器,則會擲回錯誤。

有一些特殊標頭應予注意。

  • 傳送「連線:保持連線」會通知 Node.js 與伺服器的連線應持續到下一個要求。

  • 傳送「內容長度」標頭會停用預設的區塊編碼。

  • 傳送「預期」標頭會立即傳送要求標頭。通常,在傳送「預期:100-繼續」時,應設定逾時和 'continue' 事件的監聽器。請參閱 RFC 2616 第 8.2.3 節以取得更多資訊。

  • 傳送授權標頭會覆寫使用 auth 選項來計算基本驗證。

使用 URL 作為 options 的範例

const options = new URL('http://abc:[email protected]');

const req = http.request(options, (res) => {
  // ...
}); 

在成功的要求中,以下事件將按以下順序發出

  • 'socket'
  • 'response'
    • 'data'res 物件上發出任意次數(如果回應主體為空,則根本不會發出 'data',例如在大部分重新導向中)
    • 'end'res 物件上
  • 'close'

在連線錯誤的情況下,將發出以下事件

  • 'socket'
  • 'error'
  • 'close'

在收到回應之前發生過早的連線關閉的情況下,以下事件將按以下順序發出

  • 'socket'
  • 'error' 錯誤訊息為 '錯誤:socket 掛斷',錯誤代碼為 'ECONNRESET'
  • 'close'

在收到回應之後發生過早的連線關閉的情況下,以下事件將按以下順序發出

  • 'socket'
  • 'response'
    • 'data'res 物件上發出任意次數
  • (在此處關閉連線)
  • 'aborted'res 物件上
  • 'error'res 物件上,錯誤訊息為 '錯誤:已中止',錯誤代碼為 'ECONNRESET'
  • 'close'
  • 'close'res 物件上

如果在指定 socket 之前呼叫 req.destroy(),以下事件將按以下順序發出

  • (在此呼叫 req.destroy())
  • 'error' 發生錯誤,訊息為 'Error: socket hang up',代碼為 'ECONNRESET',或 req.destroy() 被呼叫的錯誤
  • 'close'

如果在連線成功之前呼叫 req.destroy(),將按以下順序發出下列事件

  • 'socket'
  • (在此呼叫 req.destroy())
  • 'error' 發生錯誤,訊息為 'Error: socket hang up',代碼為 'ECONNRESET',或 req.destroy() 被呼叫的錯誤
  • 'close'

如果在收到回應後呼叫 req.destroy(),將按以下順序發出下列事件

  • 'socket'
  • 'response'
    • 'data'res 物件上發出任意次數
  • (在此呼叫 req.destroy())
  • 'aborted'res 物件上
  • 'error'res 物件上發生錯誤,訊息為 'Error: aborted',代碼為 'ECONNRESET',或 req.destroy() 被呼叫的錯誤
  • 'close'
  • 'close'res 物件上

如果在指定 socket 之前呼叫 req.abort(),將按以下順序發出下列事件

  • (在此呼叫 req.abort())
  • 'abort'
  • 'close'

如果在連線成功之前呼叫 req.abort(),將按以下順序發出下列事件

  • 'socket'
  • (在此呼叫 req.abort())
  • 'abort'
  • 'error' 錯誤訊息為 '錯誤:socket 掛斷',錯誤代碼為 'ECONNRESET'
  • 'close'

如果在收到回應後呼叫 req.abort(),將按以下順序發出下列事件

  • 'socket'
  • 'response'
    • 'data'res 物件上發出任意次數
  • (在此呼叫 req.abort())
  • 'abort'
  • 'aborted'res 物件上
  • 'error'res 物件上發生錯誤,訊息為 'Error: aborted',代碼為 'ECONNRESET'
  • 'close'
  • 'close'res 物件上

設定 timeout 選項或使用 setTimeout() 函式,不會中止請求或執行任何操作,除了新增 'timeout' 事件。

傳遞 AbortSignal,然後在對應的 AbortController 上呼叫 abort(),其行為與對請求呼叫 .destroy() 相同。具體來說,將發出 'error' 事件,其中包含訊息為 'AbortError: The operation was aborted'、代碼為 'ABORT_ERR'cause(如果已提供)的錯誤。

http.validateHeaderName(name[, label])#

對提供的 name 執行低階驗證,此驗證會在呼叫 res.setHeader(name, value) 時執行。

傳遞非法值作為 name 會導致擲出 TypeError,並由 code: 'ERR_INVALID_HTTP_TOKEN' 識別。

在將標頭傳遞至 HTTP 要求或回應之前,不需要使用此方法。HTTP 模組會自動驗證此類標頭。

範例

import { validateHeaderName } from 'node:http';

try {
  validateHeaderName('');
} catch (err) {
  console.error(err instanceof TypeError); // --> true
  console.error(err.code); // --> 'ERR_INVALID_HTTP_TOKEN'
  console.error(err.message); // --> 'Header name must be a valid HTTP token [""]'
}const { validateHeaderName } = require('node:http');

try {
  validateHeaderName('');
} catch (err) {
  console.error(err instanceof TypeError); // --> true
  console.error(err.code); // --> 'ERR_INVALID_HTTP_TOKEN'
  console.error(err.message); // --> 'Header name must be a valid HTTP token [""]'
}

http.validateHeaderValue(name, value)#

對提供的 value 執行低階驗證,此驗證會在呼叫 res.setHeader(name, value) 時執行。

傳遞非法值作為 value 會導致擲出 TypeError

  • 未定義值錯誤由 code: 'ERR_HTTP_INVALID_HEADER_VALUE' 識別。
  • 無效值字元錯誤由 code: 'ERR_INVALID_CHAR' 識別。

在將標頭傳遞至 HTTP 要求或回應之前,不需要使用此方法。HTTP 模組會自動驗證此類標頭。

範例

import { validateHeaderValue } from 'node:http';

try {
  validateHeaderValue('x-my-header', undefined);
} catch (err) {
  console.error(err instanceof TypeError); // --> true
  console.error(err.code === 'ERR_HTTP_INVALID_HEADER_VALUE'); // --> true
  console.error(err.message); // --> 'Invalid value "undefined" for header "x-my-header"'
}

try {
  validateHeaderValue('x-my-header', 'oʊmɪɡə');
} catch (err) {
  console.error(err instanceof TypeError); // --> true
  console.error(err.code === 'ERR_INVALID_CHAR'); // --> true
  console.error(err.message); // --> 'Invalid character in header content ["x-my-header"]'
}const { validateHeaderValue } = require('node:http');

try {
  validateHeaderValue('x-my-header', undefined);
} catch (err) {
  console.error(err instanceof TypeError); // --> true
  console.error(err.code === 'ERR_HTTP_INVALID_HEADER_VALUE'); // --> true
  console.error(err.message); // --> 'Invalid value "undefined" for header "x-my-header"'
}

try {
  validateHeaderValue('x-my-header', 'oʊmɪɡə');
} catch (err) {
  console.error(err instanceof TypeError); // --> true
  console.error(err.code === 'ERR_INVALID_CHAR'); // --> true
  console.error(err.message); // --> 'Invalid character in header content ["x-my-header"]'
}

http.setMaxIdleHTTPParsers(max)#

設定閒置 HTTP 剖析器的最大數量。