国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

NodeJS學(xué)習(xí)筆記之Http模塊

2019-11-20 13:25:06
字體:
供稿:網(wǎng)友

一,開篇分析

首先“Http”這個(gè)概念大家應(yīng)該比較熟悉了,它不是基于特定語言的,是一個(gè)通用的應(yīng)用層協(xié)議,不同語言有不同的實(shí)現(xiàn)細(xì)節(jié),但是萬變不離其宗,思想是相同的,

NodeJS作為一個(gè)宿主運(yùn)行環(huán)境,以JavaScript為宿主語言,它也有自己實(shí)現(xiàn)的一套標(biāo)準(zhǔn),這篇文章我們就一起來學(xué)習(xí)一下 “Http模塊” 。但是作為前提來說,

希望大家可以先閱讀一下官網(wǎng)提供的api,有一個(gè)前置了解,這樣就方便多了,以下是Http部分的api概覽:

復(fù)制代碼 代碼如下:

HTTP
    http.STATUS_CODES
    http.createServer([requestListener])
    http.createClient([port], [host])
    Class: http.Server
    事件 : 'request'
    事件: 'connection'
    事件: 'close'
    Event: 'checkContinue'
    事件: 'connect'
    Event: 'upgrade'
    Event: 'clientError'
    server.listen(port, [hostname], [backlog], [callback])
    server.listen(path, [callback])
    server.listen(handle, [callback])
    server.close([callback])
    server.maxHeadersCount
    server.setTimeout(msecs, callback)
    server.timeout
    Class: http.ServerResponse
        事件: 'close'
        response.writeContinue()
        response.writeHead(statusCode, [reasonPhrase], [headers])
        response.setTimeout(msecs, callback)
        response.statusCode
        response.setHeader(name, value)
        response.headersSent
        response.sendDate
        response.getHeader(name)
        response.removeHeader(name)
        response.write(chunk, [encoding])
        response.addTrailers(headers)
        response.end([data], [encoding])
        http.request(options, callback)
        http.get(options, callback)
    Class: http.Agent
        new Agent([options])
        agent.maxSockets
        agent.maxFreeSockets
        agent.sockets
        agent.freeSockets
        agent.requests
        agent.destroy()
        agent.getName(options)
        http.globalAgent
    Class: http.ClientRequest
        Event 'response'
        Event: 'socket'
        事件: 'connect'
        Event: 'upgrade'
        Event: 'continue'
        request.write(chunk, [encoding])
        request.end([data], [encoding])
        request.abort()
        request.setTimeout(timeout, [callback])
        request.setNoDelay([noDelay])
        request.setSocketKeepAlive([enable], [initialDelay])
    http.IncomingMessage
        事件: 'close'
        message.httpVersion
        message.headers
        message.rawHeaders
        message.trailers
        message.rawTrailers
        message.setTimeout(msecs, callback)
        message.method
        message.url
        message.statusCode
        message.socket

讓我們先從一個(gè)簡單例子開始,創(chuàng)建一個(gè)叫server.js的文件,并寫入以下代碼:

復(fù)制代碼 代碼如下:

 var http = require('http') ;
 var server = http.createServer(function(req,res){
 res.writeHeader(200,{
     'Content-Type' : 'text/plain;charset=utf-8'  // 添加charset=utf-8
 }) ;
 res.end("Hello,大熊!") ;
 }) ;
 server.listen(8888) ;
 console.log("http server running on port 8888 ...") ;

(node server.js)以下是運(yùn)行結(jié)果:

 

二,細(xì)節(jié)分析實(shí)例

具體看一下這個(gè)小例子:

(1行):通過"require"引入NodeJS自帶的"http"模塊,并且把它賦值給http變量。

(2行):調(diào)用http模塊提供的函數(shù):"createServer" 。這個(gè)函數(shù)會(huì)返回一個(gè)新的web服務(wù)器對(duì)象。

  參數(shù) "requestListener" 是一個(gè)函數(shù),它將會(huì)自動(dòng)加入到 "request" 事件的監(jiān)聽隊(duì)列。

  當(dāng)一個(gè)request到來時(shí),Event-Loop會(huì)將這個(gè)Listener回調(diào)函數(shù)放入執(zhí)行隊(duì)列, node中所有的代碼都是一個(gè)一個(gè)從執(zhí)行隊(duì)列中拿出來執(zhí)行的。

  這些執(zhí)行都是在工作線程上(Event Loop本身可以認(rèn)為在一個(gè)獨(dú)立的線程中,我們一般不提這個(gè)線程,而將node稱呼為一個(gè)單線程的執(zhí)行環(huán)境),

  所有的回調(diào)都是在一個(gè)工作線程上運(yùn)行。

  我們?cè)谠賮砜匆幌?requestListener"這個(gè)回調(diào)函數(shù),它提供了兩個(gè)參數(shù)(request,response),

  每次收到一個(gè)請(qǐng)求時(shí)觸發(fā)。注意每個(gè)連接又可能有多個(gè)請(qǐng)求(在keep-alive的連接中)。

  "request"是http.IncomingMessage的一個(gè)實(shí)例。"response"是http.ServerResponse的一個(gè)實(shí)例。

  一個(gè)http request對(duì)象是可讀流,而http response對(duì)象則是可寫流。

  一個(gè)"IncomingMessage"對(duì)象是由http.Server或http.ClientRequest創(chuàng)建的,

  并作為第一參數(shù)分別傳遞給"request"和"response"事件。

  它也可以被用來訪問應(yīng)答的狀態(tài),頭文件和數(shù)據(jù)。

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

(3行):“writeHeader”,使用 "response.writeHead()"  函數(shù)發(fā)送一個(gè)Http狀態(tài)200和Http頭的內(nèi)容類型(content-type)。

  向請(qǐng)求回復(fù)響應(yīng)頭。"statusCode"是一個(gè)三位是的HTTP狀態(tài)碼,例如 404 。最后一個(gè)參數(shù),"headers",是響應(yīng)頭的內(nèi)容。

  舉個(gè)栗子:

復(fù)制代碼 代碼如下:

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

 注意:Content-Length 是以字節(jié)(byte)計(jì)算,而不是以字符(character)計(jì)算。

  之前的例子原因是字符串 “Hello World !” 只包含了單字節(jié)的字符。

  如果body包含了多字節(jié)編碼的字符,就應(yīng)當(dāng)使用Buffer.byteLength()來確定在多字節(jié)字符編碼情況下字符串的字節(jié)數(shù)。

  需要進(jìn)一步說明的是Node不檢查Content-Lenth屬性和已傳輸?shù)腷ody長度是否吻合。

 statusCode是一個(gè)三位是的HTTP狀態(tài)碼, 例如:"404" 。這里要說的是 "http.STATUS_CODES" ,全部標(biāo)準(zhǔn)"Http"響應(yīng)狀態(tài)碼的集合和簡短描述都在里面。

 如下是源碼參考:

復(fù)制代碼 代碼如下:

var STATUS_CODES = exports.STATUS_CODES = {
  100 : 'Continue',
  101 : 'Switching Protocols',
  102 : 'Processing',                 // RFC 2518, obsoleted by RFC 4918
  200 : 'OK',
  201 : 'Created',
  202 : 'Accepted',
  203 : 'Non-Authoritative Information',
  204 : 'No Content',
  205 : 'Reset Content',
  206 : 'Partial Content',
  207 : 'Multi-Status',               // RFC 4918
  300 : 'Multiple Choices',
  301 : 'Moved Permanently',
  302 : 'Moved Temporarily',
  303 : 'See Other',
  304 : 'Not Modified',
  305 : 'Use Proxy',
  307 : 'Temporary Redirect',
  400 : 'Bad Request',
  401 : 'Unauthorized',
  402 : 'Payment Required',
  403 : 'Forbidden',
  404 : 'Not Found',
  405 : 'Method Not Allowed',
  406 : 'Not Acceptable',
  407 : 'Proxy Authentication Required',
  408 : 'Request Time-out',
  409 : 'Conflict',
  410 : 'Gone',
  411 : 'Length Required',
  412 : 'Precondition Failed',
  413 : 'Request Entity Too Large',
  414 : 'Request-URI Too Large',
  415 : 'Unsupported Media Type',
  416 : 'Requested Range Not Satisfiable',
  417 : 'Expectation Failed',
  418 : 'I/'m a teapot',              // RFC 2324
  422 : 'Unprocessable Entity',       // RFC 4918
  423 : 'Locked',                     // RFC 4918
  424 : 'Failed Dependency',          // RFC 4918
  425 : 'Unordered Collection',       // RFC 4918
  426 : 'Upgrade Required',           // RFC 2817
  500 : 'Internal Server Error',
  501 : 'Not Implemented',
  502 : 'Bad Gateway',
  503 : 'Service Unavailable',
  504 : 'Gateway Time-out',
  505 : 'HTTP Version not supported',
  506 : 'Variant Also Negotiates',    // RFC 2295
  507 : 'Insufficient Storage',       // RFC 4918
  509 : 'Bandwidth Limit Exceeded',
  510 : 'Not Extended'                // RFC 2774
};

節(jié)選自,Nodejs源碼 ”http.js“ 143行開始。

其實(shí)從客戶端應(yīng)答結(jié)果也不難看出:

 

(6行):”response.end“------當(dāng)所有的響應(yīng)報(bào)頭和報(bào)文被發(fā)送完成時(shí)這個(gè)方法將信號(hào)發(fā)送給服務(wù)器。服務(wù)器會(huì)認(rèn)為這個(gè)消息完成了。

  每次響應(yīng)完成之后必須調(diào)用該方法。如果指定了參數(shù) “data” ,就相當(dāng)于先調(diào)用  “response.write(data, encoding) ” 之后再調(diào)用 “response.end()” 。

(8行):”server.listen(8888)“ ------ 服務(wù)器用指定的句柄接受連接,綁定在特定的端口。

以上就是一個(gè)比較詳細(xì)的分析過程,希望有助于加深理解,代碼雖然不多,但是重在理解一些細(xì)節(jié)機(jī)制,以便日后高效的開發(fā)NodeJS應(yīng)用。

三,實(shí)例

除了可以使用"request"對(duì)象訪問請(qǐng)求頭數(shù)據(jù)外,還能把"request"對(duì)象當(dāng)作一個(gè)只讀數(shù)據(jù)流來訪問請(qǐng)求體數(shù)據(jù)。

這是一個(gè)"POST"請(qǐng)求的例子:

復(fù)制代碼 代碼如下:

 http.createServer(function (request, response) {
     var body = [];
     console.log(request.method) ;
     console.log(request.headers) ;
     request.on('data', function (chunk) {
         body.push(chunk);
     }) ;
     request.on('end', function () {
         body = Buffer.concat(body) ;
         console.log(body.toString()) ;
     });
 }).listen(8888) ;

下是一個(gè)完整的“Http”請(qǐng)求數(shù)據(jù)內(nèi)容。

復(fù)制代碼 代碼如下:

 POST / HTTP/1.1
 User-Agent: curl/7.26.0
 Host: localhost
 Accept: */*
 Content-Length: 11
 Content-Type: application/x-www-form-urlencoded
 Hello World

四,總結(jié)一下

(1),理解 "Http" 概念。
(2),熟練使用 "Http" 相關(guān)的api。
(3),注意細(xì)節(jié)的把控,比如:“POST,GET” 之間的處理細(xì)節(jié)。
(4),"requestListener"的理解。
(5),強(qiáng)調(diào)一個(gè)概念:一個(gè)http request對(duì)象是可讀流,而http response對(duì)象則是可寫流 。

發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 永年县| 西和县| 郓城县| 岢岚县| 类乌齐县| 峨边| 台东县| 开封县| 仁寿县| 卓尼县| 阿坝| 吴旗县| 临海市| 罗甸县| 青海省| 炎陵县| 当阳市| 江油市| 诏安县| 南漳县| 香港 | 和政县| 阜宁县| 建宁县| 乌拉特后旗| 阳原县| 丹棱县| 区。| 长兴县| 新乡县| 团风县| 大厂| 阜南县| 郓城县| 临沭县| 东方市| 海城市| 卓资县| 太原市| 平南县| 汽车|