鍍金池/ 教程/ HTML/ HTTP
模塊
斷言測試
Buffer
Smalloc
TTY
概述
REPL
HTTP
DNS
路徑
集群
TLS/SSL
系統(tǒng)
加密
調(diào)試器
進(jìn)程
Punycode
虛擬機(jī)
HTTPS
網(wǎng)絡(luò)
Query String
C/C++ 插件
實(shí)用工具
文件系統(tǒng)
Zlib
子進(jìn)程
UDP/Datagram Sockets
定時(shí)器
逐行讀取
字符串解碼器
全局對象
事件
URL
控制臺

HTTP

穩(wěn)定性: 3 - 穩(wěn)定

使用 HTTP 服務(wù)器或客戶端功能必須調(diào)用 require('http')。

Node 里的 HTTP 接口支持協(xié)議里原本比較難用的特性。特別是很大的或塊編碼的消息。這些接口不會完全緩存整個(gè)請求或響應(yīng),這樣用戶可以在請求或響應(yīng)中使用數(shù)據(jù)流。

HTTP消息頭對象和下面的例子類似:

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

Keys 都是小寫,值不能修改。

為了能支持盡可能多的 HTTP 應(yīng)用程序,Node 提供的 HTTP API 接口都是底層的。僅能處理流和消息。它把消息解析成報(bào)文頭和報(bào)文體,但是不解析實(shí)際的報(bào)文頭和報(bào)文體內(nèi)容。

定義報(bào)文頭的時(shí)候,多個(gè)值間可用 , 分隔。除了 set-cookiecookie 頭,因?yàn)樗鼈儽硎局档臄?shù)組。諸如 content-length 的只有一個(gè)值的報(bào)文頭,直接解析,并且只有單值可以表示成已經(jīng)解析好的對象。

接收到的原始頭信息以數(shù)組([key, value, key2, value2, ...])的形式保存在 rawHeaders 里。例如,之前提到的消息對象會有如下的 rawHeaders

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

http.METHODS

  • {Array}

解析器支持的 HTTP 方法列表。

http.STATUS_CODES

  • {Object}

全部標(biāo)準(zhǔn) HTTP 響應(yīng)狀態(tài)碼的和描述的集合。例如,http.STATUS_CODES[404] === 'Not Found'。

http.createServer([requestListener])

返回 http.Server 的新實(shí)例。

requestListener 函數(shù)自動加到'request' 事件里。

http.createClient([port][, host])

這個(gè)函數(shù)已經(jīng)被拋棄,用 http.request() 替換。創(chuàng)建一個(gè)新的 HTTP 客戶端,連接到服務(wù)器的 porthost 。

類: http.Server

這是事件分發(fā)器 EventEmitter,有以下事件:

事件: 'request'

function (request, response) { }

每當(dāng)有請求的時(shí)候觸發(fā)。注意:每個(gè)連接可以有多個(gè)請求(在 keep-alive 連接中)。requesthttp.IncomingMessage 實(shí)例,responsehttp.ServerResponse 的實(shí)例。

事件: 'connection'

function (socket) { }

當(dāng)建立新的 TCP 流的時(shí)候。 socket 是一個(gè) net.Socket 對象。通常用戶不會訪問這個(gè)事件。協(xié)議解析器綁定套接字時(shí)采用的方式使套接字不會出發(fā) readable 事件。也能通過 request.connection 訪問 socket

事件: 'close'

function () { }

服務(wù)器關(guān)閉的時(shí)候觸發(fā)。

事件: 'checkContinue'

function (request, response) { }

當(dāng) http 收到 100-continue 的 http 請求時(shí)會觸發(fā)。如果沒有監(jiān)聽這個(gè)事件,服務(wù)器將會自動發(fā)送 100 Continue 的響應(yīng)。

如果客戶端需要繼續(xù)發(fā)送請求主題,或者生成合適的 HTTP 響應(yīng)(如,400 請求無效),可以通過調(diào)用 response.writeContinue() 來處理。

注意:觸發(fā)并處理這個(gè)事件的時(shí)候,不會再觸發(fā) request 事件。

事件: 'connect'

function (request, socket, head) { }

當(dāng)客戶端請求 http 連接時(shí)觸發(fā)。如果沒有監(jiān)聽這個(gè)事件,客戶端請求連接的時(shí)候會被關(guān)閉。

  • request 是 http 請求的參數(shù),與 request 事件參數(shù)相同。
  • socket 是服務(wù)器和客戶端間的 socket。
  • head 是 buffer 的實(shí)例。網(wǎng)絡(luò)隧道的第一個(gè)包,可能為空。

這個(gè)事件觸發(fā)后,請求的 socket 不會有 data 事件監(jiān)聽器,也就是說你需要綁定一個(gè)監(jiān)聽器到 data 上,來處理在發(fā)送到服務(wù)器上的 socket 數(shù)據(jù)。

事件: 'upgrade'

function (request, socket, head) { }

當(dāng)客戶端請求 http upgrage 時(shí)候會觸發(fā)。如果沒有監(jiān)聽這個(gè)事件,客戶端請求一個(gè)連接的時(shí)候會被關(guān)閉。

  • request 是 http 請求的參數(shù),與 request 事件參數(shù)相同。
  • socket 是服務(wù)器和客戶端間的 socket。
  • head 是 buffer 的實(shí)例。網(wǎng)絡(luò)隧道的第一個(gè)包,可能為空。

這個(gè)事件觸發(fā)后,請求的 socket 不會有 data 事件監(jiān)聽器,也就是說你需要綁定一個(gè)監(jiān)聽器到 data 上,來處理在發(fā)送到服務(wù)器上的 socket 數(shù)據(jù)。

事件: 'clientError'

function (exception, socket) { }

如果一個(gè)客戶端連接觸發(fā)了一個(gè) 'error' 事件, 它就會轉(zhuǎn)發(fā)到這里.

socket 是導(dǎo)致錯(cuò)誤的 net.Socket 對象。

server.listen(port[, hostname][, backlog][, callback])

在指定的的端口和主機(jī)名上開始接收連接。 如果忽略主機(jī)名,服務(wù)器將會接收指向任意 IPv4 的地址(INADDR_ANY)。

監(jiān)聽一個(gè) unix socket,需要提供一個(gè)文件名而不是主機(jī)名和端口。

積壓量 backlog 為等待連接隊(duì)列的最大長度。實(shí)際的長度由你的操作系統(tǒng)的 sysctl 設(shè)置決定(比如 linux 上的 tcp_max_syn_backlog and somaxconn)。默認(rèn)參數(shù)值為 511 (不是 512)

這是異步函數(shù)。最后一個(gè)參數(shù) callback 會作為事件監(jiān)聽器添加到 listening 事件。參見net.Server.listen(port)。

server.listen(path[, callback])

啟動一個(gè) UNIX socket 服務(wù)器所給路徑 path

這是異步函數(shù)。最后一個(gè)參數(shù) callback 會作為事件監(jiān)聽器添加到 listening事件。參見net.Server.listen(port)。

server.listen(handle[, callback])

  • handle {Object}
  • callback {Function}

    handle 對象可以是 server 或 socket(任意以下劃線 _handle開頭的成員),或者{fd: <n>}對象。

這會導(dǎo)致 server 用參數(shù) handle 接收連接,前提條件是文件描述符或句柄已經(jīng)連接到端口或域 socket。

Windows 不能監(jiān)聽文件句柄。

這是異步函數(shù)。最后一個(gè)參數(shù) callback 會作為事件監(jiān)聽器添加到 listening 事件。參見net.Server.listen(port)。

server.close([callback])

禁止 server 接收連接。參見 net.Server.close().

server.maxHeadersCount

最大請求頭的數(shù)量限制,默認(rèn) 1000。如果設(shè)置為 0,則不做任何限制。

server.setTimeout(msecs, callback)

  • msecs {Number}
  • callback {Function}

為 socket 設(shè)置超時(shí)時(shí)間,單位為毫秒,如果發(fā)生超時(shí),在 server 對象上觸發(fā) 'timeout' 事件,參數(shù)為 socket 。

如果在 Server 對象上有一個(gè) 'timeout' 事件監(jiān)聽器,超時(shí)的時(shí)候,將會調(diào)用它,參數(shù)為 socket 。

默認(rèn)情況下,Server 的超時(shí)為 2 分鐘,如果超時(shí)將會銷毀 socket。如果你給 Server 的超時(shí)事件設(shè)置了回調(diào)函數(shù),那你就得負(fù)責(zé)處理 socket 超時(shí)。

server.timeout

  • {Number} Default = 120000 (2 minutes)

超時(shí)的時(shí)長,單位為毫秒。

注意,socket 的超時(shí)邏輯在連接時(shí)設(shè)定,所以有新的連接時(shí)才能改變這個(gè)值。

設(shè)為 0 時(shí),建立連接的自動超時(shí)將失效。

類: http.ServerResponse

這是一個(gè)由 HTTP 服務(wù)器(而不是用戶)內(nèi)部創(chuàng)建的對象。作為第二個(gè)參數(shù)傳遞給 'request'事件。

該響應(yīng)實(shí)現(xiàn)了 Writable Stream 接口。這是一個(gè)包含下列事件的 EventEmitter

事件: 'close'

function () { }

在調(diào)用 response.end(),或準(zhǔn)備 flush 前,底層連接結(jié)束。

事件: 'finish'

function () { }

發(fā)送完響應(yīng)觸發(fā)。響應(yīng)頭和響應(yīng)體最后一段數(shù)據(jù)被剝離給操作系統(tǒng)后,通過網(wǎng)絡(luò)來傳輸時(shí)被觸發(fā)。這并不代表客戶端已經(jīng)收到數(shù)據(jù)。

這個(gè)事件之后,響應(yīng)對象不會再觸發(fā)任何事件。

response.writeContinue()

發(fā)送 HTTP/1.1 100 Continue 消息給客戶端,表示請求體可以發(fā)送??梢栽诜?wù)器上查看'checkContinue' 事件。

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

發(fā)送一個(gè)響應(yīng)頭給請求。狀態(tài)碼是 3 位數(shù)字,如 404。最后一個(gè)參數(shù) headers 是響應(yīng)頭。建議第二個(gè)參數(shù)設(shè)置為可以看的懂的消息。

例如:

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

這個(gè)方法僅能在消息中調(diào)用一次,而且必須在 response.end() 前調(diào)用。

如果你在這之前調(diào)用 response.write()response.end(),將會計(jì)算出不穩(wěn)定的頭。

Content-Length 是字節(jié)數(shù),而不是字符數(shù)。上面的例子 'hello world' 僅包含一個(gè)字節(jié)字符。如果 body 包含高級編碼的字符, Buffer.byteLength() 就必須確定指定編碼的字符數(shù)。Node 不會檢查Content-Length 和 body 的長度是否相同。

response.setTimeout(msecs, callback)

  • msecs {Number}
  • callback {Function}

設(shè)置 socket 超時(shí)時(shí)間,單位為毫秒。如果提供了回調(diào)函數(shù),將會在 response 對象的 'timeout' 事件上添加監(jiān)聽器。

如果沒有給請求、響應(yīng)、服務(wù)器添加 'timeout' 監(jiān)視器,超時(shí)的時(shí)候?qū)N毀 socket。如果你給請求、響應(yīng)、服務(wù)器加了處理函數(shù),就需要負(fù)責(zé)處理 socket 超時(shí)。

response.statusCode

使用默認(rèn)的 headers 時(shí)(沒有顯式的調(diào)用 response.writeHead() ),這個(gè)屬性表示將要發(fā)送給客戶端狀態(tài)碼。

例如:

response.statusCode = 404;

響應(yīng)頭發(fā)送給客戶端的后,這個(gè)屬性表示狀態(tài)碼已經(jīng)發(fā)送。

response.statusMessage

使用默認(rèn) headers 時(shí)(沒有顯式的調(diào)用 response.writeHead() ), 這個(gè)屬性表示將要發(fā)送給客戶端狀態(tài)信息。 如果這個(gè)沒有定義,將會使用狀態(tài)碼的標(biāo)準(zhǔn)消息。

例如:

response.statusMessage = 'Not found';

當(dāng)響應(yīng)頭發(fā)送給客戶端的時(shí)候,這個(gè)屬性表示狀態(tài)消息已經(jīng)發(fā)送。

response.setHeader(name, value)

設(shè)置默認(rèn)頭某個(gè)字段內(nèi)容。如果這個(gè)頭即將被發(fā)送,內(nèi)容會被替換。如果你想設(shè)置更多的頭, 就使用一個(gè)相同名字的字符串?dāng)?shù)組。

例如:

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

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

response.headersSent

Boolean (只讀)。如果headers發(fā)送完畢,則為 true,反之為 false。

response.sendDate

默認(rèn)值為 true。若為 true,當(dāng) headers 里沒有 Date 值時(shí),自動生成 Date 并發(fā)送。

只有在測試環(huán)境才能禁用; 因?yàn)?HTTP 要求響應(yīng)包含 Date 頭.

response.getHeader(name)

讀取一個(gè)在隊(duì)列中但是還沒有被發(fā)送至客戶端的header。名字是大小寫敏感。僅能再頭被flushed前調(diào)用。

例如:

var contentType = response.getHeader('content-type');

response.removeHeader(name)

從即將發(fā)送的隊(duì)列里移除頭。

例如:

response.removeHeader("Content-Encoding");

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

如果調(diào)用了這個(gè)方法,且還沒有調(diào)用 response.writeHead(),將會切換到默認(rèn)的 header,并更新這個(gè)header。

這個(gè)方法將發(fā)送響應(yīng)體數(shù)據(jù)塊??赡軙啻握{(diào)用這個(gè)方法,以提供 body 成功的部分內(nèi)容。

chunk 可以是字符串或 buffer。如果 chunk 是字符串,第二個(gè)參數(shù)表明如何將它編碼成字節(jié) 流。encoding 的默認(rèn)值是'utf8'。最后一個(gè)參數(shù)在刷新這個(gè)數(shù)據(jù)塊時(shí)調(diào)用。

注意:這個(gè)是原始的 HTTP body,和高級的multi-part body 編碼無關(guān)。

第一次調(diào)用 response.write() 的時(shí)候,將會發(fā)送緩存的頭信息和第一個(gè) body 給客戶端。第二次,將會調(diào)用 response.write()。Node 認(rèn)為你將會獨(dú)立發(fā)送流數(shù)據(jù)。這意味著,響應(yīng)緩存在第一個(gè)數(shù)據(jù)塊中。

如果成功的刷新全部數(shù)據(jù)到內(nèi)核緩沖區(qū),返回 true 。如果部分或全部數(shù)據(jù)在用戶內(nèi)存中還處于排隊(duì)狀況,返回 false 。當(dāng)緩存再次釋放的時(shí)候,將會觸發(fā) 'drain'

response.addTrailers(headers)

這個(gè)方法給響應(yīng)添加 HTTP 的尾部 header(消息末尾的 header)。

只有數(shù)據(jù)塊編碼用于響應(yīng)體時(shí),才會觸發(fā) Trailers;如果不是(例如,請求是HTTP/1.0),它們將會被自動丟棄。

如果你想觸發(fā) trailers, HTTP 會要求發(fā)送 Trailer 頭,它包含一些信息,比如:

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

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

這個(gè)方法告訴服務(wù)器,所有的響應(yīng)頭和響應(yīng)體已經(jīng)發(fā)送;服務(wù)器可以認(rèn)為消息結(jié)束。response.end() 方法必須在每個(gè)響應(yīng)中調(diào)用。

如果指定了參數(shù) data,將會在響應(yīng)流結(jié)束的時(shí)候調(diào)用。

http.request(options[, callback])

Node 維護(hù)每個(gè)服務(wù)器的連接來生成 HTTP 請求。這個(gè)函數(shù)讓你可以發(fā)布請求。

參數(shù)options是對象或字符串。如果 options 是字符串,會通過 url.parse() 自動解析。

options 值:

  • host: 請求的服務(wù)器域名或 IP 地址,默認(rèn):'localhost'
  • hostname: 用于支持 url.parse()。 hostname 優(yōu)于 host
  • port: 遠(yuǎn)程服務(wù)器端口。 默認(rèn): 80.
  • localAddress: 用于綁定網(wǎng)絡(luò)連接的本地接口
  • socketPath: Unix域 socket(使用host:port或socketPath
  • method: 指定 HTTP 請求方法。 默認(rèn): 'GET'.
  • path: 請求路徑。 默認(rèn): '/'。如果有查詢字符串,則需要包含。例如'/index.html?page=12'。請求路徑包含非法字符時(shí)拋出異常。目前,只有空格不行,不過在未來可能改變。
  • headers: 包含請求頭的對象
  • auth: 用于計(jì)算認(rèn)證頭的基本認(rèn)證,即 user:password
  • agent: 控制Agent的行為。當(dāng)使用了一個(gè)Agent的時(shí)候,請求將默認(rèn)為Connection: keep-alive??赡艿闹禐椋?
    • undefined (default): 在這個(gè)主機(jī)和端口上使用 global Agent
    • Agent object: 在Agent中顯式使用 passed .
    • false: 選擇性停用連接池,默認(rèn)請求為: Connection: close.
    • keepAlive: {Boolean} 持資源池周圍的socket,用于未來其它請求。默認(rèn)值為false。
    • keepAliveMsecs: {Integer} 使用HTTP KeepAlive 的時(shí)候,通過正在保持活動的sockets發(fā)送TCP KeepAlive包的頻繁程度。默認(rèn)值為1000。僅當(dāng)keepAlive為true時(shí)才相關(guān)。

可選參數(shù) callback 將會作為一次性的監(jiān)視器,添加給 'response' 事件。

http.request() 返回一個(gè) http.ClientRequest類的實(shí)例。ClientRequest實(shí)例是一個(gè)可寫流對象。如果需要用 POST 請求上傳一個(gè)文件的話,就將其寫入到ClientRequest對象。

例如:

var postData = querystring.stringify({
  'msg' : 'Hello World!'
});

var options = {
  hostname: 'www.google.com',
  port: 80,
  path: '/upload',
  method: 'POST',
  headers: {
    'Content-Type': 'application/x-www-form-urlencoded',
    'Content-Length': postData.length
  }
};

var req = http.request(options, function(res) {
  console.log('STATUS: ' + res.statusCode);
  console.log('HEADERS: ' + JSON.stringify(res.headers));
  res.setEncoding('utf8');
  res.on('data', function (chunk) {
    console.log('BODY: ' + chunk);
  });
});

req.on('error', function(e) {
  console.log('problem with request: ' + e.message);
});

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

注意,例子里調(diào)用了 req.end()。http.request() 必須調(diào)用 req.end() 來表明請求已經(jīng)完成,即使沒有數(shù)據(jù)寫入到請求 body 里。

如果在請求的時(shí)候遇到錯(cuò)誤(DNS 解析、TCP 級別的錯(cuò)誤或?qū)嶋H HTTP 解析錯(cuò)誤),在返回的請求對象時(shí)會觸發(fā)一個(gè) 'error' 事件。

有一些特殊的頭需要注意:

  • 發(fā)送 Connection: keep-alive 告訴服務(wù)器保持連接,直到下一個(gè)請求到來。

  • 發(fā)送 Content-length 頭將會禁用chunked編碼。

  • 發(fā)送一個(gè) Expect 頭,會立即發(fā)送請求頭,一般來說,發(fā)送 Expect: 100-continue ,你必須設(shè)置超時(shí),并監(jiān)聽 continue 事件。更多細(xì)節(jié)參見 RFC2616 Section 8.2.3 。

  • 發(fā)送一個(gè)授權(quán)頭,將會使用 auth 參數(shù)重寫,來計(jì)算基本的授權(quán)。

http.get(options[, callback])

因?yàn)槎鄶?shù)請求是沒有報(bào)文體的 GET 請求, Node 提供了這個(gè)簡便的方法。和 http.request() 唯一不同點(diǎn)在于,這個(gè)方法自動設(shè)置 GET,并自動調(diào)用 req.end()。

例如:

http.get("http://www.google.com/index.html", function(res) {
  console.log("Got response: " + res.statusCode);
}).on('error', function(e) {
  console.log("Got error: " + e.message);
});

類: http.Agent

HTTP Agent 用于 socket 池,用于 HTTP 客戶端請求。

HTTP Agent 也把客戶端請求默認(rèn)為使用 Connection:keep-alive 。如果沒有 HTTP 請求正在等著成為空閑 socket 的話,那么 socket 將關(guān)閉。這意味著,Node 的資源池在負(fù)載的情況下對 keep-alive 有利,但是仍然不需要開發(fā)人員使用 KeepAlive 來手動關(guān)閉 HTTP 客戶端。

如果你選擇使用 HTTP KeepAlive, 可以創(chuàng)建一個(gè) Agent 對象,將 flag 設(shè)置為 true. (參見下面的 constructor options ) ,這樣 Agent 會把沒用到的 socket 放到池里,以便將來使用。他們會被顯式的標(biāo)志,讓 Node 不運(yùn)行。但是,當(dāng)不再使用它的時(shí)候,需要顯式的調(diào)用destroy(),這樣 socket 將會被關(guān)閉。

當(dāng) socket 事件觸發(fā) close 事件或特殊的 agentRemove 事件時(shí),socket 將會從 agent 池里移除。如果你要保持 HTTP 請求保持長時(shí)間打開,并且不希望他們在池里,可以參考以下代碼:

http.get(options, function(res) {
  // Do stuff
}).on("socket", function (socket) {
  socket.emit("agentRemove");
});

另外,你可以使用 agent:false 讓資源池停用:

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

new Agent([options])

  • options {Object} agent 上的設(shè)置選項(xiàng)集合,有以下字段內(nèi)容:
    • keepAlive {Boolean} 持資源池周圍的 socket,用于未來其它請求。默認(rèn)值為 false。
    • keepAliveMsecs {Integer} 使用 HTTP KeepAlive 的時(shí)候,通過正在保持活動的 sockets 發(fā)送 TCP KeepAlive 包的頻繁程度。默認(rèn)值為 1000。僅當(dāng) keepAlive 為 true 時(shí)才相關(guān)。.】
    • maxSockets {Number} 在空閑狀態(tài)下,還依然開啟的 socket 的最大值。僅當(dāng) keepAlive 設(shè)置為 true 的時(shí)候有效。默認(rèn)值為 256。

http.request 使用的默認(rèn)的 http.globalAgent ,會設(shè)置全部的值為默認(rèn)。

必須在創(chuàng)建你自己的 Agent 對象后,才能配置這些值。

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

agent.maxSockets

默認(rèn)值為 Infinity。決定了每臺主機(jī)上的 agent 可以擁有的并發(fā) socket 的打開數(shù)量,主機(jī)可以是 host:porthost:port:localAddress。

agent.maxFreeSockets

默認(rèn)值 256. 對于支持 HTTP KeepAlive 的 Agent 而言,這個(gè)方法設(shè)置了空閑狀態(tài)下仍然打開的套接字?jǐn)?shù)的最大值。

agent.sockets

這個(gè)對象包含了當(dāng)前 Agent 使用中的 socket 數(shù)組。不要修改它。

agent.freeSockets

使用 HTTP KeepAlive 的時(shí)候,這個(gè)對象包含等待當(dāng)前 Agent 使用的 socket 數(shù)組。不要修改它。

agent.requests

這個(gè)對象包含了還沒分配給 socket 的請求數(shù)組。不要修改它。

agent.destroy()

銷毀任意一個(gè)被 agent 使用 的socket。

通常情況下不要這么做。如果你正在使用一個(gè)允許 KeepAlive 的 agent,當(dāng)你知道不在使用它的時(shí)候,最好關(guān)閉 agent。否則,socket 會一直保存打開狀態(tài),直到服務(wù)器關(guān)閉。

agent.getName(options)

獲取一組請求選項(xiàng)的唯一名,來確定某個(gè)連接是否可重用。在 http agent 里,它會返回 host:port:localAddress。在 http agent 里, name 包括 CA,cert, ciphers, 和其他 HTTPS/TLS 特殊選項(xiàng)來決定 socket 是否可以重用。

http.globalAgent

Agent 的全局實(shí)例,是 http 客戶端的默認(rèn)請求。

類: http.ClientRequest

該對象在內(nèi)部創(chuàng)建并從 http.request() 返回。他是 正在 處理的請求,其頭部已經(jīng)在隊(duì)列中。使用 setHeader(name, value), getHeader(name), removeHeader(name) API 可以改變header。當(dāng)關(guān)閉連接的時(shí)候,header將會和第一個(gè)數(shù)據(jù)塊一起發(fā)送。

為了獲取響應(yīng),可以給請求對象的 'response' 添加監(jiān)聽器。當(dāng)接收到響應(yīng)頭的時(shí)候?qū)恼埱髮ο罄镉|發(fā)'response''response' 事件執(zhí)行時(shí)有一個(gè)參數(shù),該參數(shù)為 http.IncomingMessage 的實(shí)例。

'response' 事件期間,可以給響應(yīng)對象添加監(jiān)視器,監(jiān)聽 'data' 事件。

如果沒有添加 'response' 處理函數(shù),響應(yīng)將被完全忽略。如果你添加了 'response' 事件處理函數(shù),那你 必須 消費(fèi)掉從響應(yīng)對象獲取的數(shù)據(jù),可以在 'readable' 事件里調(diào)用 response.read() ,或者添加一個(gè) 'data' 處理函數(shù),或者調(diào)用 .resume() 方法。如果未讀取數(shù)據(jù),它將會消耗內(nèi)存,最終產(chǎn)生 process out of memory 錯(cuò)誤。

Node 不會檢查 Content-Length 和 body 的長度是否相同。

該請求實(shí)現(xiàn)了 Writable Stream 接口。這是一個(gè)包含下列事件的 EventEmitter。

事件: 'response'

function (response) { }

當(dāng)接收到請求的時(shí)候會觸發(fā),僅會觸發(fā)一次。 response 的參數(shù)是 http.IncomingMessage 的實(shí)例。

Options:

  • host: 要請求的服務(wù)器域名或 IP 地址
  • port: 遠(yuǎn)程服務(wù)器的端口
  • socketPath: Unix 域 Socket (使用 host:port 或 socketPath 之一)

事件: 'socket'

function (socket) { }

Socket 附加到這個(gè)請求的時(shí)候觸發(fā)。

事件: 'connect'

function (response, socket, head) { }

每次服務(wù)器使用 CONNECT 方法響應(yīng)一個(gè)請求時(shí)觸發(fā)。如果這個(gè)這個(gè)事件未被監(jiān)聽,接收 CONNECT 方法的客戶端將關(guān)閉他們的連接。

下面的例子展示了一對匹配的客戶端/服務(wù)器如何監(jiān)聽 connect 事件。 var http = require('http'); var net = require('net'); var url = require('url');

// Create an HTTP tunneling proxy
var proxy = http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('okay');
});
proxy.on('connect', function(req, cltSocket, head) {
  // connect to an origin server
  var srvUrl = url.parse('http://' + req.url);
  var srvSocket = net.connect(srvUrl.port, srvUrl.hostname, function() {
    cltSocket.write('HTTP/1.1 200 Connection Established\r\n' +
                    'Proxy-agent: Node-Proxy\r\n' +
                    '\r\n');
    srvSocket.write(head);
    srvSocket.pipe(cltSocket);
    cltSocket.pipe(srvSocket);
  });
});

// now that proxy is running
proxy.listen(1337, '127.0.0.1', function() {

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

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

  req.on('connect', function(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', function(chunk) {
      console.log(chunk.toString());
    });
    socket.on('end', function() {
      proxy.close();
    });
  });
});

事件: 'upgrade'

function (response, socket, head) { }

每當(dāng)服務(wù)器響應(yīng) upgrade 請求時(shí)觸發(fā)。如果沒有監(jiān)聽這個(gè)事件,客戶端會收到 upgrade 頭后關(guān)閉連接。

下面的例子展示了一對匹配的客戶端/服務(wù)器如何監(jiān)聽 upgrade 事件。

var http = require('http');

// Create an HTTP server
var srv = http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('okay');
});
srv.on('upgrade', function(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
srv.listen(1337, '127.0.0.1', function() {

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

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

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

事件: 'continue'

function () { }

當(dāng)服務(wù)器發(fā)送 '100 Continue' HTTP 響應(yīng)的時(shí)候觸發(fā),通常因?yàn)檎埱蟀?'Expect: 100-continue'。該指令表示客戶端應(yīng)發(fā)送請求體。

request.flushHeaders()

刷新請求的頭。

考慮效率因素,Node.js 通常會緩存請求的頭直到你調(diào)用 request.end(),或?qū)懭胝埱蟮牡谝粋€(gè)數(shù)據(jù)塊。然后,包裝請求的頭和數(shù)據(jù)到一個(gè)獨(dú)立的 TCP 包里。

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

發(fā)送一個(gè)請求體的數(shù)據(jù)塊。通過多次調(diào)用這個(gè)函數(shù),用戶能流式的發(fā)送請求給服務(wù)器,這種情況下,建議使用['Transfer-Encoding', 'chunked'] 頭。

chunk 參數(shù)必須是 Buffer 或字符串。

回調(diào)參數(shù)可選,當(dāng)這個(gè)數(shù)據(jù)塊被刷新的時(shí)候會被調(diào)用。

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

發(fā)送請求完畢。如果 body 的數(shù)據(jù)沒被發(fā)送,將會將他們刷新到流里。如果請求是分塊的,該方法會發(fā)送終結(jié)符0\r\n\r\n 。

如果指定了 data,等同于先調(diào)用 request.write(data, encoding),再調(diào)用 request.end(callback)

如果有 callback,將會在請求流結(jié)束的時(shí)候調(diào)用。

request.abort()

終止一個(gè)請求. (v0.3.8 開始新加入)。

request.setTimeout(timeout[, callback])

如果 socket 被分配給這個(gè)請求,并完成連接,將會調(diào)用 socket.setTimeout() 。

request.setNoDelay([noDelay])

如果 socket 被分配給這個(gè)請求,并完成連接,將會調(diào)用 socket.setNoDelay()。

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

如果 socket 被分配給這個(gè)請求,并完成連接,將會調(diào)用 socket.setKeepAlive()。

http.IncomingMessage

http.Serverhttp.ClientRequest 創(chuàng)建了 IncomingMessage 對象,作為第一個(gè)參數(shù)傳遞給 'response'。它可以用來訪問應(yīng)答的狀態(tài),頭文件和數(shù)據(jù)。

它實(shí)現(xiàn)了 Readable Stream 接口,以及以下額外的事件,方法和屬性。

事件: 'close'

function () { }

表示底層連接已經(jīng)關(guān)閉。 和 'end'類似,這個(gè)事件每個(gè)應(yīng)答只會發(fā)送一次。

message.httpVersion

客戶端向服務(wù)器發(fā)送請求時(shí),客戶端發(fā)送的 HTTP 版本;或者服務(wù)器想客戶端返回應(yīng)答時(shí),服務(wù)器的 HTTP 版本。通常是 '1.1''1.0' 。

另外, response.httpVersionMajor 是第一個(gè)整數(shù),response.httpVersionMinor 是第二個(gè)整數(shù)。

message.headers

請求/響應(yīng)頭對象。

只讀的頭名稱和值的映射。頭的名字是小寫,比如:

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

message.rawHeaders

接收到的請求/響應(yīng)頭字段列表。

注意,鍵和值在同一個(gè)列表中。它并非一個(gè)元組列表。所以,偶數(shù)偏移量為鍵,奇數(shù)偏移量為對應(yīng)的值。

頭名字不是小寫敏感,也沒用合并重復(fù)的頭。 // 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.trailers

請求/響應(yīng) 的尾部對象。只在 'end' 事件中存在。

message.rawTrailers

接收到的原始的請求/響應(yīng)尾部鍵和值。僅在 'end' 事件中存在。

message.setTimeout(msecs, callback)

  • msecs {Number}
  • callback {Function}

調(diào)用 message.connection.setTimeout(msecs, callback).

message.method

僅對從 http.Server 獲得的請求有效。

請求方法如果一個(gè)只讀的字符串。 例如:'GET', 'DELETE'.

message.url

僅對從 http.Server 獲得的請求有效。

請求的 URL 字符串。它僅包含實(shí)際的 HTTP 請求中所提供的 URL,比如請求如下:

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

request.url 就是:

'/status?name=ryan'

如果你想將 URL 分解,可以用 require('url').parse(request.url),例如:

node> require('url').parse('/status?name=ryan')
{ href: '/status?name=ryan',
  search: '?name=ryan',
  query: 'name=ryan',
  pathname: '/status' }

如果想從查詢字符串中解析出參數(shù),可以用 require('querystring').parse 函數(shù),或者將true 作為第二個(gè)參數(shù)傳遞給 require('url').parse。 例如:

node> require('url').parse('/status?name=ryan', true)
{ href: '/status?name=ryan',
  search: '?name=ryan',
  query: { name: 'ryan' },
  pathname: '/status' }

message.statusCode

僅對從 http.ClientRequest 獲取的響應(yīng)有效。

3位數(shù)的 HTTP 響應(yīng)狀態(tài)碼 404。

message.statusMessage

僅對從 http.ClientRequest 獲取的響應(yīng)有效。

HTTP 的響應(yīng)消息。比如, OKInternal Server Error.

message.socket

和連接相關(guān)聯(lián)的 net.Socket 對象。

通過 HTTPS 支持,使用 request.connection.verifyPeer()request.connection.getPeerCertificate() 獲取客戶端的身份信息。

上一篇:Punycode下一篇:子進(jìn)程