Heim > Artikel > Web-Frontend > So erstellen Sie einen http-Dateiserver mit node.js
Dieses Mal zeige ich Ihnen, wie Sie mit node.js einen http-Dateiserver erstellen. Was sind die Vorsichtsmaßnahmen für die Verwendung von node.js zum Erstellen eines http-Dateiservers? Werfen wir einen Blick darauf.
Um Dateien zu lesen, verwenden wir das Dateisystemmodul (mit dem Namen „fs“) und Stream. Außerdem müssen wir die URL analysieren, die HTTP-Methode unterscheiden und EventEmitter verwenden .
FileServer-Code Nur die Parameter, die an die createServer-Methode übergeben werden. Wir haben eine Entscheidung basierend auf request.method getroffen. Wenn es nicht GET ist, wird 403 zurückgegeben. Wenn ja, stellen Sie fest, ob die Datei vorhanden ist. Wenn sie nicht vorhanden ist, geben Sie 404 zurück. Wenn sie vorhanden ist, lesen Sie die Daten und schreiben Sie sie auf den Client. Die Logik ist so einfach. Im Folgenden stellen wir die verwendeten neuen Erkenntnisse vor.
Dateisystem
Um FileSystem zu verwenden, müssen Sie require verwenden, um das fs-Modul einzuführen, genau wie im vorherigen Code. Die API des Dateisystems ist seit langem im Einsatz, schauen Sie hier nach: https://nodejs.org/api/fs.html. Wir sprechen nur über die verwendeten Funktionen. Den Dateistatus abrufen
Wenn wir in unserem FileServer eine Anfrage vom Client erhalten, rufen wir die Datei zunächst über fs.stat ab () Methodenstatus. Der Prototyp der Methode fs.stat() lautet wie folgt: // 引入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");
Der erste Parameter ist der Dateipfad und der zweite Parameter ist die Rückruffunktion. Die Methode fs.stat () ist asynchron und das Ergebnis wird über den Rückruf der Rückruffunktion zurückgegeben. Der Prototyp des Rückrufs lautet wie folgt:
fs.stat(path, callback)
Der erste Parameter gibt an, ob ein Fehler aufgetreten ist. Der zweite Parameter ist ein Objekt vom Typ fs.Stats, das die Statusinformationen der Datei speichert, wie z. B. Größe, Erstellungszeit, Änderungszeit usw.
Nachdem der FileServer-Code den Dateistatus erhalten hat, liest er die Größe, ruft die writeHead-Methode von http.ServerResponse auf, setzt den HTTP-Statuscode auf 200 und legt auch die Inhaltslänge fest Kopfzeile. Der Code lautet wie folgt:
Code kopierenDer Code lautet wie folgt:response.writeHead(200, {"Content-Type": "text/plain" , "Content-Length" : stats.size})
ReadStream
Als nächstes rufen wir fs.createReadStream auf, um ein ReadStream-Objekt zu erstellen. ReadStream ist ein Stream und ein EventEmitter. Der Prototyp der fs.createReadStream-Methode lautet wie folgt: function(err, stats)
Der erste Parameter ist der Dateipfad und der zweite Parameter ist ein optionales JSON-Objekt, mit dem einige Optionen zum Öffnen der Datei angegeben werden. Der Standardwert lautet wie folgt:
fs.createReadStream(path[, options])
Das autoClose-Attribut ist standardmäßig auf true gesetzt. Wenn die Datei gelesen wird oder ein Fehler auftritt, wird die Datei automatisch geschlossen. Das fd-Attribut kann mit einem vorhandenen Dateideskriptor verknüpft werden, sodass der Pfad ignoriert wird und der Stream basierend auf einer bereits geöffneten Datei erstellt wird. Optionen können auch Start- und Endelemente haben, die Start- und Endpositionen angeben und bestimmte Bereiche der Datei lesen. Wenn wir die Haltepunktwiederaufnahme implementieren möchten, ist die Verwendung ähnlich:
rrreeencoding wird verwendet, um die Codierung der Datei anzugeben. Dies hat derzeit eine besondere Bedeutung für Textdateien ' und 'ascii' ' und 'base64'.
ReadStream liest Daten asynchron und liest sie Stück für Stück. Beim Lesen eines Teils davon wird ein Datenereignis gesendet. Die Daten werden an den mit dem Ereignis verbundenen Listener übergeben (eigentlich eine Rückrufmethode). In unserem Code rufen wir einfach „response.write“ auf, um die Daten an den Client zu schreiben. Beachten Sie, dass „response.write“ mehrmals aufgerufen werden kann. Und da wir Content-Length festlegen, wird keine Chunked-Codierung verwendet. Wenn wir Content-Length nicht festlegen, wird standardmäßig der Chunked-Modus aktiviert.
ReadStream gibt das Endereignis aus, wenn das Lesen der Datei abgeschlossen ist, und das Fehlerereignis, wenn ein Fehler auftritt. Wir hören auf diese beiden Ereignisse und beenden einfach die Antwort.
Wir haben Code wie stream.on im Beispielcode gesehen. Lassen Sie es uns unten erklären.
EventEmitter
Das von Node.js basierend auf der V8-Engine implementierte ereignisgesteuerte IO ist eines seiner größten und besten Features. Mit dem Ereignismechanismus kann asynchrones E/A vollständig genutzt werden, um den Leistungsengpass des Single-Threaded-Programmiermodells zu überwinden, wodurch die Verwendung von JavaScript für die Back-End-Entwicklung praktisch wird. EventEmitter的基本用法 events.EventEmitter是一个简单的事件发射器的实现,具有addListener、on、once、removeListener、emit等方法,开发者可以很方便的调用这些API监听某个事件或者发射某个事件。 我们在示例中用到的fs.ReadStream就是一个EventEmitter,它实现了stream.Readable接口,而stream.Readable具有data、error、end、close、readable等事件。 通常我们使用EventEmitter的on或addListener来监听一个事件,这个时间可能会多次触发,每次触发,我们提供的回调方法都会被调用。我们示例中的代码就是这样: Node.js的事件机制,会给某个事件关联一个回调方法列表,这样多个关注者就可以监听同一个事件。每个事件发射时,可能会带有数据和状态,这些数据是通过回调方法的参数传递出来的。那某一个特定的事件,它对应的回调方法的参数是什么样子的,则由事件定义的那个类(实例)来决定。EventEmitter的emit方法原型如下: 这个原型说明一个事件的回调方法可以有一个或多个参数,也可以没有参数。要想知道某个事件的回调方法是否有参数、每个参数的含义,只好去找相关的API文档。stream.Readable的data事件的参数是chunk,Buffer类型,代表读到的数据。 如果我们只想监听某个事件一次,则可以调用EventEmitter的once方法。要想移除一个事件监听器,可以调用removeListener,想移除所有,则可以调用removeAllListener。 自定义事件 Node.js的很多模块都继承自Event模块。我们自己也可以通过继承EventEmitter来实现自己的对象,添加自己的自定义事件。 这里有个简单的例子: 在这个简单的例子里,我们定义了Ticker对象,通过全局方法setInterval开启了一个定时器,每隔1000毫秒发射一个名为“tick”的事件。 Node.js的工具模块封装了继承的方法,我们调用它来的inherits方法来完成Ticker对events.EventEmitter的继承。 自定义事件的使用方法,和Node.js内置模块提供的事件的用法完全一样。 相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章! 推荐阅读: stream.on('data',function(chunk){
response.write(chunk);
});
emitter.emit(event[, arg1][, arg2][, ...])
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");
});
Das obige ist der detaillierte Inhalt vonSo erstellen Sie einen http-Dateiserver mit node.js. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!