最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Node.js創(chuàng)建HTTP文件服務(wù)器的使用示例

 更新時間:2018年05月11日 10:48:37   作者:foruok  
我們的目的比較簡單,使用Node.js創(chuàng)建一個HTTP協(xié)議的文件服務(wù)器,你可以使用瀏覽器或其它下載工具到文件服務(wù)器上下載文件,具有一定的參考價值,感興趣的小伙伴們可以參考一下

HelloWorld示例只有演示意義,這次我們來搞一個實際的例子:文件服務(wù)器。我們使用Node.js創(chuàng)建一個HTTP協(xié)議的文件服務(wù)器,你可以使用瀏覽器或其它下載工具到文件服務(wù)器上下載文件。

為了讀取文件,我們會用到File System模塊(名字是”fs”),Stream,我們還要分析URL,區(qū)別HTTP方法,還會用到EventEmitter。

文件服務(wù)器FileServer的代碼

先上代碼吧,依然是簡單的:

// 引入http模塊
var http = require("http"); 
var fs = require("fs");

// 創(chuàng)建server,指定處理客戶端請求的函數(shù)
http.createServer(
  function(request, response) {
    //判斷HTTP方法,只處理GET 
    if(request.method != "GET"){
      response.writeHead(403);
      response.end();
      return null;
    }

    //此處也可使用URL模塊來分析URL(https://nodejs.org/api/url.html)
    var sep = request.url.indexOf('?');
    var filePath = sep < 0 ? request.url : request.url.slice(0, sep);
    console.log("GET file: " + filePath);

    //當文件存在時發(fā)送數(shù)據(jù)給客戶端,否則404
    var fileStat = fs.stat("."+filePath, 
      function(err, stats){
        if(err) {
          response.writeHead(404);
          response.end();
          return null;
        }
        //TODO:Content-Type應(yīng)該根據(jù)文件類型設(shè)置
        response.writeHead(200, {"Content-Type": "text/plain", "Content-Length": stats.size});

        //使用Stream
        var stream = fs.createReadStream("."+filePath);

        stream.on('data',function(chunk){
          response.write(chunk);
        });

        stream.on('end',function(){
          response.end();
        });

        stream.on('error',function(){
          response.end();
        });
      }
    );
  }
).listen(8000); 

console.log("Hello World start listen on port 8000");

最大的變化,就在傳遞給createServer方法的參數(shù)了。

我們根據(jù)request.method作了判斷,不是GET就返回403。如果是呢,就判斷文件是否存在,不存在,返回404,存在就讀取數(shù)據(jù)寫給客戶端。邏輯就是這么簡單。下面我們來介紹用到的新知識。

File System

要使用FileSystem,得用require引入fs模塊,就如前面代碼里那樣。File System的API老長老長了,看這里吧:https://nodejs.org/api/fs.html。我們只說用到的特性。

獲取文件狀態(tài)

在我們的FileServer里,收到和客戶端請求時先通過fs.stat()方法獲取文件狀態(tài)。fs.stat()方法原型如下:

fs.stat(path, callback)

第一個參數(shù)是文件路徑,第二個參數(shù)是回調(diào)函數(shù)。fs.stat()方法是異步的,結(jié)果通過回調(diào)函數(shù)callback返回。callback的原型如下:

function(err, stats)

第一個參數(shù)指示是否出現(xiàn)了錯誤,第二個參數(shù)是一個對象,類型是fs.Stats,保存了文件的狀態(tài)信息,比如大小、創(chuàng)建時間、修改時間等。

FileServer的代碼獲取到文件狀態(tài)后,讀取大小,調(diào)用http.ServerResponse的writeHead方法,設(shè)置HTTP狀態(tài)碼為200,還設(shè)置了Content-Length頭部。代碼如下:

復制代碼 代碼如下:
response.writeHead(200, {"Content-Type": "text/plain", "Content-Length": stats.size})

ReadStream

接下來呢,我們調(diào)用fs.createReadStream創(chuàng)建了一個ReadStream對象。ReadStream是Stream,也是EventEmitter。

fs.createReadStream方法原型如下:

fs.createReadStream(path[, options])

第一個參數(shù)是文件路徑,第二個參數(shù)是可選的JSON對象,用來指定打開文件的一些選項,默認值如下:

{ flags: ‘r', 
encoding: null, 
fd: null, 
mode: 0666, 
autoClose: true 
}

autoClose屬性默認為true,讀完文件或讀取出錯時,文件會被自動關(guān)閉。fd屬性可以關(guān)聯(lián)一個已有的文件描述符,這樣就會忽略path,根據(jù)一個已經(jīng)打開的文件來創(chuàng)建流。options還可以有start和end項,指定起、止位置,讀取文件的特定區(qū)域。如果我們要實現(xiàn)斷點續(xù)傳,就需要這個了,用法類似這樣:

fs.createReadStream('sample.mp4', {start: 1000, end: 10000});

encoding用來指定文件的編碼,這對于文本文件有特殊的意義,目前支持'utf8'、'ascii'和'base64'。

ReadStream讀取數(shù)據(jù)是異步的,一塊一塊的讀,讀到一部分就發(fā)送一個data事件,數(shù)據(jù)呢,會傳遞給與事件關(guān)聯(lián)的listener(實際上是一個回調(diào)方法)。在我們的代碼里,僅僅是調(diào)用response.write把數(shù)據(jù)寫給客戶端。注意,可能會多次調(diào)用response.write哦。又因為我們設(shè)置了Content-Length,所以不會采用chunked編碼方式。如果我們不設(shè)置Content-Length,那默認會啟用chunked方式。

ReadStream讀完文件時會發(fā)射end事件,出錯時會發(fā)射error事件,我們監(jiān)聽這兩個事件,簡單的終止響應(yīng)。

我們在示例代碼中看到了stream.on這種代碼,下面來解釋吧。

EventEmitter

Node.js基于V8引擎實現(xiàn)的事件驅(qū)動IO,是其最大最棒的特色之一。有了事件機制,就可以充分利用異步IO突破單線程編程模型的性能瓶頸,使得用JavaScript作后端開發(fā)有了實際意義。

EventEmitter的基本用法

events.EventEmitter是一個簡單的事件發(fā)射器的實現(xiàn),具有addListener、on、once、removeListener、emit等方法,開發(fā)者可以很方便的調(diào)用這些API監(jiān)聽某個事件或者發(fā)射某個事件。

我們在示例中用到的fs.ReadStream就是一個EventEmitter,它實現(xiàn)了stream.Readable接口,而stream.Readable具有data、error、end、close、readable等事件。

通常我們使用EventEmitter的on或addListener來監(jiān)聽一個事件,這個時間可能會多次觸發(fā),每次觸發(fā),我們提供的回調(diào)方法都會被調(diào)用。我們示例中的代碼就是這樣:

    stream.on('data',function(chunk){
      response.write(chunk);
    });

Node.js的事件機制,會給某個事件關(guān)聯(lián)一個回調(diào)方法列表,這樣多個關(guān)注者就可以監(jiān)聽同一個事件。每個事件發(fā)射時,可能會帶有數(shù)據(jù)和狀態(tài),這些數(shù)據(jù)是通過回調(diào)方法的參數(shù)傳遞出來的。那某一個特定的事件,它對應(yīng)的回調(diào)方法的參數(shù)是什么樣子的,則由事件定義的那個類(實例)來決定。EventEmitter的emit方法原型如下:

emitter.emit(event[, arg1][, arg2][, ...])

這個原型說明一個事件的回調(diào)方法可以有一個或多個參數(shù),也可以沒有參數(shù)。要想知道某個事件的回調(diào)方法是否有參數(shù)、每個參數(shù)的含義,只好去找相關(guān)的API文檔。stream.Readable的data事件的參數(shù)是chunk,Buffer類型,代表讀到的數(shù)據(jù)。

如果我們只想監(jiān)聽某個事件一次,則可以調(diào)用EventEmitter的once方法。要想移除一個事件監(jiān)聽器,可以調(diào)用removeListener,想移除所有,則可以調(diào)用removeAllListener。

自定義事件

Node.js的很多模塊都繼承自Event模塊。我們自己也可以通過繼承EventEmitter來實現(xiàn)自己的對象,添加自己的自定義事件。

這里有個簡單的例子:

var util=require("util");
var events = require("events");
function Ticker() {
  var self = this;
  events.EventEmitter.call(this);
  setInterval(function(){
    self.emit("tick")
    },
    1000
  );
}
util.inherits(Ticker, events.EventEmitter);

var ticker = new Ticker();
ticker.on("tick", function() {
 console.log("tick event");
});

在這個簡單的例子里,我們定義了Ticker對象,通過全局方法setInterval開啟了一個定時器,每隔1000毫秒發(fā)射一個名為“tick”的事件。

Node.js的工具模塊封裝了繼承的方法,我們調(diào)用它來的inherits方法來完成Ticker對events.EventEmitter的繼承。

自定義事件的使用方法,和Node.js內(nèi)置模塊提供的事件的用法完全一樣。

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • 在NodeJS中啟用ECMAScript 6小結(jié)(windos以及Linux)

    在NodeJS中啟用ECMAScript 6小結(jié)(windos以及Linux)

    ECMAScript 6 是JavaScript的下一代標準,其目標,是使得JavaScript可以用來編寫復雜的應(yīng)用程序、函數(shù)庫和代碼的自動生成器(code generator)。
    2014-07-07
  • 切換Node.js鏡像源的方法詳解

    切換Node.js鏡像源的方法詳解

    Node.js 是一個非常流行的 JavaScript 運行環(huán)境,擁有許多強大的功能和庫,使得它在 Web 開發(fā)、服務(wù)器端編程等領(lǐng)域中廣泛使用,在本文中,我們將介紹如何切換 Node.js 的鏡像源,并提供一些思考和難點,幫助讀者更好地理解這個問題,需要的朋友可以參考下
    2024-01-01
  • nvm如何查看node版本

    nvm如何查看node版本

    文章介紹了如何使用nvm查看Node.js版本,并解決了由于舊淘寶鏡像廢棄導致的命令無效問題,解決方法是在nvm的setting文件中添加特定代碼
    2024-12-12
  • node作為中間服務(wù)層如何發(fā)送請求(發(fā)送請求的實現(xiàn)方法詳解)

    node作為中間服務(wù)層如何發(fā)送請求(發(fā)送請求的實現(xiàn)方法詳解)

    node作為中間服務(wù)層如何發(fā)送請求?下面小編就為大家分享一下發(fā)送請求的實現(xiàn)方法,具有很好的參考價值,希望對大家有所幫助
    2018-01-01
  • Node.js五大應(yīng)用性能技巧小結(jié)(必須收藏)

    Node.js五大應(yīng)用性能技巧小結(jié)(必須收藏)

    本篇文章主要介紹了Node.js五大應(yīng)用性能技巧小結(jié)(必須收藏),小編覺得挺不錯的,現(xiàn)在分享給大家
    2017-08-08
  • Node.js中處理錯誤的4種最佳方法分享

    Node.js中處理錯誤的4種最佳方法分享

    錯誤處理并不是編碼工作中最吸引人的部分,但在?Node.js?中構(gòu)建可靠、生產(chǎn)級別的應(yīng)用程序時,它是絕對必要的,下面小編就來為大家介紹一下Node.js中處理錯誤的4種最佳方法吧
    2025-02-02
  • Node處理CPU密集型任務(wù)有哪些方法

    Node處理CPU密集型任務(wù)有哪些方法

    這篇文章主要介紹了Node處理CPU密集型任務(wù)有哪些方法,Node是一個非阻塞I/O和事件驅(qū)動的JavaScript運行環(huán)境,所以它非常適合用來構(gòu)建I/O密集型應(yīng)用,例如Web服務(wù)等
    2022-09-09
  • 手把手教你使用TypeScript開發(fā)Node.js應(yīng)用

    手把手教你使用TypeScript開發(fā)Node.js應(yīng)用

    為了減少代碼編寫過程中出現(xiàn)的錯誤,以及更好的維護你的項目,本文將手把手教你配置一個簡單的開發(fā)環(huán)境來編寫Node.js的應(yīng)用程序,感興趣的小伙伴們可以參考一下
    2019-05-05
  • node環(huán)境下運行js代碼缺少window環(huán)境的原因以及解決方法

    node環(huán)境下運行js代碼缺少window環(huán)境的原因以及解決方法

    Node是一個基于Chrome?V8引擎的運行環(huán)境,讓JavaScript運行在服務(wù)端的開發(fā)平臺,這篇文章主要給大家介紹了關(guān)于node環(huán)境下運行js代碼缺少window環(huán)境的原因以及解決方法,需要的朋友可以參考下
    2023-11-11
  • 在Node.js中使用TypeScript的方法示例

    在Node.js中使用TypeScript的方法示例

    在前端開發(fā)中,隨著TypeScript的不斷普及,越來越多的開發(fā)者使用TypeScript進行開發(fā),然而,在后端開發(fā)中,在Node.js中使用 TypeScript還是相對較少見的,這篇文章將介紹如何在Node.js中配置TypeScript ,以及如何使用TypeScript來開發(fā)高質(zhì)量的應(yīng)用程序
    2023-06-06

最新評論

宁海县| 五峰| 江阴市| 从江县| 仲巴县| 平谷区| 海晏县| 望城县| 额敏县| 高要市| 安图县| 剑川县| 南涧| 东至县| 广汉市| 吴忠市| 阿尔山市| 西峡县| 祥云县| 根河市| 永新县| 邓州市| 清远市| 色达县| 合阳县| 克什克腾旗| 吉木乃县| 敦化市| 新巴尔虎左旗| 达拉特旗| 桐庐县| 梅河口市| 体育| 额尔古纳市| 南城县| 获嘉县| 塔河县| 台东市| 渭南市| 山东省| 连南|