Podręcznik
Express
Trasowanie
Obiekt app, utworzony za pomocą polecenia express(), dysponuje metodami odpowiadającymi metodom HTTP: get, post, put, delete itd. Za pomocą tych metod można określać trasy, które będą obsługiwane przez aplikację serwerową. Każda z tych metod wymaga podania co najmniej dwóch argumentów wejściowych:
- ścieżki (ang. path),
- funkcji (nazywanej po angielsku route handler, co nie ma powszechnie przyjętego polskiego odpowiednika) wywoływanej po nadejściu żądania zawierającego daną ścieżkę i metodę HTTP.
app.[metoda]([ścieżka], [route_handler]);
Jeśli, przykładowo, chcemy, aby żądanie metodą GET dla ścieżki /hello poskutkowało wysłaniem w odpowiedzi tekstu "Hello, world", to można to zrealizować w następujący sposób:
res.send('Hello, world');
});
W najprostszym przypadku, funkcja stanowiąca route handler powinna przyjmować dwa argumenty wejściowe, typowo nazywane req i res (od ang. request i response):
- pierwszy argument wejściowy reprezentuje przychodzące żądanie,
- drugi argument wejściowy reprezentuje odpowiedź, która zostanie wysłana przez aplikację serwerową.
Określanie ścieżek
Ścieżka, stanowiąca pierwszy argument metody app.get, app.post itp., może być podana w formie wyrażenia regularnego (ang. regular expression). Przykładowo, poniższe polecenie:
przypisze funkcję handler do wszystkich trzech następujących ścieżek:
- /
- /index
- /index.html
Trasy, zdefiniowane w kodzie aplikacji serwerowej, są podczas trasowania sprawdzane po kolei, a gdy jakaś trasa okaże się pasować do żądania, to dalsze nie będą już sprawdzane. Na końcu pliku można więc umieścić kod obsługujący wszystkie nieprzewidziane trasy:
// obsługa różnych przewidzianych tras
// ...
app.get("/*", (req, res) => unexpected_route_handler);
"/*" oznacza tu dowolną ścieżkę zaczynającą się od ukośnika.
Konstruowanie odpowiedzi
Odpowiedzi na żądania należy konstruować i wysyłać za pomocą metod obiektu res (będącego jednym z argumentów wejściowych metod takich jak app.get, app.post, ...). Do metod generujących odpowiedzi należą m.in.:
- res.send, służąca do wysyłania różnego rodzaju odpowiedzi, w tym prostego tekstu;
- res.sendFile, służąca do wysyłania plików;
- res.redirect, służąca do przekierowywania żądań;
- res.download, służąca do zlecania pobrania pliku.
Wywołanie dowolnej z powyższych metod skutkuje wysłaniem odpowiedzi i zakończeniem przetwarzania żądania. Jeśli żadna taka metoda nie zostanie wywołana, to żądanie może pozostać bez odpowiedzi.
Przykładowo, jeśli w odpowiedzi na żądanie GET ze ścieżką /contact ma być przesłany plik contact.html, zapisany w folderze views, to można to zrealizować w następujący sposób:
// ...
app.get("/contact", (req, res) => {
res.sendFile(path.join(__dirname, "views", "contact.html"));
});
Kody odpowiedzi
Express automatycznie dobiera kody odpowiedzi (np. 200 – OK, 404 – Not Found itp.). Można jednak również samemu ustalić kod za pomocą metody res.status. Przykładowo, jeśli w odpowiedzi na nieprzewidzianą ścieżkę chcemy wysłać przygotowany specjalnie na taką okazję plik not_found.html, zapisany w folderze views, to powinniśmy opatrzyć go kodem 404; można to zrealizować w następujący sposób:
Przekierowanie za pomocą metody res.redirect domyślnie opatrzone jest kodem 302 (oznaczającym przekierowanie tymczasowe). Przekierowanie z kodem 301 (sygnalizującym, że adres został zmieniony na stałe) można zrealizować w następujący sposób:
Przykład
Poniższy fragment kodu stanowi zebranie wcześniejszych przykładów i implementuje prostą aplikację serwerową. Aplikacja ta:
- W odpowiedzi na żądanie GET pod dowolną ze ścieżek: /, /index lub /index.html wysyła plik index.html, zapisany w folderze views, z kodem 200;
- W odpowiedzi na wszelkie inne żądania GET wysyła plik not_found.html, zapisany w folderze views, z kodem 404.
const express = require('express');
const app = express();
const port = 3000;
app.get("^/$|/index(.html)?", (req, res) => {
res.sendFile(path.join(__dirname, "views", "index.html"));
});
app.get("/*", (req, res) => {
res.status(404).sendFile(path.join(__dirname, "views", "not_found.html"));
})
app.listen(port, () => console.log(`Aplikacja serwerowa działa na porcie ${port}.`));
Więcej informacji: