Kontynuujemy prace nad naszym serwerem node.js, który teraz będzie miał możliwość serwowania wszystkich plików o wszystkich rozszerzeniach.

Przykład z poprzedniej lekcji:

const fs = require("fs");
const path = require("path");
const http = require("http");

const server = http.createServer(function(req, res) {

    var fileName = null;
    var file = null;

    var url = req.url;

    url = url.startsWith("/") ? url.slice(1) : url;
    url = url.includes("?") ? url.slice(0, url.indexOf("?")) : url;

    if(url === "") {
        fileName = "lorem.txt";
    } else {
        fileName = url;
    }
    
    file = fs.createReadStream(path.join(__dirname, "files", fileName));

    file.on("error", function(err) {

        res.writeHead(404, "Not Found");
        res.end();

    });

    res.writeHead(200, {"Content-Type": "text/plain"});

    file.pipe(res);

});

server.listen(8080, function() {
    console.log("Serwer uruchomiony pod adresem: http://localhost:8080");
});

Ok, teraz dodajmy sobie taki słownik:

const MIME_TYPES = {
    ".txt": "text/plain",
    'default': "text/plain",
};

Teraz tworzymy nowe zmienne mime oraz extension:

const server = http.createServer(function(req, res) {

    var fileName = null;
    var file = null;

    var url = req.url;

    url = url.startsWith("/") ? url.slice(1) : url;
    url = url.includes("?") ? url.slice(0, url.indexOf("?")) : url;

    if(url === "") {
        fileName = "lorem.txt";
    } else {
        fileName = url;
    }

    var extension = path.extname(fileName);
    var mime;

    //(...)

Teraz obsłużymy wyjątek, w którym extension nie jest podane (czyli daliśmy blabla zamiast blabla.txt):

var extension = path.extname(fileName);
    var mime;

    if(!extension){
        extension = ".txt"
        fileName += extension;
        mime = MIME_TYPES[extension];
    }

Jeżeli rozszerzenia nie ma, to zakładamy, że chodzi o txt, poprawiamy filename oraz ustawiamy mime.

Teraz ustawienie MIME, gdy rozszerzenie jest:

//(...)
if(!extension){
        extension = ".txt"
        fileName += extension;
        mime = MIME_TYPES[extension];
    } else {
        mime = MIME_TYPES.hasOwnProperty(extension) ? MIME_TYPES[extension] : MIME_TYPES['default'];
    }
//(...)

Jeżeli jest to sprawdzamy, czy w MIME_TYPES mamy taki klucz. Jak nie – dajemy default. Teraz tylko musimy ustawić odpowiedni nagłówek:

file = fs.createReadStream(path.join(__dirname, "files", fileName));
   
    file.on("error", function(err) {

        res.writeHead(404, "Not Found");
        res.end();

    });

    res.writeHead(200, {"Content-Type": mime});

    file.pipe(res);

Na chwilę obecną będzie działać tylko dla plików txt, nawet jak pominiemy rozszerzenie.

Zróbmy w files plik widget.json:

{"widget": {
    "debug": "on",
    "window": {
        "title": "Sample Konfabulator Widget",
        "name": "main_window",
        "width": 500,
        "height": 500
    },
    "image": { 
        "src": "Images/Sun.png",
        "name": "sun1",
        "hOffset": 250,
        "vOffset": 250,
        "alignment": "center"
    },
    "text": {
        "data": "Click Here",
        "size": 36,
        "style": "bold",
        "name": "text1",
        "hOffset": 250,
        "vOffset": 100,
        "alignment": "center",
        "onMouseUp": "sun1.opacity = (sun1.opacity / 100) * 90;"
    }
}}  

Dodajmy json do mime_types:

const MIME_TYPES = {
    ".txt": "text/plain",
    '.json' : 'application/json',
    'default': "text/plain",
};

Całość serwera powinna wyglądać tak i bez problemu obsługiwać pliki json, txt oraz pliki txt bez rozszerzenia txt w urlu (jak również query strings, które są pomijane):

const server = http.createServer(function(req, res) {

    var fileName = null;
    var file = null;

    var url = req.url;

    url = url.startsWith("/") ? url.slice(1) : url;
    url = url.includes("?") ? url.slice(0, url.indexOf("?")) : url;

    if(url === "") {
        fileName = "lorem.txt";
    } else {
        fileName = url;
    }

    var extension = path.extname(fileName);
    var mime;

    if(!extension){
        extension = ".txt"
        fileName += extension;
        mime = MIME_TYPES[extension];
    } else {
        mime = MIME_TYPES.hasOwnProperty(extension) ? MIME_TYPES[extension] : MIME_TYPES['default'];
    }
    

    file = fs.createReadStream(path.join(__dirname, "files", fileName));
   
    file.on("error", function(err) {

        res.writeHead(404, "Not Found");
        res.end();

    });

    res.writeHead(200, {"Content-Type": mime});

    file.pipe(res);

});

server.listen(8080, function() {
    console.log("Serwer uruchomiony pod adresem: http://localhost:8080");
});

Stworzyliśmy naprawdę fajny mini-projekt w czystym node.