你必須通過require('http')
來使用HTTP服務(wù)器和客戶端。
io.js
中的HTTP接口被設(shè)置來支持許多HTTP協(xié)議里原本用起來很困難的特性。特別是大且成塊的有編碼的消息。這個接口從不緩沖整個請求或響應(yīng)。用戶可以對它們使用流。
HTTP消息頭可能是一個類似于以下例子的對象:
{ 'content-length': '123',
'content-type': 'text/plain',
'connection': 'keep-alive',
'host': 'mysite.com',
'accept': '*/*' }
鍵是小寫的。值沒有被修改。
為了全方位的支持所有的HTTP應(yīng)用。io.js
的HTTP API是非常底層的。它只處理流以及解釋消息。它將消息解釋為消息頭和消息體,但是不解釋實際的消息頭和消息體。
被定義的消息頭允許以多個,
字符分割,除了set-cookie
和cookie
頭,因為它們表示值得數(shù)組。如content-length
這樣只有單個值的頭被直接將解析,并且成為解析后對象的一個單值。
收到的原始消息頭會被保留在rawHeaders
屬性中,它是一個形式如[key, value, key2, value2, ...]
的數(shù)組。例如,之前的消息頭可以有如下的rawHeaders
:
[ 'ConTent-Length', '123456',
'content-LENGTH', '123',
'content-type', 'text/plain',
'CONNECTION', 'keep-alive',
'Host', 'mysite.com',
'accepT', '*/*' ]
一個被解析器所支持的HTTP方法的列表。
一個所有標(biāo)準(zhǔn)HTTP響應(yīng)狀態(tài)碼的集合,以及它們的簡短描述。例如,http.STATUS_CODES[404] === 'Not Found'
。
http.Server
實例requestListener
是一個會被自動添加為request
事件監(jiān)聽器的函數(shù)。
這個函數(shù)已經(jīng)被啟用。請使用http.request()
替代。構(gòu)造一個新的HTTP客戶端。port
和host
指定了需要連接的目標(biāo)服務(wù)器。
這是一個具有以下事件的EventEmitter
:
當(dāng)有請求來到時觸發(fā)。注意每一個連接可能有多個請求(在長連接的情況下)。請求是一個http.IncomingMessage
實例,響應(yīng)是一個http.ServerResponse
實例。
當(dāng)一個新的TCP流建立時觸發(fā)。socket
是一個net.Socket
類型的實例。用戶通常不會接觸這個事件。特別的,因為協(xié)議解釋器綁定它的方式,socket
將不會觸發(fā)readable
事件。這個socket
可以由request.connection
得到。
當(dāng)服務(wù)器關(guān)閉時觸發(fā)。
當(dāng)每次收到一個HTTPExpect: 100-continue
請求時觸發(fā)。如果不監(jiān)聽這個事件,那么服務(wù)器會酌情自動響應(yīng)一個100 Continue
。
處理該事件時,如果客戶端可以繼續(xù)發(fā)送請求主體則調(diào)用response.writeContinue()
, 如果不能則生成合適的HTTP響應(yīng)(如400 Bad Request
)。
注意,當(dāng)這個事件被觸發(fā)并且被處理,request
事件則不會再觸發(fā)。
每當(dāng)客戶端發(fā)起一個httpCONNECT
請求時觸發(fā)。如果這個事件沒有被監(jiān)聽,那么客戶端發(fā)起httpCONNECT
的連接會被關(guān)閉。
request
是一個http請求參數(shù),它也被包含在request
事件中。socket
是一個服務(wù)器和客戶端間的網(wǎng)絡(luò)套接字。head
是一個Buffer
實例,隧道流中的第一個報文,該參數(shù)可能為空在這個事件被觸發(fā)后,請求的socket
將不會有data
事件的監(jiān)聽器,意味著你將要綁定一個data
事件的監(jiān)聽器來處理這個socket
中發(fā)往服務(wù)器的數(shù)據(jù)。
每當(dāng)客戶端發(fā)起一個httpupgrade
請求時觸發(fā)。如果這個事件沒有被監(jiān)聽,那么客戶端發(fā)起upgrade
的連接會被關(guān)閉。
request
是一個http請求參數(shù),它也被包含在request
事件中。socket
是一個服務(wù)器和客戶端間的網(wǎng)絡(luò)套接字。head
是一個Buffer
實例,升級后流中的第一個報文,該參數(shù)可能為空在這個事件被觸發(fā)后,請求的socket
將不會有data
事件的監(jiān)聽器,意味著你將要綁定一個data
事件的監(jiān)聽器來處理這個socket
中發(fā)往服務(wù)器的數(shù)據(jù)。
如果一個客戶端連接發(fā)生了錯誤,這個事件將會被觸發(fā)。
socket
是一個錯誤來源的net.Socket
對象。
從指定的端口和主機名開始接收連接。如果hostname
被忽略,那么如果IPv6可用,服務(wù)器將接受任意IPv6地址(::),否則為任何IPv4地址(0.0.0.)。port
為0
將會設(shè)置一個隨機端口。
如果要監(jiān)聽一個unix socket
,請?zhí)峁┮粋€文件名而不是端口和主機名。
backlog
是連接等待隊列的最大長度。它的實際長度將有你操作系統(tǒng)的sysctl
設(shè)置(如linux中的tcp_max_syn_backlog
和somaxconn
)決定。默認(rèn)值為511
(不是512
)。
這個函數(shù)式異步的。最后一個callback
參數(shù)將會添加至listening
事件的監(jiān)聽器。參閱net.Server.listen(port)
。
通過給定的path
,開啟一個監(jiān)聽連接的 UNIX socket
服務(wù)器。
這個函數(shù)式異步的。最后一個callback
參數(shù)將會添加至listening
事件的監(jiān)聽器。參閱net.Server.listen(path)
。
handle
對象是既可以是一個server可以是一個socket
(或者任意以下劃線開頭的成員_handle
),或一個{fd: <n>}
對象。
這將使得服務(wù)器使用指定句柄接受連接,但它假設(shè)文件描述符或句柄已經(jīng)被綁定至指定的端口或域名socket
。
在Windows下不支持監(jiān)聽一個文件描述符。
這個函數(shù)式異步的。最后一個callback
參數(shù)將會添加至listening
事件的監(jiān)聽器。參閱net.Server.listen()
。
讓服務(wù)器停止接收新的連接。參閱net.Server.close()
。
限制最大請求頭數(shù)量,默認(rèn)為1000
。如果設(shè)置為0
,則代表無限制。
設(shè)置socket
的超時值,并且如果超時,會在服務(wù)器對象上觸發(fā)一個timeout
事件,并且將傳遞socket
作為參數(shù)。
如果在服務(wù)器對象時又一個timeout
事件監(jiān)聽器,那么它將會被調(diào)用,而超時的socket
將會被作為參數(shù)。
默認(rèn)的,服務(wù)器的超時值是兩分鐘,并且如果超時,socket
會被自動銷毀。但是,如果你給timeout
事件傳遞了回調(diào)函數(shù),那么你必須為要親自處理socket
超時。
返回一個server
對象。
120000
(兩分鐘)一個socket
被判定為超時之前的毫秒數(shù)。
注意,socket
的超時邏輯在連接時被設(shè)定,所以改變它的值僅影響之后到達(dá)服務(wù)器的連接,而不是所有的連接。
設(shè)置為0
將會為連接禁用所有的自動超時行為。
這個對象由HTTP服務(wù)器內(nèi)部創(chuàng)建,而不是由用戶。它會被傳遞給request
事件監(jiān)聽器的第二個參數(shù)。
這個對象實現(xiàn)了Writable
流接口。它是一個具有以下事件的EventEmitter
:
表明底層的連接在response.end()
被調(diào)用或能夠沖刷前被關(guān)閉。
當(dāng)響應(yīng)被設(shè)置時觸發(fā)。更明確地說,這個事件在當(dāng)響應(yīng)頭的最后一段和響應(yīng)體為了網(wǎng)絡(luò)傳輸而交給操作系統(tǒng)時觸發(fā)。它并不表明客戶端已經(jīng)收到了任何信息。
這個事件之后,response
對象不會再觸發(fā)任何事件。
給客戶端傳遞一個HTTP/1.1 100 Continue
信息,表明請求體必須被傳遞。參閱服務(wù)器的checkContinue
事件。
為請求設(shè)置一個響應(yīng)頭。statusCode
是一個三位的HTTP狀態(tài)碼,如404
。最后一個參數(shù)headers
,是響應(yīng)頭。第二個參數(shù)statusMessage
是可選的,表示狀態(tài)碼的一個可讀信息。
例子:
var body = 'hello world';
response.writeHead(200, {
'Content-Length': body.length,
'Content-Type': 'text/plain' });
這個方法對于一個信息只能調(diào)用一次,并且它必須在response.end()
之前被調(diào)用。
如果你在調(diào)用這個方法前調(diào)用了response.write()
或response.end()
,將會調(diào)用這個函數(shù),并且一個implicit/mutable
頭會被計算使用。
注意,Content-Length
是以字節(jié)計,而不是以字符計。上面例子能正常運行時因為字符串'hello world'
僅包含單字節(jié)字符。如果響應(yīng)體包含了多字節(jié)編碼的字符,那么必須通過指定的編碼來調(diào)用Buffer.byteLength()
來確定字節(jié)數(shù)。并且io.js
不會檢查Content-Length
與響應(yīng)體的字節(jié)數(shù)是否相等。
設(shè)置socket
的超時值(毫秒),如果傳遞了回調(diào)函數(shù),那么它將被添加至response
對象的timeout
事件的監(jiān)聽器。
如果沒有為request
,request
或服務(wù)器添加timeout
監(jiān)聽器。那么socket
會在超時時銷毀。如果你為request
,request
或服務(wù)器添加了timeout
監(jiān)聽器,那么你必須為要親自處理socket
超時。
返回一個response
對象。
當(dāng)使用隱式響應(yīng)頭(不明確調(diào)用response.writeHead()
)時,這個屬性控制了發(fā)送給客戶端的狀態(tài)碼,在當(dāng)響應(yīng)頭被沖刷時。
例子:
response.statusCode = 404;
在響應(yīng)頭發(fā)送給客戶端之后,這個屬性表明了被發(fā)送的狀態(tài)碼。
當(dāng)使用隱式響應(yīng)頭(不明確調(diào)用response.writeHead()
)時,這個屬性控制了發(fā)送給客戶端的狀態(tài)信息,在當(dāng)響應(yīng)頭被沖刷時。當(dāng)它沒有被指定(undefined
)時,將會使用標(biāo)準(zhǔn)HTTP狀態(tài)碼信息。
例子:
response.statusMessage = 'Not found';
在響應(yīng)頭發(fā)送給客戶端之后,這個屬性表明了被發(fā)送的狀態(tài)信息。
為一個隱式的響應(yīng)頭設(shè)置一個單獨的頭內(nèi)容。如果這個頭已存在,那么將會被覆蓋。當(dāng)你需要發(fā)送一個同名多值的頭內(nèi)容時請使用一個字符串?dāng)?shù)組。
例子:
response.setHeader("Content-Type", "text/html");
//or
response.setHeader("Set-Cookie", ["type=ninja", "language=javascript"]);
布爾值(只讀)。如果響應(yīng)頭被發(fā)送則為true
,反之為false
。
當(dāng)為true
時,當(dāng)響應(yīng)頭中沒有Date
值時會被自動設(shè)置。默認(rèn)為true
。
這個值只會為了測試目的才會被禁用。HTTP協(xié)議要求響應(yīng)頭中有Date
值。
讀取已經(jīng)被排隊但還未發(fā)送給客戶端的響應(yīng)頭。注意name
是大小寫敏感的。這個函數(shù)只能在響應(yīng)頭被隱式?jīng)_刷前被調(diào)用。
例子:
var contentType = response.getHeader('content-type');
取消一個在隊列中等待隱式發(fā)送的頭。
例子:
response.removeHeader("Content-Encoding");
如果這個方法被調(diào)用并且response.writeHead()
沒有備調(diào)用,那么它將轉(zhuǎn)換到隱式響應(yīng)頭模式,并且刷新隱式響應(yīng)頭。
這個方法傳遞一個數(shù)據(jù)塊的響應(yīng)體。這個方法可能被調(diào)用多次來保證連續(xù)的提供響應(yīng)體。
數(shù)據(jù)塊可以是一個字符串或一個buffer
。如果數(shù)據(jù)塊是一個字符串,那么第二個參數(shù)是它的編碼。默認(rèn)是UTF-8.最后一個回調(diào)函數(shù)參數(shù)會在數(shù)據(jù)塊被沖刷后觸發(fā)。注意:這是一個底層的HTTP報文,高級的多部分報文編碼無法使用。
第一次調(diào)用response.write()
時,它會傳遞緩存的頭信息以及第一個報文給客戶端。第二次調(diào)用時,io.js
假設(shè)你將發(fā)送數(shù)據(jù)流,然后分別發(fā)送。這意味著響應(yīng)式緩沖到第一個報文的數(shù)據(jù)塊中。
如果整個數(shù)據(jù)都成功得沖刷至內(nèi)核緩沖,則放回true
。如果用戶內(nèi)存中有部分或全部的數(shù)據(jù)在隊列中,那么返回false
。drain
事件將會在緩沖再次釋放時觸發(fā)。
這個方法添加HTTP尾隨頭(一個在消息最后的頭)給響應(yīng)。
只有當(dāng)數(shù)據(jù)編碼被用于響應(yīng)時尾隨才會觸發(fā)。如果不是(如請求是HTTP/1.0
),它們將被安靜地丟棄。
注意,如果你要觸發(fā)尾隨消息,HTTP要求傳遞一個包含報文頭場列表的尾隨頭:
response.writeHead(200, { 'Content-Type': 'text/plain',
'Trailer': 'Content-MD5' });
response.write(fileData);
response.addTrailers({'Content-MD5': "7895bf4b8828b55ceaf47747b4bca667"});
response.end();
這個方法告知服務(wù)器所有的響應(yīng)頭和響應(yīng)體都已經(jīng)發(fā)送;服務(wù)器會認(rèn)為這個消息完成了。這個方法必須在每次響應(yīng)完成后被調(diào)用。
如果指定了data
,就相當(dāng)于調(diào)用了response.write(data, encoding)
之后再調(diào)用response.end(callback)
。
如果指定了回調(diào)函數(shù),那么它將在響應(yīng)流結(jié)束后觸發(fā)。
io.js
為每個服務(wù)器維護(hù)了幾個連接,用來產(chǎn)生HTTP請求。這函數(shù)允許你透明地發(fā)送請求。
options
參數(shù)可以是一個對象或一個字符串,如果options
是一個字符串,它將自動得被url.parse()
翻譯。
Options:
localhost
。host
的別名。為了支持url.parse()
的話,hostname
比host
更好些。host
和hostname
時的IP地址協(xié)議族。合法值是4
和6
。當(dāng)沒有指定時,將都被使用。80
。socket
(使用host:port
或socketPath
)。GET
。/
。如果有查詢字符串,則需要包含。例如'/index.html?page=12'。請求路徑包含非法字符時拋出異常。目前,只否決空格,不過在未來可能改變。'user:password'
。agent: 控制agent
行為。當(dāng)使用一個代理時,請求將默認(rèn)為Connection: keep-alive
??赡苤涤校?/p>
agent
中顯示使用passed。agent
的連接池。默認(rèn)請求為Connection: close
。可選的回調(diào)函數(shù)將會被添加為response
事件的“一次性”監(jiān)聽器(one time listener)。
http.request()
返回一個http.ClientRequest
類的實例。這個ClientRequest
實例是一個可寫流。如果你需要使用POST
請求上傳一個文件,那么就將之寫入這個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);
});
res.on('end', function() {
console.log('No more data in response.')
})
});
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ù)要被寫入請求體)。
如果有一個錯誤在請求時發(fā)生(如DNS解析,TCP級別錯誤或?qū)嶋H的HTTP解析錯誤),一個error
事件將會在返回對象上觸發(fā)。
下面有一些特殊的需要主要的請求頭:
發(fā)送'Connection: keep-alive'
會告知io.js
保持連直到下一個請求發(fā)送。
發(fā)送'Content-length'
頭會禁用默認(rèn)的數(shù)據(jù)塊編碼。
發(fā)送'Expect'
頭將會立刻發(fā)送一個請求頭。通常,當(dāng)發(fā)送'Expect: 100-continue'
時,你需要同時設(shè)置一個超時和監(jiān)聽后續(xù)的時間。參閱RFC2616的8.2.3章節(jié)來獲取更多信息。
發(fā)送一個授權(quán)頭將會覆蓋使用auth
選項來進(jìn)行基本授權(quán)。
由于大多數(shù)請求是沒有請求體的GET
請求。io.js
提供了這個簡便的方法。這個方法和http.request()
方法的唯一區(qū)別是它設(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客戶端請求中的socket
做成池。
HTTP Agent 也把客戶端的請求默認(rèn)為使用Connection:keep-alive
。如果沒有HTTP請求正在等待成為空閑的套接字的話,那么套接字將關(guān)閉。這意味著io.js
的資源池在負(fù)載的情況下對keep-alive
有利,但是仍然不需要開發(fā)人員使用KeepAlive來手動關(guān)閉HTTP客戶端。
如果你選擇使用HTTP KeepAlive
,那么你可以創(chuàng)建一個標(biāo)志設(shè)為true
的Agent對象(見下面的構(gòu)造函數(shù)選項)。然后,Agent將會在資源池中保持未被使用的套接字,用于未來使用。它們將會被顯式標(biāo)記,以便于不保持io.js
進(jìn)程的運行。但是當(dāng)KeepAlive agent沒有被使用時,顯式地destroy()
KeepAlive agent仍然是個好主意,這樣socket
會被關(guān)閉。
當(dāng)socket
觸發(fā)了close
事件或者特殊的agentRemove
事件的時候,套接字們從agent的資源池中移除。這意味著如果你打算保持一個HTTP請求長時間開啟,并且不希望它保持在資源池中,那么你可以按照下列幾行的代碼做事:
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è)置可配置的選項??梢杂幸韵聦傩?/strong>:
socket
被其他請求所使用,默認(rèn)為false
socket
發(fā)送TCP KeepAlive 報文的間隔。默認(rèn)為1000
。只在KeepAlive
被設(shè)置為true
時有效socket
的最大數(shù)量。默認(rèn)為Infinity
socket
數(shù)。僅在keepAlive
為true
時有效。默認(rèn)為256
http.request
使用的默認(rèn)的http.globalAgent
包含它們屬性的各自的默認(rèn)值。
為了配置它們中的任何一個,你必須創(chuàng)建你自己的Agent
對象。
var http = require('http');
var keepAliveAgent = new http.Agent({ keepAlive: true });
options.agent = keepAliveAgent;
http.request(options, onResponseCallback);
默認(rèn)為Infinity
。決定了每個源上可以擁有的并發(fā)的socket
的數(shù)量。源為'host:port'
或'host:port:localAddress'
結(jié)合體。
默認(rèn)為256
。對于支持HTTP KeepAlive的Agent,這設(shè)置了在空閑狀態(tài)下保持打開的最大socket
數(shù)量。
這個對象包含了正在被Agent使用desocket
數(shù)組。請不要修改它。
這個對象包含了當(dāng)HTTP KeepAlive被使用時正在等待的socket
數(shù)組。請不要修改它。
這個對象包含了還沒有被分配給socket
的請求隊列。請不要修改它。
銷毀正在被agent使用的所有socket
。
通常沒有必要這么做。但是,如果你正在使用一個啟用了KeepAlive
的agent,那么最好明確地關(guān)閉agent當(dāng)你知道它不會再被使用時。否則,在服務(wù)器關(guān)閉它們前socket
可能被閑置。
通過一個請求選項集合來獲取一個獨一無二的名字,來決定一個連接是否可被再使用。在http代理中,這返回host:port:localAddress
。在https代理中,name
包括了CA,cert,ciphers和HTTPS/TLS-specific
配置來決定一個socket
是否能被再使用。
所有的http客戶端請求使用的默認(rèn)全局Agent
實例。
這個對象時被內(nèi)部創(chuàng)建的,并且通過http.request()
被返回。它代表了一個正在處理的請求,其頭部已經(jīng)進(jìn)入了隊列。這個頭部仍然可以通過setHeader(name, value)
,getHeader(name)
和removeHeader(name)
修改。實際的頭部會隨著第一個數(shù)據(jù)塊發(fā)送,或在關(guān)閉連接時發(fā)送。
要獲得響應(yīng)對象,請為response
事件添加一個監(jiān)聽器。request
對象的response
事件將會在收到響應(yīng)頭時觸發(fā)。這個response
事件的第一個參數(shù)是一個http.IncomingMessage
的實例。
在response
事件期間,可以給響應(yīng)對象添加監(jiān)聽器;尤其是監(jiān)聽data
事件。
如果沒有添加response
事件監(jiān)聽器,那么響應(yīng)會被完全忽略。但是,如果你添加了response
事件,那么你必須通過調(diào)用response.read()
,添加data
事件監(jiān)聽器或調(diào)用.resume()
方法等等,來從響應(yīng)對象中消耗數(shù)據(jù)。在數(shù)據(jù)被消費之前,end
事件不會觸發(fā)。如果數(shù)據(jù)沒有被讀取,它會消耗內(nèi)存,最后導(dǎo)致'process out of memory'
錯誤。
注意:io.js
不會檢查Content-Length
和被傳輸?shù)捻憫?yīng)體長度是否相同。
這個請求實現(xiàn)了Writable
流接口。這是一個包含了以下事件的EventEmitter
:
當(dāng)這個請求收到一個響應(yīng)時觸發(fā)。這個事件只會被觸發(fā)一次。response
參數(shù)是一個http.IncomingMessage
實例。
Options:
socket
(使用host:port
或socketPath
中的一個)當(dāng)一個socket
被分配給一個請求時觸發(fā)。
每次服務(wù)器使用CONNECT
方法響應(yīng)一個請求時觸發(fā)。如果這個事件沒有被監(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: io.js-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();
});
});
});
Emitted each time a server responds to a request with an upgrade. If this event isn't being listened for, clients receiving an upgrade header will have their connections closed.每次服務(wù)器返回upgrade
響應(yīng)給請求時觸發(fā)。如果這個事件沒有被監(jiān)聽,客戶端接收一個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);
});
});
當(dāng)服務(wù)器發(fā)出一個'100 Continue'
HTTP響應(yīng)時,通常這是因為請求包含'Expect: 100-continue'
。這是一個客戶端須要發(fā)送請求體的指示。
當(dāng)請求被客戶端中止時觸發(fā)。這個事件只會在第一次調(diào)用abort()
時觸發(fā)。
沖刷請求頭。
由于效率原因,io.js
通常在直到你調(diào)用request.end()
或?qū)懭氲谝粋€數(shù)據(jù)塊前都會緩沖請求頭,然后努力將請求頭和數(shù)據(jù)打包為一個TCP報文。
這通常是你想要的(它節(jié)約了一個TCP往返)。但當(dāng)?shù)谝环輸?shù)據(jù)會等待很久才被發(fā)送時不是。request.flushHeaders()
使你能繞過這個優(yōu)化并且啟動請求。
發(fā)送一個響應(yīng)塊。當(dāng)用戶想要將請求體流式得發(fā)送給服務(wù)器時,可以通過調(diào)用這個方法多次來辦到--在這種情況下,建議在創(chuàng)建請求時使用['Transfer-Encoding', 'chunked']
頭。
chunk
參數(shù)必須是一個Buffer
或一個字符串。
encoding
參數(shù)是可選的,并且僅當(dāng)chunk
是字符串時有效。默認(rèn)為'utf8'
。
callback
參數(shù)是可選的,并且當(dāng)數(shù)據(jù)塊被沖刷時被調(diào)用。
結(jié)束發(fā)送請求。如果有任何部分的請求體未被發(fā)送,這個函數(shù)將會將它們沖刷至流中。如果請求是成塊的,它會發(fā)送終結(jié)符'0\r\n\r\n'
。
如果data
被指定,那么這與調(diào)用request.write(data, encoding)
后再調(diào)用request.end(callback)
相同。
如果callback
被指定,那么它將在請求流結(jié)束時被調(diào)用。
中止請求。
一旦一個socket
被分配給這個請求并且完成連接,socket.setTimeout()
會被調(diào)用。
返回request
對象。
一旦一個socket
被分配給這個請求并且完成連接,socket.setNoDelay()
會被調(diào)用。
一旦一個socket
被分配給這個請求并且完成連接,socket.setKeepAlive()
會被調(diào)用。
一個IncomingMessage
對象被http.Server
或http.ClientRequest
創(chuàng)建,并且分別被傳遞給request
和response
事件的第一個參數(shù)。它被用來取得響應(yīng)狀態(tài),響應(yīng)頭和響應(yīng)體。
它實現(xiàn)了Readable
流接口,并且有以下額外的事件,方法和屬性。
表明底層連接被關(guān)閉。與end
相同,這個時間每次響應(yīng)只會觸發(fā)一次。
當(dāng)向服務(wù)器發(fā)送請求時,客戶端發(fā)送的HTTP版本。向客戶端發(fā)送響應(yīng)時,服務(wù)器響應(yīng)的HTTP版本。通常是'1.1'
或'1.0'
。
另外,response.httpVersionMajor
是第一個整數(shù),response.httpVersionMinor
是第二個整數(shù)。
請求/響應(yīng)頭對象。
只讀的頭名稱和值映射。頭名稱是小寫的,例子:
// Prints something like:
//
// { 'user-agent': 'curl/7.22.0',
// host: '127.0.0.1:8000',
// accept: '*/*' }
console.log(request.headers);
接受到的原始請求/響應(yīng)頭列表。
注意鍵和值在同一個列表中,它并非一個元組列表。于是,偶數(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);
請求/響應(yīng)尾部對象。只在end
事件中存在。
接受到的原始請求/響應(yīng)頭尾部鍵值對。只在end
事件中存在。
調(diào)用message.connection.setTimeout(msecs, callback)
。
返回message
。
僅對從http.Server
獲得的請求有效。
請求方法是字符串。只讀。例如:'GET'
,'DELETE'
。
僅對從http.Server
獲得的請求有效。
請求的URL字符串。這僅僅只包含實際HTTP請求中的URL。如果請求是:
GET /status?name=ryan HTTP/1.1\r\n
Accept: text/plain\r\n
\r\n
那么request.url
將是:
'/status?name=ryan'
如果你想分塊地解釋URL。你可以調(diào)用require('url').parse(request.url)
。例子:
iojs> require('url').parse('/status?name=ryan')
{ href: '/status?name=ryan',
search: '?name=ryan',
query: 'name=ryan',
pathname: '/status' }
如果你想從查詢字符串中提取參數(shù),你可以使用require('querystring').parse
函數(shù),或者給require('url').parse
方法的第二個參數(shù)傳遞true
,例子:
iojs> require('url').parse('/status?name=ryan', true)
{ href: '/status?name=ryan',
search: '?name=ryan',
query: { name: 'ryan' },
pathname: '/status' }
只對從http.ClientRequest
到來的響應(yīng)有效。
3位整數(shù)HTTP狀態(tài)碼。如404
。
只對從http.ClientRequest
到來的響應(yīng)有效。
HTTP響應(yīng)狀態(tài)信息。如OK
或Internal Server Error
。
與此連接關(guān)聯(lián)的net.Socket
對象。
通過HTTPS的支持,使用request.socket.getPeerCertificate()
來獲取客戶端的身份細(xì)節(jié)。
更多建議: