xdh精英班20160909課后作業(yè): Node.js HTTP 介紹

xdh精英班20160909課后作業(yè): Node.js HTTP 介紹

本文根據(jù)xdh精英班20160909課后作業(yè)要求整理而成竿滨。本文同步發(fā)表于簡(jiǎn)書(shū),鏈接地址: http://www.reibang.com/p/2618139c0346

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

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

HTTP消息頭對(duì)象和下面的例子類似:

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

Keys 都是小寫(xiě),值不能修改弹沽。

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

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

接收到的原始頭信息以數(shù)組([key, value, key2, value2, ...])的形式保存在 rawHeaders 里泻蚊。例如,之前提到的消息對(duì)象會(huì)有如下的 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ù)自動(dòng)加到'request' 事件里。

類: http.Server

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

  • 事件: 'request'

    function (request, response) { }

    每當(dāng)有請(qǐng)求的時(shí)候觸發(fā)滩褥。注意:每個(gè)連接可以有多個(gè)請(qǐng)求(在 keep-alive 連接中)。request 是 http.IncomingMessage 實(shí)例炫加,response 是 http.ServerResponse 的實(shí)例瑰煎。

  • 事件: 'connection'

    function (socket) { }

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

  • 事件: 'close'

    function () { }

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

  • 事件: 'checkContinue'

    function (request, response) { }

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

    如果客戶端需要繼續(xù)發(fā)送請(qǐng)求主題析恋,或者生成合適的 HTTP 響應(yīng)(如,400 請(qǐng)求無(wú)效)盛卡,可以通過(guò)調(diào)用 response.writeContinue() 來(lái)處理助隧。

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

  • 事件: 'connect'

    function (request, socket, head) { }

    當(dāng)客戶端請(qǐng)求 http 連接時(shí)觸發(fā)并村。如果沒(méi)有監(jiān)聽(tīng)這個(gè)事件,客戶端請(qǐng)求連接的時(shí)候會(huì)被關(guān)閉滓技。

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

    這個(gè)事件觸發(fā)后,請(qǐng)求的 socket 不會(huì)有 data 事件監(jiān)聽(tīng)器原环,也就是說(shuō)你需要綁定一個(gè)監(jiān)聽(tīng)器到 data 上挠唆,來(lái)處理在發(fā)送到服務(wù)器上的 socket 數(shù)據(jù)。

  • 事件: 'upgrade'

    function (request, socket, head) { }

    當(dāng)客戶端請(qǐng)求 http upgrage 時(shí)候會(huì)觸發(fā)嘱吗。如果沒(méi)有監(jiān)聽(tīng)這個(gè)事件玄组,客戶端請(qǐng)求一個(gè)連接的時(shí)候會(huì)被關(guān)閉。

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

    這個(gè)事件觸發(fā)后耻蛇,請(qǐng)求的 socket 不會(huì)有 data 事件監(jiān)聽(tīng)器踪蹬,也就是說(shuō)你需要綁定一個(gè)監(jiān)聽(tīng)器到 data 上,來(lái)處理在發(fā)送到服務(wù)器上的 socket 數(shù)據(jù)臣咖。

  • 事件: 'clientError'

    function (exception, socket) { }

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

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

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

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

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

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

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

  • server.listen(path[, callback])

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

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

  • server.listen(handle[, callback])

    • handle {Object}

    • callback {Function}

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

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

    Windows 不能監(jiān)聽(tīng)文件句柄孵淘。

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

  • server.close([callback])

    禁止 server 接收連接揉阎。參見(jiàn) net.Server.close().

  • server.maxHeadersCount

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

  • server.setTimeout(msecs, callback)

    • msecs {Number}
    • callback {Function}

    為 socket 設(shè)置超時(shí)時(shí)間毡庆,單位為毫秒坑赡,如果發(fā)生超時(shí),在 server 對(duì)象上觸發(fā) 'timeout' 事件么抗,參數(shù)為 socket 毅否。

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

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

  • server.timeout

    • {Number} Default = 120000 (2 minutes)

    超時(shí)的時(shí)長(zhǎng),單位為毫秒卒蘸。

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

    設(shè)為 0 時(shí)恰起,建立連接的自動(dòng)超時(shí)將失效修械。

類: http.ServerResponse

這是一個(gè)由 HTTP 服務(wù)器(而不是用戶)內(nèi)部創(chuàng)建的對(duì)象。作為第二個(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)后貌亭,通過(guò)網(wǎng)絡(luò)來(lái)傳輸時(shí)被觸發(fā)柬唯。這并不代表客戶端已經(jīng)收到數(shù)據(jù)。

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

  • response.writeContinue()

    發(fā)送 HTTP/1.1 100 Continue 消息給客戶端,表示請(qǐng)求體可以發(fā)送剧腻【醒耄可以在服務(wù)器上查看'checkContinue' 事件。
    response.writeHead(statusCode[, statusMessage][, headers])

    發(fā)送一個(gè)響應(yīng)頭給請(qǐ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(),將會(huì)計(jì)算出不穩(wěn)定的頭。

    Content-Length 是字節(jié)數(shù)盟萨,而不是字符數(shù)凉翻。上面的例子 'hello world' 僅包含一個(gè)字節(jié)字符。如果 body 包含高級(jí)編碼的字符捻激, Buffer.byteLength() 就必須確定指定編碼的字符數(shù)制轰。Node 不會(huì)檢查Content-Length 和 body 的長(zhǎng)度是否相同。

  • response.setTimeout(msecs, callback)

    • msecs {Number}
    • callback {Function}

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

    如果沒(méi)有給請(qǐng)求调俘、響應(yīng)伶棒、服務(wù)器添加 'timeout' 監(jiān)視器,超時(shí)的時(shí)候?qū)?huì)銷毀 socket彩库。如果你給請(qǐng)求肤无、響應(yīng)、服務(wù)器加了處理函數(shù)骇钦,就需要負(fù)責(zé)處理 socket 超時(shí)宛渐。

  • response.statusCode

    使用默認(rèn)的 headers 時(shí)(沒(méi)有顯式的調(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í)(沒(méi)有顯式的調(diào)用 response.writeHead() ), 這個(gè)屬性表示將要發(fā)送給客戶端狀態(tài)信息坦仍。 如果這個(gè)沒(méi)有定義鳍烁,將會(huì)使用狀態(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)容會(huì)被替換爹梁。如果你想設(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 里沒(méi)有 Date 值時(shí)积糯,自動(dòng)生成 Date 并發(fā)送。

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

  • response.getHeader(name)

    讀取一個(gè)在隊(duì)列中但是還沒(méi)有被發(fā)送至客戶端的header谦纱。名字是大小寫(xiě)敏感看成。僅能再頭被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è)方法川慌,且還沒(méi)有調(diào)用 response.writeHead(),將會(huì)切換到默認(rèn)的 header祠乃,并更新這個(gè)header梦重。

    這個(gè)方法將發(fā)送響應(yīng)體數(shù)據(jù)塊×链桑可能會(huì)多次調(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亮靴,和高級(jí)的multi-part body 編碼無(wú)關(guān)。

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

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

  • response.addTrailers(headers)

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

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

    如果你想觸發(fā) trailers宽菜, HTTP 會(huì)要求發(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犬庇,將會(huì)在響應(yīng)流結(jié)束的時(shí)候調(diào)用僧界。

  • http.request(options[, callback])

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

    參數(shù)options是對(duì)象或字符串捂襟。如果 options 是字符串,會(huì)通過(guò) url.parse() 自動(dòng)解析欢峰。

    options 值:

    • host: 請(qǐng)求的服務(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 請(qǐng)求方法宠漩。 默認(rèn): 'GET'.
    • path: 請(qǐng)求路徑举反。 默認(rèn): '/'。如果有查詢字符串扒吁,則需要包含火鼻。例如'/index.html?page=12'。請(qǐng)求路徑包含非法字符時(shí)拋出異常雕崩。目前魁索,只有空格不行,不過(guò)在未來(lái)可能改變盼铁。
    • headers: 包含請(qǐng)求頭的對(duì)象
    • auth: 用于計(jì)算認(rèn)證頭的基本認(rèn)證粗蔚,即 user:password
    • agent: 控制Agent的行為。當(dāng)使用了一個(gè)Agent的時(shí)候饶火,請(qǐng)求將默認(rèn)為Connection: keep-alive鹏控。可能的值為:
      • undefined (default): 在這個(gè)主機(jī)和端口上使用 global Agent
      • Agent object: 在Agent中顯式使用 passed .
      • false: 選擇性停用連接池,默認(rèn)請(qǐng)求為: Connection: close.
      • keepAlive: {Boolean} 持資源池周圍的socket趁窃,用于未來(lái)其它請(qǐng)求牧挣。默認(rèn)值為false。
        keepAliveMsecs: {Integer} 使用HTTP KeepAlive 的時(shí)候醒陆,通過(guò)正在保持活動(dòng)的sockets發(fā)送TCP KeepAlive包的頻繁程度瀑构。默認(rèn)值為1000。僅當(dāng)keepAlive為true時(shí)才相關(guān)刨摩。

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

    http.request() 返回一個(gè) http.ClientRequest類的實(shí)例澡刹。ClientRequest實(shí)例是一個(gè)可寫(xiě)流對(duì)象呻征。如果需要用POST請(qǐng)求上傳一個(gè)文件的話,就將其寫(xiě)入到ClientRequest對(duì)象罢浇。

    例如:

    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() 來(lái)表明請(qǐng)求已經(jīng)完成嚷闭,即使沒(méi)有數(shù)據(jù)寫(xiě)入到請(qǐng)求 body 里攒岛。

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

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

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

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

    • 發(fā)送一個(gè) Expect 頭吵聪,會(huì)立即發(fā)送請(qǐng)求頭,一般來(lái)說(shuō)兼雄,發(fā)送 Expect: 100-continue ,你必須設(shè)置超時(shí)吟逝,并監(jiān)聽(tīng) continue 事件。

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

  • http.get(options[, callback])

    因?yàn)槎鄶?shù)請(qǐng)求是沒(méi)有報(bào)文體的 GET 請(qǐng)求金砍, Node 提供了這個(gè)簡(jiǎn)便的方法局蚀。和 http.request() 唯一不同點(diǎn)在于,這個(gè)方法自動(dòng)設(shè)置 GET恕稠,并自動(dòng)調(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 客戶端請(qǐng)求鹅巍。

HTTP Agent 也把客戶端請(qǐng)求默認(rèn)為使用 Connection:keep-alive 千扶。如果沒(méi)有 HTTP 請(qǐng)求正在等著成為空閑 socket 的話,那么 socket 將關(guān)閉骆捧。這意味著澎羞,Node 的資源池在負(fù)載的情況下對(duì) keep-alive 有利,但是仍然不需要開(kāi)發(fā)人員使用 KeepAlive 來(lái)手動(dòng)關(guān)閉 HTTP 客戶端敛苇。

如果你選擇使用 HTTP KeepAlive妆绞, 可以創(chuàng)建一個(gè) Agent 對(duì)象,將 flag 設(shè)置為 true. (參見(jiàn)下面的 constructor options ) 枫攀,這樣 Agent 會(huì)把沒(méi)用到的 socket 放到池里括饶,以便將來(lái)使用。他們會(huì)被顯式的標(biāo)志来涨,讓 Node 不運(yùn)行图焰。但是,當(dāng)不再使用它的時(shí)候蹦掐,需要顯式的調(diào)用destroy()技羔,這樣 socket 將會(huì)被關(guān)閉。

當(dāng) socket 事件觸發(fā) close 事件或特殊的 agentRemove 事件時(shí)卧抗,socket 將會(huì)從 agent 池里移除藤滥。如果你要保持 HTTP 請(qǐng)求保持長(zhǎng)時(shí)間打開(kāi),并且不希望他們?cè)诔乩锟盼叮梢詤⒖家韵麓a:

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浦马,用于未來(lái)其它請(qǐng)求时呀。默認(rèn)值為 false。
      • keepAliveMsecs {Integer} 使用 HTTP KeepAlive 的時(shí)候晶默,通過(guò)正在保持活動(dòng)的 sockets 發(fā)送 TCP KeepAlive 包的頻繁程度谨娜。默認(rèn)值為 1000。僅當(dāng) keepAlive 為 true 時(shí)才相關(guān)磺陡。.】
      • maxSockets {Number} 在空閑狀態(tài)下,還依然開(kāi)啟的 socket 的最大值趴梢。僅當(dāng) keepAlive 設(shè)置為 true 的時(shí)候有效。默認(rèn)值為 256币他。

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

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

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

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

  • agent.maxFreeSockets

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

  • agent.sockets

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

  • agent.freeSockets

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

  • agent.requests

    這個(gè)對(duì)象包含了還沒(méi)分配給 socket 的請(qǐng)求數(shù)組。不要修改它拓劝。

  • agent.destroy()

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

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

  • agent.getName(options)

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

  • http.globalAgent

    Agent 的全局實(shí)例迂尝,是 http 客戶端的默認(rèn)請(qǐng)求脱茉。

類: http.ClientRequest

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

為了獲取響應(yīng),可以給請(qǐng)求對(duì)象的 'response' 添加監(jiān)聽(tīng)器锻梳。當(dāng)接收到響應(yīng)頭的時(shí)候?qū)?huì)從請(qǐng)求對(duì)象里觸發(fā)'response'箭券。'response' 事件執(zhí)行時(shí)有一個(gè)參數(shù),該參數(shù)為 http.IncomingMessage 的實(shí)例唱蒸。

在 'response' 事件期間邦鲫,可以給響應(yīng)對(duì)象添加監(jiān)視器,監(jiān)聽(tīng) 'data' 事件神汹。

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

Node 不會(huì)檢查 Content-Length 和 body 的長(zhǎng)度是否相同。

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

  • 事件: 'response'

    function (response) { }

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

    • Options:

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

    function (socket) { }

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

  • 事件: 'connect'

    function (response, socket, head) { }

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

    下面的例子展示了一對(duì)匹配的客戶端/服務(wù)器如何監(jiān)聽(tīng) 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 請(qǐng)求時(shí)觸發(fā)鱼鸠。如果沒(méi)有監(jiān)聽(tīng)這個(gè)事件,客戶端會(huì)收到 upgrade 頭后關(guān)閉連接。

    下面的例子展示了一對(duì)匹配的客戶端/服務(wù)器如何監(jiān)聽(tīng) 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)檎?qǐng)求包含 'Expect: 100-continue'漆弄。該指令表示客戶端應(yīng)發(fā)送請(qǐng)求體。
    request.flushHeaders()

    刷新請(qǐng)求的頭造锅。

    考慮效率因素,Node.js 通常會(huì)緩存請(qǐng)求的頭直到你調(diào)用 request.end()廉邑,或?qū)懭胝?qǐng)求的第一個(gè)數(shù)據(jù)塊哥蔚。然后,包裝請(qǐng)求的頭和數(shù)據(jù)到一個(gè)獨(dú)立的 TCP 包里蛛蒙。

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

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

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

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

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

    發(fā)送請(qǐng)求完畢收奔。如果 body 的數(shù)據(jù)沒(méi)被發(fā)送掌呜,將會(huì)將他們刷新到流里。如果請(qǐng)求是分塊的坪哄,該方法會(huì)發(fā)送終結(jié)符0\r\n\r\n 质蕉。

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

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

  • request.abort()

    終止一個(gè)請(qǐng)求. (v0.3.8 開(kāi)始新加入)兑宇。

  • request.setTimeout(timeout[, callback])

    如果 socket 被分配給這個(gè)請(qǐng)求,并完成連接棒卷,將會(huì)調(diào)用 socket.setTimeout() 顾孽。

  • request.setNoDelay([noDelay])

    如果 socket 被分配給這個(gè)請(qǐng)求,并完成連接比规,將會(huì)調(diào)用 socket.setNoDelay()若厚。

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

    如果 socket 被分配給這個(gè)請(qǐng)求,并完成連接蜒什,將會(huì)調(diào)用 socket.setKeepAlive()测秸。

類 http.IncomingMessage

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

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

  • 事件: 'close'

    function () { }

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

  • message.httpVersion

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

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

  • message.headers

    請(qǐng)求/響應(yīng)頭對(duì)象崩掘。

    只讀的頭名稱和值的映射。頭的名字是小寫(xiě)少办,比如:

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

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

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

    頭名字不是小寫(xiě)敏感,也沒(méi)用合并重復(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

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

  • message.rawTrailers

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

  • message.setTimeout(msecs, callback)

    • msecs {Number}
    • callback {Function}

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

  • message.method

    僅對(duì)從 http.Server 獲得的請(qǐng)求有效。

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

  • message.url

    僅對(duì)從 http.Server 獲得的請(qǐng)求有效乖杠。

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

    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

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

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

  • message.statusMessage

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

    HTTP 的響應(yīng)消息。比如包吝, OK 或 Internal Server Error.

  • message.socket

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

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市臼氨,隨后出現(xiàn)的幾起案子掺喻,更是在濱河造成了極大的恐慌,老刑警劉巖储矩,帶你破解...
    沈念sama閱讀 206,723評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件感耙,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡持隧,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,485評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)宫莱,“玉大人娃胆,你說(shuō)我怎么就攤上這事⊙嚼牵” “怎么了裂允?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,998評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)哥艇。 經(jīng)常有香客問(wèn)我绝编,道長(zhǎng),這世上最難降的妖魔是什么貌踏? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,323評(píng)論 1 279
  • 正文 為了忘掉前任十饥,我火速辦了婚禮,結(jié)果婚禮上祖乳,老公的妹妹穿的比我還像新娘逗堵。我一直安慰自己,他們只是感情好眷昆,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,355評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布砸捏。 她就那樣靜靜地躺著谬运,像睡著了一般。 火紅的嫁衣襯著肌膚如雪垦藏。 梳的紋絲不亂的頭發(fā)上梆暖,一...
    開(kāi)封第一講書(shū)人閱讀 49,079評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音掂骏,去河邊找鬼轰驳。 笑死,一個(gè)胖子當(dāng)著我的面吹牛弟灼,可吹牛的內(nèi)容都是我干的级解。 我是一名探鬼主播,決...
    沈念sama閱讀 38,389評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼田绑,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼勤哗!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起掩驱,我...
    開(kāi)封第一講書(shū)人閱讀 37,019評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤芒划,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后欧穴,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體民逼,經(jīng)...
    沈念sama閱讀 43,519評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,971評(píng)論 2 325
  • 正文 我和宋清朗相戀三年涮帘,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了拼苍。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,100評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡调缨,死狀恐怖疮鲫,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情弦叶,我是刑警寧澤棚点,帶...
    沈念sama閱讀 33,738評(píng)論 4 324
  • 正文 年R本政府宣布,位于F島的核電站湾蔓,受9級(jí)特大地震影響瘫析,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜默责,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,293評(píng)論 3 307
  • 文/蒙蒙 一贬循、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧桃序,春花似錦杖虾、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,289評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)坟比。三九已至,卻和暖如春嚷往,著一層夾襖步出監(jiān)牢的瞬間葛账,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,517評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工皮仁, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留籍琳,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,547評(píng)論 2 354
  • 正文 我出身青樓贷祈,卻偏偏與公主長(zhǎng)得像趋急,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子势誊,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,834評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • 使用 HTTP 服務(wù)器或客戶端功能必須調(diào)用require('http')呜达。 Node 里的 HTTP 接口支持協(xié)議...
    保川閱讀 1,375評(píng)論 0 1
  • https://nodejs.org/api/documentation.html 工具模塊 Assert 測(cè)試 ...
    KeKeMars閱讀 6,305評(píng)論 0 6
  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)粟耻,斷路器查近,智...
    卡卡羅2017閱讀 134,600評(píng)論 18 139
  • 本文轉(zhuǎn)自 http://my.oschina.net/antianlu/blog/228511 摘要 翻譯和注釋了...
    birdflying閱讀 1,859評(píng)論 0 2
  • http中請(qǐng)求request和響應(yīng)response信息說(shuō)明 Request http.ServerRequest ...
    drolor閱讀 1,002評(píng)論 0 0