Node.js/Webserver
Text-Info
-
30min
- mittel
- JavaScript
Die für eine Response nötige Software fällt im Allgemeinen in zwei Kategorien: Frontend und Backend.
- Das clientseitige Frontend wird aus HTML, CSS und, falls Interaktivität nötig ist, JavaScript zusammengebaut.
- Das serverseitige Backend befasst sich mit dem Austausch, der Verarbeitung und Speicherung von Daten auf dem Server.
Mit Node.js können Sie JavaScript auch im Backend auf dem Server nutzen.
In diesem Tutorial lernen Sie, wie Sie einen Webserver mit dem in Node.js schon enthaltenen http-Modul einrichten können. Das Beispiel basiert auf einem Konzept von Jared Wilcurt, das auf github zu finden ist.
Inhaltsverzeichnis
Mein erster Webserver
Node.js hat ein eingebautes Modul namens HTTP,
das es Node.js ermöglicht, Daten über das Hyper Text Transfer Protocol (HTTP) zu übertragen.
Um das HTTP-Modul einzubinden, verwende die require()
-Methode.[1] Es hat sich als Konvention etabliert, dass die Variable dem Namen des eingebundenen Moduls entspricht.
1 const http = require('http');
2 var port = 8080;
3
4 http.createServer((request, response) => {
5 response.writeHead(200, {
6 'Content-Type': 'text/plain'
7 });
8 response.write('Server funzt!\n');
9 response.end();
10 }).listen(port);
Die createServer()-Funktion erzeugt einen Server, der als Parameter ein Anfrageobjekt (request
) und ein Antwortobjekt (response
) enthält.
- Die HTTP-Anfrage wird im Anfrageobjekt erfasst.
- Die HTTP-Antwort wird mit weiteren Methoden erzeugt:
- response.writeHead() sendet einen Dokument-Header, der …
- dem Browser mitteilt, dass die Anfrage erfolgreich war (status code 200) und Klartext übermittelt wird.
- response.write() übermittelt den body (Dokumentinhalt) der Seite
- response.end() zeigt, dass header und body der Response übermittelt worden sind.
- response.writeHead() sendet einen Dokument-Header, der …
- mit listen() kann der Port übermittelt werden.
Speicher das Script als server.js
und rufe es im Terminal auf.
http://localhost:8080
ein:Die Angabe localhost
für die interne IP-Adresse 127.0.0.1
ist nur für den lokalen Computer verfügbar, nicht für die lokalen Netzwerke, mit denen wir verbunden sind, oder gar für das Internet.
Um im Terminal anzuzeigen, dass der Server läuft, können wir eine Meldung ausgeben:
var port = 8080;
...
http.createServer((request, response) => {
...
}).listen(port);
// Nachricht, die im Terminal ausgegeben wird.
console.log(WHT + 'Statischer Webserver läuft auf\n => http://localhost:' + port + '/\nCTRL + C zum Beenden');
Ausliefern einer Webseite
In einem zweiten Schritt soll unser Webserver nicht nur einen Text, sondern eine komplette Webseite in HTML senden.
const http = require('http');
let port = 8080;
http.createServer((request, response) => {
response.writeHead(200, {
'Content-Type': 'text/html'
});
response.write(`<html><body><h1>Das ist HTML</h1><p>Und das ein Absatz!</p></body></html>`);
response.end();
}).listen(port);
// Nachricht, die im Terminal ausgegeben wird.
console.log(WHT + 'Statischer Webserver läuft auf\n => http://localhost:' + port + '/\nCTRL + C zum Beenden');
In response.writeHead
wird der MIME-Type auf text/html
geändert.
response.write
sendet einen langen String voller HTML-Tags.
Schön ist anders.
Im Normalfall sendet ein Server als Antwort auf eine Anfrage nicht eine Zeichenkette, sondern ein HTML-Dokument und weitere Dateien wie Bilder, PDFs oder Videos. Ob diese als physische Dateien auf dem Server vorhanden sind oder vom Server aus Inhalten einer Datenbank dynamisch zusammengestellt wird, spielt dabei keine Rolle. Diese Aufgabentrennung (engl. Separation of concerns) ermöglicht es, unsere Scripte kürzer und übersichtlicher zu halten.
File System - Dateien schreiben und lesen
Unser Server wird nun so erweitert, dass er Dokumente mit dem passenden MIME-Type ausliefert. Anfragen ohne entsprechenden Inhalt sollen nicht mit 200 (ok), sondern mit einer Fehlermeldung 404 (not found) beantwortet werden.
Eigentlich kann JavaScript Dateien weder auslesen noch schreiben. Mit dem in Node.js integrierten File System ist dies mittlerweile möglich.[2]
Das Filesystem wird mit require(fs)
aufgerufen.
// Require in some of the native stuff that comes with Node
var http = require('http');
var url = require('url');
var path = require('path');
var fs = require('fs');
// Port number to use
var port = 8080;
// Colors for CLI output
var WHITE = '\033[39m';
var RED = '\033[91m';
var GREEN = '\033[32m';
// Create the server
http.createServer(function (request, response) {
// The requested URL, like http://localhost:8000/file.html => /file.html
var uri = url.parse(request.url).pathname;
// get the /file.html from above and then find it from the current folder
var filename = path.join(process.cwd(), uri);
// Setting up MIME-Type (YOU MAY NEED TO ADD MORE HERE) <--------
var contentTypesByExtension = {
'.html': 'text/html',
'.css': 'text/css',
'.js': 'text/javascript',
'.json': 'text/json',
'.svg': 'image/svg+xml'
};
// Check if the requested file exists
fs.exists(filename, function (exists) {
// If it doesn't
if (!exists) {
// Output a red error pointing to failed request
console.log(RED + 'FAIL: ' + filename);
// Redirect the browser to the 404 page
filename = path.join(process.cwd(), '/404.html');
// If the requested URL is a folder, like http://localhost:8000/catpics
} else if (fs.statSync(filename).isDirectory()) {
// Output a green line to the console explaining what folder was requested
console.log(GREEN + 'FLDR: ' + WHITE + filename);
// redirect the user to the index.html in the requested folder
filename += '/index.html';
}
// Assuming the file exists, read it
fs.readFile(filename, 'binary', function (err, file) {
// Output a green line to console explaining the file that will be loaded in the browser
console.log(GREEN + 'FILE: ' + WHITE + filename);
// If there was an error trying to read the file
if (err) {
// Put the error in the browser
response.writeHead(500, {'Content-Type': 'text/plain'});
response.write(err + '\n');
response.end();
return;
}
// Otherwise, declare a headers object and a var for the MIME-Type
var headers = {};
var contentType = contentTypesByExtension[path.extname(filename)];
// If the requested file has a matching MIME-Type
if (contentType) {
// Set it in the headers
headers['Content-Type'] = contentType;
}
// Output the read file to the browser for it to load
response.writeHead(200, headers);
response.write(file, 'binary');
response.end();
});
});
}).listen(parseInt(port, 10));
// Nachricht, die im Terminal ausgegeben wird.
console.log(WHITE + 'Static file server running at\n => http://localhost:' + port + '/\nCTRL + C to shutdown');
Ein solcher Server könnte einfach zu einem HTTPS-Server erweitert werden. Dazu würdest Du aber noch Zertifikate benötigen.[3]
Weblinks
- github:
- npm-Free-Server
This is a very tiny server. Without comments it's 50 lines of code and it's <1KB (minified). - local-web-server
A lean, modular web server for rapid full-stack development.- Supports HTTP, HTTPS and HTTP2.
- Small and 100% personalisable. Load and use only the behaviour required by your project.
- Attach a custom view to personalise how activity is visualised.
- Programmatic and command-line interfaces.
- npm-Free-Server
Quellen
- ↑ Node.js: require()
- ↑ Node.js: File System
- ↑ Node.js: How to create an https server?.