W Express req.params zawiera wartości nazwanych segmentów ścieżki trasy (/users/:id daje req.params.id), req.query zawiera query string po ? (/search?q=node daje req.query.q), a req.body zawiera dane wysłane w body żądania. req.params i req.query są wypełniane przy każdym żądaniu, ale req.body zostaje undefined, dopóki nie odczyta go parser body, np. app.use(express.json()). Wartości w params i query to zawsze stringi.
Pierwsze żądanie odpowiada {"params":{"userId":"7"},"query":{"sort":"new","limit":"2"}}. Zwróć uwagę na cudzysłowy: 7 i 2 to stringi, więc zamień je przez Number(), zanim zaczniesz liczyć albo porównywać z liczbami. Teraz zmień metodę na POST, zostaw ścieżkę /users/7/posts i wyślij body {"title": "Hello", "draft": true}: odpowiedź to 201 z "body":{"title":"Hello","draft":true}, gdzie true to prawdziwy boolean, bo przyszedł z JSON.
req.params vs req.query vs req.body
req.params | req.query | req.body | |
|---|---|---|---|
| Skąd pochodzi | Ze ścieżki, /users/:id | Z query stringa, ?sort=new | Z body żądania |
| Przykładowy URL lub body | /users/7 | /users?sort=new | {"name": "Ada"} |
| Wartość | { id: '7' } | { sort: 'new' } | { name: 'Ada' } |
| Typy | Stringi | Stringi i tablice stringów | To, co zawiera JSON |
| Wymaga konfiguracji | :name w trasie | Niczego | app.use(express.json()) |
| Typowe użycie | Który zasób | Filtrowanie, sortowanie, strony | Dane do utworzenia lub zmiany |
Trasa może mieć kilka parametrów, a każda nazwa staje się kluczem w req.params: /teams/:teamId/members/:memberId daje oba identyfikatory. Rozdziela je też myślnik lub kropka, więc /flights/:from-:to zamienia /flights/LAX-SFO w { from: 'LAX', to: 'SFO' }.
req.query z powtórzonymi i brakującymi kluczami
Klucz, który występuje dwa razy, staje się tablicą, a brakujący klucz to undefined, więc daj opcjom wartość domyślną:
Odpowiedź to {"page":1,"tags":["red","sale"],"raw":{"tag":["red","sale"]}}. Wyślij GET /products?tag=red&page=3, a tags nadal jest tablicą, ["red"], bo [].concat() zamienia string albo tablicę w tablicę. Express 5 parsuje query stringi prostym parserem Node, więc ?filter[size]=m daje klucz "filter[size]", a nie zagnieżdżony obiekt; Express 4 go zagnieżdżał.
req.body wymaga express.json()
Node dostarcza body jako strumień bajtów. express.json() czyta go, parsuje i ustawia req.body, ale tylko wtedy, gdy żądanie ma Content-Type: application/json. Formularze HTML wysyłają application/x-www-form-urlencoded, do którego potrzebny jest express.urlencoded().
Wyślij POST /signup z body {"email": "ada@example.com"}, a dostaniesz 201 z {"email":"ada@example.com","name":"anonymous"}. Wyślij puste body, a dostaniesz 400. ?? {} ma znaczenie: bez niego destrukturyzacja undefined rzuca TypeError przy każdym żądaniu bez body w JSON. Do prawdziwej walidacji kształtu i typów użyj biblioteki schematów, np. zod.
req.headers i req.get()
req.headers to obiekt ze wszystkimi nagłówkami żądania, z nazwami zapisanymi małymi literami. req.get(name) czyta jeden nagłówek i ignoruje wielkość liter, więc req.get('Content-Type') i req.get('content-type') zwracają tę samą wartość. Kilka innych właściwości, których będziesz używać:
path to /whoami, a originalUrl to /whoami?debug=1. Dodaj w pasku żądania nagłówek Authorization: Bearer abc i wyślij jeszcze raz: token zmieni się na "Bearer abc". W routerze podpiętym przez app.use('/api', router) req.path traci prefiks /api, a req.originalUrl go zachowuje (routing w Express wyjaśnia podpinanie).
Częste błędy
Odczytywanie req.body w żądaniu GET. Przeglądarki i większość klientów nie wysyłają body z GET. Opcje dla GET umieszczaj w query stringu.
Sprawdzanie flagi z query jako wartości truthy. ?admin=false daje string 'false', który jest truthy, więc if (req.query.admin) przechodzi. Porównuj stringi: req.query.admin === 'true'.
Wysyłanie JSON bez nagłówka. Klient, który wysyła JSON jako text/plain, dostaje req.body === undefined. Ustaw Content-Type: application/json po stronie klienta.
Najczęściej zadawane pytania
Jak pobrać adres IP klienta w Express?
Odczytaj req.ip. Za proxy lub load balancerem to adres proxy, dopóki nie ustawisz app.set('trust proxy', 1), wtedy Express czyta nagłówek X-Forwarded-For.
Jak pobrać pełny URL żądania w Express?
req.originalUrl to ścieżka plus query string w takiej postaci, w jakiej wysłał je klient. Pełny adres zbudujesz przez `${req.protocol}://${req.get('host')}${req.originalUrl}`.
Jak obsłużyć upload plików w Express?
Uploady plików przychodzą jako multipart/form-data, którego express.json() i express.urlencoded() nie parsują. Użyj pakietu takiego jak multer, który wkłada pliki do req.file lub req.files, a pozostałe pola do req.body.
Jak odczytać ciasteczko z żądania?
Surowy nagłówek jest w req.get('cookie'). Żeby dostać obiekt w req.cookies, zainstaluj pakiet cookie-parser i dodaj app.use(cookieParser()).