亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > JS > 正文

Node.js創建HTTP文件服務器的使用示例

2024-05-06 16:44:14
字體:
來源:轉載
供稿:網友

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

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

文件服務器FileServer的代碼

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

// 引入http模塊var http = require("http"); var fs = require("fs");// 創建server,指定處理客戶端請求的函數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);    //當文件存在時發送數據給客戶端,否則404    var fileStat = fs.stat("."+filePath,       function(err, stats){        if(err) {          response.writeHead(404);          response.end();          return null;        }        //TODO:Content-Type應該根據文件類型設置        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方法的參數了。

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

File System

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

獲取文件狀態

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

fs.stat(path, callback)

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

function(err, stats)

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

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

 

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

 

ReadStream

接下來呢,我們調用fs.createReadStream創建了一個ReadStream對象。ReadStream是Stream,也是EventEmitter。

fs.createReadStream方法原型如下:

fs.createReadStream(path[, options])

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

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

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

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

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

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

ReadStream讀完文件時會發射end事件,出錯時會發射error事件,我們監聽這兩個事件,簡單的終止響應。

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

EventEmitter

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

EventEmitter的基本用法

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

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

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

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

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

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

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

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

自定義事件

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

這里有個簡單的例子:

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毫秒發射一個名為“tick”的事件。

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

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

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VeVb武林網。


注:相關教程知識閱讀請移步到JavaScript/Ajax教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲国产黄色片| 琪琪亚洲精品午夜在线| 欧美专区国产专区| 欧美国产精品va在线观看| 欧美成人激情在线| 亚洲第一精品久久忘忧草社区| 欧美日韩国产成人| 日韩美女在线观看一区| 中文字幕免费精品一区高清| 欧美成人免费大片| 欧美日韩免费在线观看| 亚洲人午夜精品| 亚洲精品久久久久中文字幕二区| 亚洲资源在线看| 久久精品人人做人人爽| 另类少妇人与禽zozz0性伦| 亚洲视频在线免费看| 97涩涩爰在线观看亚洲| 69av在线视频| 欧美xxxx做受欧美.88| 亚洲大尺度美女在线| 国产精品久久二区| 国产精品久久久久高潮| 国产成人福利视频| 欧美激情在线一区| 国产精品九九久久久久久久| 欧美电影电视剧在线观看| 中文字幕日韩av| 中日韩美女免费视频网址在线观看| 日韩欧美中文字幕在线观看| 成人欧美在线视频| 久久久久久有精品国产| 精品久久久999| 亚洲精品在线91| 国产噜噜噜噜久久久久久久久| 精品国内自产拍在线观看| www日韩中文字幕在线看| 久久偷看各类女兵18女厕嘘嘘| 2024亚洲男人天堂| 亚洲人成伊人成综合网久久久| 日本精品中文字幕| 欧美又大粗又爽又黄大片视频| 91在线免费网站| 亚洲国产精品专区久久| 国产精品成人aaaaa网站| 亚洲欧洲成视频免费观看| 欧美激情精品久久久久久| 久久亚洲精品网站| 欧美日韩国产精品一区二区三区四区| 久久网福利资源网站| 国产精品96久久久久久又黄又硬| 亚洲欧美精品中文字幕在线| 激情成人中文字幕| 色小说视频一区| 国产精品成人av性教育| 欧美孕妇毛茸茸xxxx| 91精品国产综合久久香蕉| 午夜美女久久久久爽久久| 一区二区三区视频免费| 久久中文字幕一区| 成人免费黄色网| 亚洲第一级黄色片| 精品福利免费观看| 欧美国产高跟鞋裸体秀xxxhd| 亚洲欧美日韩直播| 久久视频国产精品免费视频在线| 成人性生交大片免费看小说| 国产精品丝袜一区二区三区| 国产精品视频在线观看| 国产精品午夜视频| 97精品伊人久久久大香线蕉| 成人av.网址在线网站| 久久久电影免费观看完整版| 欧美日韩色婷婷| 欧美色视频日本高清在线观看| 在线观看欧美视频| 国产免费一区二区三区在线观看| 欧美在线性视频| 精品成人国产在线观看男人呻吟| 亚洲欧美日韩在线一区| 中文字幕最新精品| 日韩va亚洲va欧洲va国产| 日韩欧美在线播放| 国产成人精品综合| 青青草一区二区| 国色天香2019中文字幕在线观看| 在线成人激情视频| 国产又爽又黄的激情精品视频| 亚洲综合中文字幕68页| 亚洲自拍偷拍福利| 亚洲色图50p| 欧美人交a欧美精品| 亚洲成人a**站| 国产成人精品在线观看| 欧美国产日本高清在线| 国产美女搞久久| 国产国语刺激对白av不卡| 欧美一级视频免费在线观看| 77777少妇光屁股久久一区| 国产精品精品国产| 一区二区三区国产视频| 韩国三级电影久久久久久| 亚洲一区二区日本| 亚洲精品国产综合久久| 久久精品国产一区二区三区| 欧美久久精品一级黑人c片| 久久免费少妇高潮久久精品99| 亚洲天堂精品在线| 国产精品视频公开费视频| 欧美一区二区视频97| 亚洲a级在线播放观看| 亚洲福利视频久久| 在线观看免费高清视频97| 精品少妇v888av| 欧美亚洲国产精品| 欧美刺激性大交免费视频| 精品毛片三在线观看| 国产精品成人av在线| 亚洲精品中文字幕女同| 久久久亚洲影院| 欧美色播在线播放| 中文字幕亚洲一区在线观看| 日韩av片电影专区| 久久久久久中文| 精品视频久久久久久| 欧美性受xxxx白人性爽| 欧美性在线视频| 亚洲字幕在线观看| 国产视频精品va久久久久久| 精品国产老师黑色丝袜高跟鞋| 日韩暖暖在线视频| 中文字幕亚洲无线码a| 一本色道久久88精品综合| 亚洲欧美www| 亚洲天堂色网站| 国产精品手机播放| 欧美成人在线免费视频| 亚洲精品乱码久久久久久金桔影视| 57pao国产成人免费| 欧美孕妇毛茸茸xxxx| 欧美激情亚洲视频| 中国china体内裑精亚洲片| 国产亚洲精品久久久| 久久久久久久久久久成人| 欧美国产视频一区二区| 92看片淫黄大片看国产片| 美女性感视频久久久| 欧美在线视频免费播放| 国产精品久久久久av| 欧美最猛黑人xxxx黑人猛叫黄| 久久久免费电影| 久久久久久亚洲精品不卡| 欧美高清videos高潮hd| 在线播放国产精品| 亚洲一区二区中文| 欧美日韩视频免费播放| 91高清视频免费| 国产精品一区二区三区成人| 欧美成aaa人片免费看| 欧美激情精品久久久久久| www.欧美精品一二三区| 欧美日韩中文字幕| 中文字幕久久久av一区| 欧美亚洲国产视频|