Web-1/HTML formulieren

Uit Inf2019
Naar navigatie springen Naar zoeken springen
De printervriendelijke versie wordt niet langer ondersteund en kan weergavefouten bevatten. Werk uw browserbladwijzers bij en gebruik de gewone afdrukfunctie van de browser.
Web1
Netwerken

Zie ook Regels en richtlijnen
Zie ook Artikelen bewerken

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:


Web1-form-browser.png


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;
  • 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

Formulier test flow

NodeRed-code: /NodeRed-forms test

Voor het formulier gebruiken we twee HTTP-deelflows:

  1. de eerste deelflow is voor de GET van het HTML-document met daarin het formulier;
  2. 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

  1. maak deze formulier-flow in je eigen NodeRed-server:
    1. maak een nieuwe flow-pagina aan;
    2. maak daarin bovenstaande flow; kopieer deze eventueel van /NodeRed-forms test
  2. test deze formulier-flow:
    1. ga in de browser (met de ontwikkelaarstools; in de Netwerk-tab) na de welke berichten de browser ontvangt en verstuurt (request en response).
    2. voeg in NodeRed aan de uitgang van POST-knoop een debug-knoop toe, om de inhoud van het request te bekijken.
      1. configureer deze knoop zo dat deze het hele msg-object weergeeft (niet alleen de payload);
    3. bekijk de inhoud van een msg-object dat je zo krijgt in het debug-venster, in het bijzonder:
      1. - req.url
      2. - req.method
      3. - req.body
      4. - 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.

Website met login(1)

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

  1. Schakel de flow van de vorige pagina uit ("Disable" in de configuratie, via dubbel-klik op de tab-titel).
  2. Kopieer op een nieuwe pagina, de bovenstaande flow (via /NodeRed-login-1)
  3. Test deze flow: bezoek de verschillende pagina's, mogelijk met verschillende gebruikers.
    1. 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

  1. Verander het attribuut "name" in het formulier. Welke andere plaats(en) moet je dan ook aanpassen?
  2. voeg een input-veld toe, en verwerk dit in de POST-flow.
    1. bekijk het HTTP-request van het formulier in de browser-tools.
  3. 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".