Ich versuche, einen statischen Dateiserver in nodejs eher als Übung zum Verständnis von node als als perfekten Server zu erstellen. Ich kenne Projekte wie Connect und Node-Static sehr gut und beabsichtige, diese Bibliotheken für produktionsfähigeren Code zu verwenden, aber ich verstehe auch gerne die Grundlagen meiner Arbeit. In diesem Sinne habe ich eine kleine server.js codiert:
var http = require('http'),
url = require('url'),
path = require('path'),
fs = require('fs');
var mimeTypes = {
"html": "text/html",
"jpeg": "image/jpeg",
"jpg": "image/jpeg",
"png": "image/png",
"js": "text/javascript",
"css": "text/css"};
http.createServer(function(req, res) {
var uri = url.parse(req.url).pathname;
var filename = path.join(process.cwd(), uri);
path.exists(filename, function(exists) {
if(!exists) {
console.log("not exists: " + filename);
res.writeHead(200, {'Content-Type': 'text/plain'});
res.write('404 Not Found\n');
res.end();
}
var mimeType = mimeTypes[path.extname(filename).split(".")[1]];
res.writeHead(200, mimeType);
var fileStream = fs.createReadStream(filename);
fileStream.pipe(res);
}); //end path.exists
}).listen(1337);
Meine Frage ist zweifach
Ist dies der "richtige" Weg, um grundlegende HTML-Dateien usw. im Knoten zu erstellen und zu streamen, oder gibt es eine bessere / elegantere / robustere Methode?
Tut die .pipe () im Knoten im Grunde nur Folgendes?
.
var fileStream = fs.createReadStream(filename);
fileStream.on('data', function (data) {
res.write(data);
});
fileStream.on('end', function() {
res.end();
});
Vielen Dank an alle!
fs.exists()
anstelle despath.exists()
obigen Codes. Prost! und ja! nicht vergessenreturn
:Antworten:
Ihr Basisserver sieht gut aus, außer:
Es
return
fehlt eine Aussage.Und:
res.writeHead(200, mimeType);
sollte sein:
res.writeHead(200, {'Content-Type':mimeType});
Ja
pipe()
macht das im Grunde, es pausiert / setzt auch den Quellstrom fort (falls der Empfänger langsamer ist). Hier ist der Quellcode derpipe()
Funktion: https://github.com/joyent/node/blob/master/lib/stream.jsquelle
Weniger ist mehr
Gehen Sie einfach zuerst zur Eingabeaufforderung Ihres Projekts und verwenden Sie
Dann schreiben Sie Ihren app.js Code wie folgt:
Sie würden dann einen "öffentlichen" Ordner erstellen, in dem Sie Ihre Dateien ablegen. Ich habe es zuerst auf die härtere Weise versucht, aber Sie müssen sich um MIME-Typen kümmern, die nur zeitaufwändige Dinge zuordnen müssen, und sich dann um Antworttypen usw. usw. usw. kümmern. Nein, danke.
quelle
require('http')
in der zweiten Zeile?Ich mag es auch zu verstehen, was unter der Haube vor sich geht.
Ich habe einige Dinge in Ihrem Code bemerkt, die Sie wahrscheinlich bereinigen möchten:
Es stürzt ab, wenn der Dateiname auf ein Verzeichnis verweist, da exist wahr ist und versucht wird, einen Dateistream zu lesen. Ich habe fs.lstatSync verwendet, um die Existenz eines Verzeichnisses zu bestimmen.
Die HTTP-Antwortcodes werden nicht korrekt verwendet (200, 404 usw.)
Während MimeType ermittelt wird (aus der Dateierweiterung), wird es in res.writeHead nicht richtig eingestellt (wie von stewe hervorgehoben).
Um mit Sonderzeichen umzugehen, möchten Sie wahrscheinlich den Uri verlassen
Es folgt blind Symlinks (könnte ein Sicherheitsrisiko sein)
Vor diesem Hintergrund sind einige der Apache-Optionen (FollowSymLinks, ShowIndexes usw.) sinnvoller. Ich habe den Code für Ihren einfachen Dateiserver wie folgt aktualisiert:
quelle
var mimeType = mimeTypes[path.extname(filename).match(/\.([^\.]+)$/)[1]];
quelle
Wie wäre es mit diesem Muster, bei dem nicht separat überprüft wird, ob die Datei vorhanden ist
quelle
fileStream.on('open', ...
Ich habe eine httpServer-Funktion mit zusätzlichen Funktionen für den allgemeinen Gebrauch basierend auf der Antwort von @Jeff Ward erstellt
Verwendung:
https://github.com/kenokabe/ConciseStaticHttpServer
Vielen Dank.
quelle
Das st-Modul erleichtert das Bereitstellen statischer Dateien. Hier ist ein Auszug aus README.md:
quelle
@ JasonSebring Antwort zeigte mir in die richtige Richtung, aber sein Code ist veraltet. So machen Sie es mit der neuesten
connect
Version.Im
connect
GitHub Repository gibt es andere Middlewares, die Sie verwenden können.quelle
connect
Dokumentation ansieht , ist es nur einwrapper
fürmiddleware
. Alle anderen interessantenmiddleware
stammen aus demexpress
Repository, sodass Sie diese APIs technisch mit dem verwenden könnenexpress.use()
.