欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

 更新時間:2015年01月13日 10:56:53   投稿:hebedich  
這里只是熟悉nodejs中的http模塊的API,一般在開發(fā)過程中使用的是第三方的框架,比如說Express。其中封裝了更為簡單的構(gòu)建http服務(wù)器的API。

一,開篇分析

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

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

希望大家可以先閱讀一下官網(wǎng)提供的api,有一個前置了解,這樣就方便多了,以下是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

讓我們先從一個簡單例子開始,創(chuàng)建一個叫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)以下是運行結(jié)果:

 

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

具體看一下這個小例子:

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

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

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

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

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

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

  我們在再來看一下"requestListener"這個回調(diào)函數(shù),它提供了兩個參數(shù)(request,response),

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

  "request"是http.IncomingMessage的一個實例。"response"是http.ServerResponse的一個實例。

  一個http request對象是可讀流,而http response對象則是可寫流。

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

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

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

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

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

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

  舉個栗子:

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

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

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

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

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

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

 statusCode是一個三位是的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行開始。

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

 

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

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

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

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

三,實例

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

這是一個"POST"請求的例子:

復(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) ;

下是一個完整的“Http”請求數(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),強調(diào)一個概念:一個http request對象是可讀流,而http response對象則是可寫流 。

相關(guān)文章

  • node.js學(xué)習(xí)筆記之koa框架和簡單爬蟲練習(xí)

    node.js學(xué)習(xí)筆記之koa框架和簡單爬蟲練習(xí)

    這篇文章主要介紹了node.js學(xué)習(xí)筆記之koa框架和簡單爬蟲練習(xí),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-12-12
  • node.js中的fs.truncate方法使用說明

    node.js中的fs.truncate方法使用說明

    這篇文章主要介紹了node.js中的fs.truncate方法使用說明,本文介紹了fs.truncate的方法說明、語法、接收參數(shù)、使用實例和實現(xiàn)源碼,需要的朋友可以參考下
    2014-12-12
  • 使用NestJS開發(fā)Node.js應(yīng)用的方法

    使用NestJS開發(fā)Node.js應(yīng)用的方法

    這篇文章主要介紹了使用NestJS開發(fā)Node.js應(yīng)用的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-12-12
  • nodejs實現(xiàn)bigpipe異步加載頁面方案

    nodejs實現(xiàn)bigpipe異步加載頁面方案

    本文給大家分享的是使用nodejs結(jié)合bigpipe實現(xiàn)異步加載頁面的方案,非常的實用,也是以后前端性能優(yōu)化的一個方向,希望大家能夠喜歡。
    2016-01-01
  • 實時通信WebSocket的原理和工作過程

    實時通信WebSocket的原理和工作過程

    WebSocket持久連接使得服務(wù)器可以主動向客戶端推送數(shù)據(jù),而不需要等待客戶端的請求,是一種專門設(shè)計用于實現(xiàn)持久連接的協(xié)議,WebSocket的持久連接特性使其成為實時性要求高的應(yīng)用的理想選擇,如在線聊天、實時游戲、數(shù)據(jù)監(jiān)控等
    2023-12-12
  • 把Node.js程序加入服務(wù)實現(xiàn)隨機啟動

    把Node.js程序加入服務(wù)實現(xiàn)隨機啟動

    這篇文章主要介紹了把Node.js程序加入服務(wù)實現(xiàn)隨機啟動,本文使用qckwinsvc實現(xiàn)這個需求,講解了qckwinsvc的安裝和使用,需要的朋友可以參考下
    2015-06-06
  • nodejs使用socket5進行代理請求的實現(xiàn)

    nodejs使用socket5進行代理請求的實現(xiàn)

    這篇文章主要介紹了nodejs使用socket5進行代理請求的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-02-02
  • node中modules.exports與exports導(dǎo)出的區(qū)別

    node中modules.exports與exports導(dǎo)出的區(qū)別

    這篇文章主要介紹了node中modules.exports與exports導(dǎo)出的區(qū)別,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-06-06
  • 使用?Node-RED對?MQTT?數(shù)據(jù)流處理

    使用?Node-RED對?MQTT?數(shù)據(jù)流處理

    本文將介紹使用 Node-RED 連接到 MQTT 服務(wù)器,并對 MQTT 數(shù)據(jù)進行過濾和處理后再將其發(fā)送至 MQTT 服務(wù)器的完整操作流程。讀者可以快速了解如何使用 Node-RED 對 MQTT 數(shù)據(jù)進行簡單的流處理
    2022-05-05
  • Node.js的Koa實現(xiàn)JWT用戶認(rèn)證方法

    Node.js的Koa實現(xiàn)JWT用戶認(rèn)證方法

    本篇文章主要介紹了Node.js的Koa實現(xiàn)JWT用戶認(rèn)證方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-05-05

最新評論