Web-1/HTML formulieren
HTTP POST: formulieren
Met behulp van een HTML-formulier kun je informatie van de client (browser) naar de server sturen. Je gebruikt dit bijvoorbeeld voor het toevoegen van een artikel aan een webwinkel-wagentje, of bij het opgeven van je adres voor een webwinkel. Een HTML-formulier bestaat uit een aantal invulvelden en een Submit-button. Met de Submit-button verstuur je de inhoud van het formulier naar de server. De inhoud van het formuluer is een lijst met naam=waarde
elementen. Er zijn veel verschillende soorten invulvelden, bijvoorbeeld voor tekst, getallen, keuze uit een aantal alternatieven, enz.
In deze opdracht gebruiken we een eenvoudig HTML-formulier met een enkel invulveld, waarin de gebruiker zijn naam kan opgeven. In de browser ziet dit formulier er als volgt uit:
Dit formulier is onderdeel van een HTML-pagina. Voor dit formulier gebruiken we de volgende HTML-code:
<form method="post" action="/login-form">
Login:
<input type="text" name="username">
<button type="submit">Verstuur</button>
</form>
Toelichting:
- de form-tag heeft hier twee attributen:
method
: de opdracht in het HTTP-request request waarmee het formulier verstuurd wordt; hier:POST
action
: de URL in het HTTP-request
- het invulveld geef je aan met de
input
-tag, met als attributen:- het type van de invoer; hier:
type="text"
; - de naam van het invoerveld , hier:
name="username"
- merk op dat de input-tag geen afsluitende tag heeft;
- het type van de invoer; hier:
- de submit-button wordt gebruikt om het formulier te versturen, als HTTP-request.
Bij een submit stuurt de browser een HTTP-request naar de server, met de volgende elementen:
- method:
POST
- URL:
/login-form
- inhoud:
username=Hans
De server verwerkt bij het ontvangen van dit request de gegevens in de inhoud en stuurt een response, bijvoorbeeld in de vorm van een HTML-bestand. Bij dit voorbeeld stuurt de server een HTML-document op waarin de naam van de gebruiker ingevuld is.
Formulier flow: GET en POST
NodeRed-code: /NodeRed-forms test
Voor het formulier gebruiken we twee HTTP-deelflows:
- de eerste deelflow is voor de GET van het HTML-document met daarin het formulier;
- de tweede deelflow is voor de POST van de formulier-gegevens, met als resultaat een HTML-document waarin deze gegevens ingevuld zijn.
Merk op dat de URL voor beide deelflows dezelfde is - maar de methodes verschillen (GET en POST).
De pagina voor de GET-deelflow:
<!doctype html>
<html>
<head>
<title>Welkom</title>
</head>
<body>
<h1>Welkom op mijn website</h1>
<form method="post" action="/login-form">
Login:
<input type="text" name="username">
<button type="submit">Verstuur</button>
</form>
</body>
</html>
De pagina voor de POST-deelflow is een template waarin we de naam van de gebruiker weergeven, zoals die opgestuurd is met het formulier.
<!doctype html>
<html>
<head>
<title>Welkom!</title>
</head>
<body>
<p>Welkom {{payload.username}}!</p>
<a href="/login">Login</a>
</body>
</html>
Opdrachten
- maak deze formulier-flow in je eigen NodeRed-server:
- maak een nieuwe flow-pagina aan;
- maak daarin bovenstaande flow; kopieer deze eventueel van /NodeRed-forms test
- test deze formulier-flow:
- ga in de browser (met de ontwikkelaarstools; in de Netwerk-tab) na de welke berichten de browser ontvangt en verstuurt (request en response).
- voeg in NodeRed aan de uitgang van POST-knoop een debug-knoop toe, om de inhoud van het request te bekijken.
- configureer deze knoop zo dat deze het hele msg-object weergeeft (niet alleen de payload);
- bekijk de inhoud van een msg-object dat je zo krijgt in het debug-venster, in het bijzonder:
- - req.url
- - req.method
- - req.body
- - req.headers
Extra opdrachten
- verander het "name" attribuut van het invoerveld. Welke andere plaats(en) moet je dan ook aanpassen?
- voeg een extra invoerveld toe aan het formulier. Pas ook de verwerking van het formulier daarop aan.
Login-pagina als onderdeel van de website
In deze opdracht combineren we de pagina's van de website met deze login-pagina. We gebruiken een page-template voor het gemeenschappelijke deel van de pagina's.
NodeRed-code: /NodeRed-login-1
Deze flow zullen we in latere versies uitbreiden, zodat we bijvoorbeeld de naam van de ingelogde gebruiker op elke pagina kunnen tonen.
Opdrachten
- Schakel de flow van de vorige pagina uit ("Disable" in de configuratie, via dubbel-klik op de tab-titel).
- Kopieer op een nieuwe pagina, de bovenstaande flow (via /NodeRed-login-1)
- Test deze flow: bezoek de verschillende pagina's, mogelijk met verschillende gebruikers.
- Controleer dat elke pagina dezelfde header en footer (navigatie) heeft.
Meer over formulieren
HTTP POST gegevens
De inhoud van het POST-request bestaat uit een reeks naam-waarde paren. In NodeRed is deze inhoud beschikbaar als de payload van de NodeRed-message. Het Mustache-template gebruikt de eigenschappen van de NodeRed-message. We noteren daarom de waarde van de username in het template als: {{payload.username}}
.
HTTP GET gegevens
Je kunt een formulier ook via een HTTP GET-request naar de server sturen. In dat geval vind je de gegevens in NodeRed via msg.req.query
.
- de formulier-informatie wordt bij een GET-request verstuurt als onderdeel van de URL. Bij een POST-request wordt dit verstuurd in de inhoud (body) van het request-bericht.
GET of POST? Idempotentie
Wat is het verschil? Wanneer gebruik je POST, wanneer GET?
- POST is bedoeld voor formulieren die de toestand van de server veranderen. Voorbeeld: bestellen van een artikel in een webshop.
- GET is bedoeld voor formulieren die de toestand van de server niet veranderen. Voorbeeld: zoekopdrachten.
GET is (volgens de afspraken van het web) idempotent: het maakt geen verschil of je deze eenmaal of vaker uitvoert, je krijgt steeds hetzelfde resultaat. Dit geldt voor het ophalen van een normale pagina; dit moet je ook garanderen voor het opsturen van een formulier met GET.
POST is (volgens de afspraken van het web) niet noodzakelijk idempotent: het opnieuw versturen van een formulier kan bijvoorbeeld resulteren in een dubbele bestelling. De browser kent dit onderscheid: deze zal bij het opnieuw opsturen van een formulier met POST vragen of dat echt te bedoeling is.
Let op
- een input-element in een formulier heeft een "name" en een "value" attribuut.
- daarnaast kan een item een "id"-attribuut hebben - dat heeft een heel andere rol dan een "name" attribuut.
Andere opdrachten
- Verander het attribuut "name" in het formulier. Welke andere plaats(en) moet je dan ook aanpassen?
- voeg een input-veld toe, en verwerk dit in de POST-flow.
- bekijk het HTTP-request van het formulier in de browser-tools.
- voeg een debug-node toe aan de http-input node POST-
/login
.
Vervolg: server state en cookies
- een formulier heeft vaak invloed op de toestand van de server. In een volgend hoofdstuk gaan we in op die mogelijkheid: we houden in de server een lijst van ingelogde gebruikers bij.
- voor het onthouden van de gebruiker die lokaal ingelogd heeft is de toestand van de server niet voldoende: we moeten die naam bijhouden in de toestand van de client (browser). De technische oplossing daarvoor bestaat uit "cookies".