- Leren
- Informatica & ICT
- Programmeren
- JavaScript programmeren: DOM, events, asynchrone code en modules
- Gegevens ophalen en browser-API's
Gegevens ophalen en browser-API's
fetch, de resultaten op een webpagina te tonen en kleine hoeveelheden gegevens in de browser te bewaren. Je leest HTTP-verzoeken, HTTP-antwoorden en JSON, handelt laad- en foutstatussen af en geeft datums en prijzen uit een API de juiste opmaak voor elke lezer. Je ontdekt waarom CORS-fouten ontstaan en waarom geheime API-sleutels niet thuishoren in frontendcode. Daarna gebruik je localStorage, sessionStorage en browserfuncties zoals geolocatie en het klembord.BeginnerLes 8 van 9 in Cursus JavaScript programmeren: DOM, events, asynchrone code en modules
Wat je leert
- Leg uit hoe een HTTP-verzoek en een HTTP-antwoord werken, laad JSON-gegevens met
fetchen verstuur gegevens naar een API met de juiste methode, headers en verzoekinhoud.- Lees HTTP-verzoeken en HTTP-antwoordenBeschrijf de onderdelen van een HTTP-verzoek en een HTTP-antwoord, koppel elke HTTP-methode aan de handeling die ze uitvoert en lees statuscodes en headers in de ontwikkelaarstools van de browser.
- Laad JSON-gegevens met fetchRoep
fetchaan, controleer de status van het antwoord, lees en ontleed de JSON-inhoud en bouw verzoek-URL's met correct gecodeerde queryparameters. - Verstuur gegevens met POST, PUT, PATCH en DELETEGeef een optieobject door aan
fetchom JSON of formuliergegevens te versturen en handel het antwoord van de server af nadat je een record hebt gemaakt, bijgewerkt of verwijderd.
- Lees HTTP-verzoeken en HTTP-antwoorden
- Zet API-resultaten om in pagina-inhoud, geef datums en geldbedragen de juiste opmaak voor de lezer en houd de pagina duidelijk terwijl gegevens worden geladen, het laden mislukt of resultaten in een andere volgorde binnenkomen.
- Render API-resultaten op de paginaBouw pagina-elementen op uit de arrays en objecten in een JSON-antwoord, voeg API-tekst veilig in en handel ontbrekende velden, lege resultaten en resultaten op meerdere pagina's af.
- Geef datums, getallen en geldbedragen uit API-gegevens de juiste opmaakZet de datumstrings, tijdstempels en bedragen die API's versturen met de opmaakfuncties van
Intlom in leesbare tekst voor de taal, regio en tijdzone van de lezer. - Toon laad-, fout- en leegtestatussenHoud de fasen van een verzoek bij, toon de gebruiker voor elke fase een duidelijke melding en herstel van fouten met nieuwe pogingen.
- Annuleer verzoeken, stel tijdslimieten in en combineer verzoekenAnnuleer verzoeken die niet meer nodig zijn, stel tijdslimieten in, voorkom dat verouderde antwoorden nieuwere vervangen en voer meerdere verzoeken parallel of na elkaar uit.
- Render API-resultaten op de pagina
- Leg het beleid voor dezelfde oorsprong en CORS-fouten uit en bescherm API-sleutels en gebruikersgegevens wanneer een pagina met andere servers communiceert.
- Begrijp het beleid voor dezelfde oorsprong en CORSBepaal de oorsprong van een URL, leg uit waarom de browser sommige antwoorden van een andere oorsprong blokkeert en herken hoe CORS-headers en voorafgaande toestemmingsverzoeken een server in staat stellen die antwoorden toe te staan.
- Bescherm API-sleutels en gebruikersgegevensLeg uit wat API-sleutels en tokens doen, waarom een geheim in frontendcode openbaar is en hoe je inloggegevens verstuurt en verantwoord met gebruikersgegevens omgaat.
- Begrijp het beleid voor dezelfde oorsprong en CORS
- Sla kleine hoeveelheden gegevens op, lees ze uit en werk ze bij met localStorage en sessionStorage, en bepaal wat verstandig en veilig is om in de browser te bewaren.
- Sla gegevens op en lees ze uit met localStorage en sessionStorageGebruik de methoden van Web Storage, leg uit hoe lang elk soort opslag bewaard blijft en wie die kan lezen, en converteer getallen, booleaanse waarden en objecten naar opgeslagen strings en terug.
- Gebruik browseropslag in een appHerstel opgeslagen toestand wanneer een pagina wordt geladen, cache API-antwoorden met een vervaltijd, houd tabbladen gesynchroniseerd en bepaal wat je niet moet opslaan.
- Sla gegevens op en lees ze uit met localStorage en sessionStorage
- Detecteer en gebruik browser-API's die een veilige pagina of toestemming van de gebruiker nodig hebben, zoals geolocatie en het klembord, en geef gebruikers een terugvaloptie wanneer een functie niet beschikbaar is.
- Vraag de locatie van de gebruiker op met de Geolocation APIControleer of een browser-API beschikbaar is, leg veilige contexten en toestemmingsverzoeken uit en gebruik de Geolocation API met de opties, fouten en een terugvaloptie.
- Kopieer tekst en gebruik andere browser-API'sKopieer tekst met de klembord-API, reageer op wijzigingen in de verbinding, lees parameters uit het adres van de pagina en volg één methode om elke nieuwe browser-API te leren kennen.
- Vraag de locatie van de gebruiker op met de Geolocation API
Gegevens ophalen en browser-API's: uitleg
1Doe verzoeken en lees de antwoorden
Een pagina kan een server om gegevens vragen zonder een nieuwe pagina te laden. Het verzoek geeft aan welke resource je wilt en wat je ermee wilt doen; het antwoord vertelt wat er is gebeurd. Je volgt die uitwisseling in het tabblad Network, zet een JSON-antwoord om in JavaScript-gegevens en stuurt wijzigingen terug naar de server. De belangrijke controlepunten zijn de methode, de status en de structuur van de inhoud: het binnenkomen van een antwoord betekent op zichzelf niet dat de bewerking is geslaagd.
1.1 De onderdelen van een HTTP-uitwisseling
Met een web-API kan een programma gegevens lezen of wijzigen via aangeduide URL's die API-eindpunten heten. JavaScript op de pagina is de client. Die verstuurt een HTTP-verzoek; de server antwoordt met een HTTP-antwoord. Veel API's versturen JSON-tekst, die objecten, arrays, strings, getallen, booleaanse waarden en null kan weergeven.
Lees een verzoek
Bekijk GET https://api.example.com/books?author=Le%20Guin&limit=5. De methode is GET, het pad /books selecteert de resource en de querystring bevat twee parameters. De waarde van author is “Le Guin”; %20 codeert de spatie. Een ampersand scheidt de parameters. De API-documentatie legt uit welke parameternamen de API accepteert en wat elke waarde betekent.
Een verzoek kan ook headers bevatten, naam-waardeparen, en verzoekinhoud, met de ingediende gegevens. Accept: application/json vraagt om een JSON-antwoord. Content-Type: application/json beschrijft de inhoud die wordt verstuurd. Authorization bevat inloggegevens. Headernamen zijn niet hoofdlettergevoelig, dus content-type en Content-Type duiden dezelfde header aan.
Kies de handeling
| Methode | Bedoelde handeling | Gebruikelijk voorbeeld |
|---|---|---|
GET | Lezen | Een lijst met notities ophalen |
POST | Maken of indienen | Een notitie toevoegen |
PUT | Vervangen | De volledige vervangende notitie versturen |
PATCH | Een deel wijzigen | Eén notitie als voltooid markeren |
DELETE | Verwijderen | Een notitie verwijderen |
GET en HEAD zijn veilige methoden: ze zijn bedoeld om te lezen, dus gebruik GET niet voor een verwijderknop. GET, PUT en DELETE zijn idempotent. Als je hetzelfde verzoek herhaalt, blijft de server in dezelfde bedoelde toestand als na eenmaal uitvoeren. Het verwijderen van een al verwijderde notitie kan een andere status teruggeven, maar de notitie blijft afwezig. Het herhalen van een POST kan een tweede record maken.
Interpreteer het antwoord
Het antwoord bevat een statuscode, headers en meestal inhoud. Het eerste cijfer deelt de uitkomst in:
- 2xx: succes.
200 OKbevat meestal gegevens,201 Createdmeldt dat iets is aangemaakt en204 No Contentheeft geen inhoud. - 3xx: doorverwijzing. Standaard volgt
fetchdoorverwijzingen. - 4xx: een probleem met het verzoek of de toegang.
400betekent een ongeldig verzoek;401betekent ontbrekende of ongeldige inloggegevens;403betekent dat de server het verzoek begrijpt maar weigert;404betekent niet gevonden;429betekent te veel verzoeken. - 5xx: een serverprobleem, zoals
500 Internal Server Errorof503 Service Unavailable.
Een aanroep van /books/42 kan 200, een JSON-inhoudstype en {"id":42,"title":"The Dispossessed","year":1974} teruggeven. Een aanroep van /books/9999 kan 404 en {"error":"Book not found"} teruggeven. Beide aanroepen hebben een antwoord ontvangen. Bij een verbindingsfout is er geen HTTP-status die JavaScript kan onderzoeken.
Onderzoek voordat je gaat gissen
Open de ontwikkelaarstools, selecteer Network en activeer de handeling. Bekijk de methode, volledige URL, status, headers, inhoud en timing. Vergelijk die met het API-eindpunt, de vereiste parameters, inloggegevens, verzoeklimieten en het voorbeeldantwoord in de documentatie. Als de server de juiste gegevens teruggaf, onderzoek je de paginacode; als de verzoek-URL verkeerd is, herstel je die voordat je de renderfunctie wijzigt.
Belangrijkste punten
- Een API-eindpunt is een URL die een API beschikbaar stelt voor een bewerking.
- De methode kiest de handeling; de URL kiest de resource en parameters.
- Verzoek- en antwoordheaders beschrijven de uitwisseling.
- Een
404is een antwoord, terwijl een verbindingsfout geen HTTP-status heeft. - Bekijk het tabblad Network en vergelijk de uitwisseling met de API-documentatie.
1.2 Laad JSON in twee asynchrone stappen
fetch(url) verstuurt een GET-verzoek en geeft een promise terug. Het resultaat is een Response-object, dat beschikbaar is zodra de headers binnenkomen. De inhoud lezen is een aparte asynchrone bewerking. response.json() leest die inhoud en ontleedt die tot JavaScript-gegevens.
Wacht, controleer en lees
async function loadBook(id) {
const response = await fetch(`https://api.example.com/books/${id}`);
if (!response.ok) {
throw new Error(`HTTP error ${response.status}`);
}
return await response.json();
}
Bij loadBook(42) haalt de eerste await het antwoord op. De voorwaarde zorgt bij een niet-succesvolle HTTP-uitkomst voor een afwijzing. De tweede await haalt het ontlede boek op, zoals { id: 42, title: "The Dispossessed", year: 1974 }. De functie zelf geeft een promise terug, dus de aanroeper wacht ook op het resultaat.
response.ok is waar voor statuscodes van 200 tot en met 299. Een HTTP-fout zoals 404 of 500 wijst de fetch-promise niet af: een server heeft geantwoord. Een netwerkfout, een geblokkeerde CORS-uitwisseling, een ongeldige verzoek-URL of annulering kan de promise wel afwijzen. Door bij !response.ok een fout op te werpen, kan een omringende try/catch ook HTTP-fouten afhandelen.
Begrijp de inhoud
Zonder await slaat const data = response.json() een promise op, niet het boek. Als je dan data.title opvraagt, krijg je undefined. Als je await bij fetch weglaat, krijg je op dezelfde manier een promise waar de code een Response verwacht.
Kies de methode om de antwoordinhoud te lezen: json() voor JSON, text() voor tekst of blob() voor binaire gegevens. Inhoud kan maar eenmaal worden gelezen. Sla het ontlede resultaat op en gebruik het opnieuw. Om ook ruwe JSON-tekst te bekijken, lees je eenmaal text() en roep je daarna JSON.parse(text) aan op die opgeslagen string.
Ongeldige JSON leidt tot een afwijzing met een SyntaxError. Een HTML-foutpagina veroorzaakt vaak een melding “Unexpected token '<'”. Lege inhoud, ook bij een 204-antwoord, kan evenmin als JSON worden ontleed. Controleer eerst de status en bekijk response.headers.get("Content-Type") wanneer je twijfelt over het formaat. Een successtatus alleen garandeert geen JSON-inhoud.
Bouw veilig een query
const url = new URL("https://api.example.com/search");
url.searchParams.set("q", "rock & roll");
url.searchParams.set("limit", 10);
Het resulterende adres is https://api.example.com/search?q=rock+%26+roll&limit=10. De ampersand in de waarde wordt als onderdeel van de waarde gecodeerd. Als je invoer aan "?q=" vastplakt, kunnen &, # of + hun URL-betekenis krijgen en de zoekopdracht veranderen. Een relatieve URL volgt de normale adresbepaling: vanaf https://notes.example.org/app/index.html laadt fetch("data/books.json") het pad /app/data/books.json op die oorsprong.
Volg de teruggegeven structuur
Bij {"results":[{"title":"Dune"}],"total":1} is de eerste titel data.results[0].title. Het buitenste object is niet de resultatenarray. Gebruik de voorbeeldweergave van het antwoord om de array te vinden voordat je die met een lus doorloopt.
Een gedeelde hulpfunctie getJSON(url, options) kan voor veel aanroepen dezelfde statuscontrole en leesbewerking uitvoeren. Geef in een .then()-keten response.json() terug vanuit de callback voor het antwoord, zodat de volgende callback ontlede gegevens ontvangt. Voeg aan het einde .catch() toe om afgewezen stappen af te handelen.
Belangrijkste punten
fetchenresponse.json()geven afzonderlijke promises terug.- Controleer
response.ok; een HTTP-fout zorgt er niet voor datfetchwordt afgewezen. - Lees de inhoud van een antwoord eenmaal en gebruik de opgeslagen waarde opnieuw.
- Gebruik
URL.searchParamsom querywaarden te coderen. - Lees geneste JSON volgens de werkelijke structuur van objecten en arrays.
- Een succesvol antwoord kan nog steeds lege of ongeldige JSON-inhoud bevatten.
1.3 Verstuur een wijziging en gebruik het resultaat van de server
Het tweede argument van fetch configureert een verzoek. De opties omvatten method, headers, body, signal en credentials. Zonder deze opties is het verzoek een GET zonder inhoud. Om JSON in te dienen, moet je zowel de tekst als het inhoudstype voorbereiden.
Verstuur JSON
const response = await fetch("https://api.example.com/notes", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ title: "Shopping", text: "Rice, lentils" }),
});
JSON.stringify produceert {"title":"Shopping","text":"Rice, lentils"}. De header vertelt de server hoe die tekst moet worden gelezen. Als je het object rechtstreeks als inhoud doorgeeft, wordt "[object Object]" verstuurd. Als je de JSON-string zonder de header verstuurt, krijgt die het label text/plain;charset=UTF-8. Veel JSON-eindpunten wijzen die af met 400 of 415 Unsupported Media Type.
Als iets succesvol is aangemaakt, krijg je vaak 201 terug met het opgeslagen record, zoals {"id":17,"title":"Shopping","text":"Rice, lentils"}. Gebruik dit teruggegeven object om de pagina bij te werken: de nieuwe id van de server is nodig voor latere wijzigingen en verwijdering.
Vervang of werk bij
| Verzoek | Inhoud | Betekenis |
|---|---|---|
PATCH /notes/17 | {"done":true} | Het opgegeven veld wijzigen |
PUT /notes/17 | De volledige vervangende notitie | De resource vervangen |
DELETE /notes/17 | Vaak geen | De resource verwijderen |
Als een veld ontbreekt in de inhoud van een PUT, kan dat veld worden verwijderd of teruggezet, afhankelijk van de API. Gebruik de gedocumenteerde methode voor de bedoelde wijziging. PUT en PATCH kunnen een bijgewerkt record met 200 teruggeven, of 204 zonder inhoud.
Handel succes af zonder aan te nemen dat er altijd JSON volgt:
if (!response.ok) {
throw new Error(`HTTP error ${response.status}`);
}
const saved = response.status === 204
? null
: await response.json();
Dit patroon past bij API-eindpunten die volgens de documentatie JSON of 204 teruggeven. Een verwijdering kan slagen en toch een ontleedfout opleveren als code zonder controle json() aanroept op de lege inhoud.
Kies het formaat van de inhoud
new FormData(formElement) verzamelt formuliervelden met een naam en geselecteerde bestanden. Geef dit rechtstreeks door als body. Laat de browser Content-Type: multipart/form-data en het bijbehorende scheidingsteken instellen; een handmatig opgegeven header kan het scheidingsteken missen dat nodig is om de velden te scheiden. Inhoud van het type URLSearchParams gebruikt application/x-www-form-urlencoded.
Verzoeken met GET en HEAD kunnen via fetch geen inhoud bevatten. Plaats zoektermen en filters in de querystring van de URL. Een poging om een GET met inhoud te versturen, wordt afgewezen met een TypeError voordat die als zoekverzoek kan dienen.
Rond veilig af na succes of een fout
Schakel de verzendknop uit voordat je op een verzoek om iets aan te maken wacht en schakel die daarna weer in met finally. Een dubbele klik kan anders twee POST-verzoeken versturen en twee records maken. Herhaal een aanmaakbewerking waarvan de uitkomst onzeker is niet automatisch: een verloren antwoord maakt niet duidelijk of de server de wijziging heeft uitgevoerd.
Bij een foutstatus kan de inhoud een nuttige melding bevatten zoals {"error":"title is required"}. Lees die eenmaal als de inhoud JSON is; vang een mislukte ontleding af en behoud een algemene HTTP-melding voor lege antwoorden of HTML-antwoorden. Houd de door de gebruiker ingevoerde tekst beschikbaar, zodat die het verzoek kan corrigeren.
Belangrijkste punten
- JSON-verzoeken hebben
JSON.stringifyen een bijpassend inhoudstype nodig. - Gebruik
PATCHvoor een gedeeltelijke wijziging enPUTvoor een volledige vervanging. - Sla het ontleden van JSON over bij
204 No Content. - Laat de browser de header voor meerdelige inhoud instellen wanneer je
FormDataverstuurt. - Gebruik het antwoord van de server, inclusief de toegekende ID, om de pagina bij te werken.
- Voorkom dubbele verzendingen en herstel bedieningselementen in
finally.
2Zet antwoorden om in een bruikbare pagina
Gegevens ophalen is maar het eerste deel van een interface. Lezers hebben bruikbare resultaten, leesbare datums en prijzen en een duidelijke melding tijdens het wachten nodig. Je bouwt de weergave op vanuit de structuur van het antwoord, voorkomt dat ontbrekende waarden die verstoren en maakt succes, lege resultaten en fouten zichtbaar. Je houdt ook overlappende verzoeken onder controle zodat een langzaam antwoord geen nieuwere resultaten kan vervangen, en kiest wanneer onafhankelijke verzoeken tegelijk kunnen worden uitgevoerd.
2.1 Bouw de weergave op uit gegevens
Renderen zet een array of object om in elementen op de pagina. Bewaar de opgehaalde gegevens in een variabele en geef ze aan een renderfunctie. Door die scheiding kun je dezelfde gegevens sorteren of filteren zonder ze opnieuw bij de server op te vragen.
Maak één element per item
function renderBooks(books, list) {
list.replaceChildren();
for (const book of books) {
const item = document.createElement("li");
item.textContent = `${book.title} (${book.year})`;
list.append(item);
}
}
Bij [{"title":"Kindred","year":1979},{"title":"Beloved","year":1987}] maakt dit twee lijstitems: “Kindred (1979)” en “Beloved (1987)”. Door de container eerst leeg te maken, vervangt een nieuwe zoekopdracht de vorige. Zonder die stap worden de oude en nieuwe lijsten bij elkaar opgeteld.
Houd externe tekst als tekst
Gebruik textContent voor titels, beschrijvingen en andere tekst uit een API. innerHTML ontleedt een string als opmaak. Een titel met <img src="x" onerror="alert(1)"> kan dan code uitvoeren. Dit heet cross-site scripting, of XSS. Tekst uit formulieren en opslag heeft dezelfde behandeling nodig, omdat die ook van een niet-vertrouwde bron kan komen.
Met elementeigenschappen stel je afzonderlijke waarden in, zoals img.alt = book.title. Daarmee wordt niet elk soort waarde automatisch veilig. Een link uit een API moet nog steeds op het protocol worden gecontroleerd:
try {
const target = new URL(book.url, location.href);
if (target.protocol === "https:" || target.protocol === "http:") {
link.href = target.href;
}
} catch {
link.removeAttribute("href");
}
Deze code werkt op een nieuw gemaakte link zonder bestaande href. Bij een ongeldige of niet-toegestane URL blijft de link zonder bestemming. Een javascript:-URL is geen gewone webnavigatie. Geef afbeeldingen waar mogelijk een betekenisvolle alt-tekst die uit de gegevens is opgebouwd.
Geef standaardwaarden zonder echte waarden te verliezen
Optionele velden kunnen ontbreken of null zijn. book.author?.name ?? "Unknown author" probeert eerst de geneste naam en geeft daarna een standaardwaarde. Optionele ketenvorming voorkomt dat een eigenschap van een ontbrekende auteur wordt opgevraagd.
De operator maakt verschil: 0 || "n/a" geeft "n/a", terwijl 0 ?? "n/a" de waarde 0 behoudt. De operator || vervangt alle falsy-waarden, inclusief nul en een lege string; ?? vervangt alleen null en undefined. Bij een boek waarvan nul exemplaren beschikbaar zijn, moet nul worden weergegeven.
Een lege resultatenarray is een geslaagde zoekopdracht zonder treffers. Toon “Geen boeken gevonden voor je zoekopdracht.” zodat lezers dit kunnen onderscheiden van een pagina die nog niet is geladen.
Vervang een zoekopdracht, voeg een volgende pagina toe
Veel API's geven pagina's terug met page, limit, een totaalaantal total of een next-URL. Bij 47 resultaten en 10 per pagina bevatten vier volle pagina's 40 records en bevat de vijfde er 7. Een nieuwe zoekopdracht wist de vorige lijst; “Meer laden” voegt de volgende pagina toe aan de huidige lijst. Houd die twee weergavehandelingen gescheiden.
Om een lokale kopie te sorteren met de nieuwste boeken eerst, gebruik je [...books].sort((a, b) => b.year - a.year) en render je die kopie. De spreadsyntaxis maakt een nieuwe array, zodat de opgeslagen volgorde van het antwoord beschikbaar blijft. Bekijk de structuur van het antwoord voordat je de array selecteert: een API met paginering plaatst die vaak in data.results.
Belangrijkste punten
- Render vanuit opgeslagen gegevens zodat lokaal sorteren geen nieuw verzoek vereist.
- Voeg niet-vertrouwde tekst in met
textContent. - Valideer het protocol van een API-link voordat je de bestemming toewijst.
- Gebruik
?.voor ontbrekende geneste gegevens en??wanneer nul nul moet blijven. - Vervang resultaten bij een nieuwe zoekopdracht; voeg resultaten van een volgende pagina toe.
2.2 Geef datums en bedragen een leesbare opmaak
API's geven waarden terug die programma's eenvoudig kunnen uitwisselen. Lezers hebben datums, tijden en bedragen nodig die zijn opgemaakt voor hun taal en regio. Houd de opgeslagen waarde gescheiden van de tekst die voor de weergave wordt gebruikt.
Lees eerst het datumformaat
"2026-03-05T14:30:00Z" duidt één moment aan: 14.30 uur UTC op 5 maart 2026. De Z betekent UTC. new Date(...) zet dit om in een JavaScript-Date. Een string met alleen een datum, zoals "2026-03-05", wordt geïnterpreteerd als middernacht UTC; een datum en tijd zonder offset, zoals "2026-03-05T14:30", wordt geïnterpreteerd als lokale tijd.
Een Unix-tijdstempel telt vanaf 1 januari 1970, UTC. API's tellen vaak seconden, maar Date gebruikt milliseconden. new Date(1772721000 * 1000) geeft hetzelfde moment op 5 maart. Als je de vermenigvuldiging weglaat, krijg je een datum in januari 1970. Lees de API-documentatie om de eenheid te bepalen.
Kies een landinstelling en tijdzone
const date = new Date("2026-03-05T14:30:00Z");
const dateFormat = new Intl.DateTimeFormat("en-US", {
dateStyle: "medium",
timeStyle: "short",
timeZone: "UTC",
});
dateFormat.format(date);
De uitvoer is “Mar 5, 2026, 2:30 PM”. Met en-GB is dat “5 Mar 2026, 14:30”. Korte datums geven “3/5/26” in en-US, “05/03/2026” in en-GB en “05.03.26” in de-DE.
De landinstelling bepaalt de presentatie; de tijdzone bepaalt de lokale tijd. Zonder timeZone gebruikt de opmaakfunctie de tijdzone van het apparaat. Dat moment is 09.30 uur in New York, 15.30 uur in Amsterdam en 23.30 uur in Tokio. Bewaar en verstuur momenten in UTC en converteer ze voor de weergave. Een kalenderdatum zoals een verjaardag vraagt aandacht: als je middernacht UTC opmaakt in een tijdzone ten westen van UTC, kan de vorige dag worden getoond.
Houd valuta en landinstelling gescheiden
const priceFormat = new Intl.NumberFormat("en-US", {
style: "currency",
currency: "EUR",
});
priceFormat.format(1234.5);
Dit geeft €1,234.50. Voor hetzelfde bedrag geeft de-DE met EUR 1.234,50 €; en-US met USD geeft $1,234.50; en-US met JPY geeft ¥1,235. JPY heeft geen kleinere munteenheid, dus de normale weergave heeft geen decimalen. Een landinstelling selecteren rekent geen valuta's om. Gebruik de valutacode die bij het bedrag wordt geleverd.
Sommige betaal-API's versturen gehele getallen in de onderverdeling van de munteenheid. Bij USD betekent 1999 cent 19.99 Amerikaanse dollar: deel door 100 voordat je het bedrag opmaakt. Pas die deling niet toe op JPY. Het optellen van gehele aantallen centen geeft 1999 + 2550 = 4549, wat wordt opgemaakt als $45.49. Dit voorkomt het bekende resultaat van decimale rekenkunde 0.1 + 0.2, dat gelijk is aan 0.30000000000000004.
Gebruik de opmaakfunctie opnieuw
Maak voor een lijst eenmaal een opmaakfunctie. Gebruik undefined als landinstelling om de standaardinstelling van de browser te kiezen; navigator.language vermeldt de voorkeurstaalcode van de browser. Andere opties maken 0.256 op als “26%”, of 12.5 met de eenheid "kilometer-per-hour" als “12.5 km/h”. new Intl.RelativeTimeFormat("en", { numeric: "auto" }).format(-1, "day") geeft “yesterday”. Met de hand opgebouwde datums zoals “03/05/2026” blijven per regio dubbelzinnig.
Belangrijkste punten
- Controleer of tijdstempels seconden of milliseconden gebruiken.
- Een expliciete tijdzone maakt de weergave van datum en tijd voorspelbaar.
- De landinstelling bepaalt de opmaak; de valuta komt uit de gegevens.
- Converteer de gedocumenteerde onderverdeling van een munteenheid voordat je geldbedragen opmaakt.
- Gebruik
Intl-opmaakobjecten opnieuw voor een hele lijst. - Strings met alleen een datum worden als UTC ontleed en kunnen bij weergave in een andere tijdzone een dag verschuiven.
2.3 Toon wat het verzoek doet
Een verzoek heeft een zichtbare levenscyclus: inactief, laden en daarna succes of fout. Succes kan gegevens of een leeg resultaat bevatten. De pagina moet elke toestand uitleggen, zodat lezers weten of ze moeten wachten, een zoekopdracht moeten aanpassen of het opnieuw moeten proberen.
Houd voorbereiding en opruiming bij elkaar
In deze handler controleert getJSON de HTTP-status en ontleedt die de inhoud, bouwt searchUrl de verzoek-URL en werkt renderResults de lijst bij. De knop en het statuselement bestaan al op de pagina.
async function search(query) {
button.disabled = true;
status.textContent = "Loading…";
try {
const data = await getJSON(searchUrl(query));
renderResults(data.results);
status.textContent = data.results.length === 0 ? "No results." : "";
} catch (error) {
status.textContent = "Could not load results. Check your connection and try again.";
console.error(error);
} finally {
button.disabled = false;
}
}
De voorbereiding gebeurt voordat er wordt gewacht. Het pad voor succes rendert de resultaten en handelt een lege array af. De catch vervangt de laadmelding als een stap waarop wordt gewacht mislukt. finally herstelt de knop na beide paden. Als het opruimen alleen na een succesvolle await zou staan, zou een fout het bedieningselement uitgeschakeld laten.
Leg de relevante oorzaak uit
Een HTTP-fout heeft een status die richting geeft aan de melding. Zeg bij 404 dat het item niet is gevonden. Vraag de gebruiker bij 401 om in te loggen; leg bij 403 uit dat toegang niet is toegestaan. Vraag de gebruiker bij 429 om te wachten. Leg bij 5xx uit dat de dienst een probleem heeft en stel voor het later opnieuw te proberen.
Een TypeError van fetch kan duiden op een netwerkfout, een geblokkeerd CORS-verzoek of een ongeldige URL. JavaScript krijgt geen betrouwbare gedetailleerde diagnose van CORS; bekijk de browserconsole en het tabblad Network. Een SyntaxError van json() wijst op ongeldige JSON. Annulering en tijdslimieten leveren fouten op zoals AbortError en TimeoutError. Bewaar technische details in de console en geef lezers een handeling die ze begrijpen.
Maak wijzigingen merkbaar
Gebruik een bestaand statuselement zoals <p role="status"></p>. Wijzigingen daarin worden aangekondigd aan schermlezers zonder de focus te verplaatsen. aria-live="polite" dient een vergelijkbaar doel; role="alert" is geschikt voor dringende fouten. Een laadindicator alleen communiceert geen leeg resultaat of mislukt verzoek.
Een knop Opnieuw proberen roept de laadfunctie opnieuw aan. Ongewijzigde verzoeken die 400 of 404 opleverden, opnieuw proberen herhaalt meestal het probleem. Tijdelijke netwerk- of dienststoringen kunnen een korte, begrensde reeks nieuwe pogingen rechtvaardigen. Een exponentieel oplopende wachttijd vergroot de pauze, bijvoorbeeld 1 seconde, 2 seconden en dan 4 seconden. Respecteer een antwoordheader Retry-After; die kan een vertraging in seconden of een HTTP-datum geven. Probeer een aanmaakverzoek dat mogelijk al is geslaagd niet automatisch opnieuw.
Als verversen mislukt maar eerdere gegevens nog bruikbaar zijn, houd die dan zichtbaar met een melding zoals “Resultaten van 10.42 uur worden getoond. Verversen is niet gelukt.” Laat oude resultaten niet zonder toelichting actueel lijken.
Test de moeilijke situaties
Gebruik de ontwikkelaarstools om de verbinding te vertragen, offline te gaan en een ontbrekend pad op te vragen. Controleer of de laadmelding direct verschijnt, een mislukt verzoek die vervangt, een leeg succesvol resultaat een eigen melding heeft en bedieningselementen weer bruikbaar worden.
Belangrijkste punten
- Maak laden, leeg succes, succes met gegevens en fouten zichtbaar.
- Plaats gezamenlijke opruiming in
finally. - Geef lezers een bruikbare handeling en houd technische details in de console.
- Kondig statuswijzigingen aan via een geschikt livegebied.
- Beperk het aantal nieuwe pogingen en respecteer de door de server gevraagde wachttijd.
2.4 Houd overlappende en parallelle verzoeken onder controle
Verzoeken kunnen langer duren dan de handeling waardoor ze zijn gestart. Een zoekantwoord kan binnenkomen nadat de lezer iets anders heeft getypt en een trage dienst kan een pagina te lang laten wachten. Bepaal welke resultaten nog relevant zijn en of elk verzoek is geslaagd.
Annuleer werk dat je niet meer nodig hebt
Maak een AbortController, geef de bijbehorende signal door aan fetch en roep daarna abort() aan om het verzoek te annuleren. Annulering kan zowel het wachten op headers als het lezen van de inhoud onderbreken. De afwijzing heet normaal gesproken "AbortError".
const controller = new AbortController();
const response = await fetch(url, { signal: controller.signal });
// A cancel button can call controller.abort().
const data = await response.json();
Handel fouten rond beide wachtbewerkingen af. Als je code een verouderde zoekopdracht bewust annuleert, keer je bij die verwachte annulering terug zonder de gebruiker te melden dat de dienst is mislukt.
fetch heeft geen ingebouwde optie timeout. Gebruik een signaal zoals AbortSignal.timeout(5000) om het verzoek te beperken tot 5000 ms, of 5 seconden actieve tijd. Voordat de headers binnenkomen, leidt dit tot een afwijzing met TimeoutError; nadat de headers zijn binnengekomen, kan het lezen van de inhoud worden onderbroken.
Voorkom dat oude zoekopdrachten winnen
Een raceconditie ontstaat wanneer de volgorde van voltooiing het resultaat verandert. Een lezer typt “ka” en daarna “kat”. Als “ka” als laatste terugkomt en wordt gerenderd, komt het scherm niet meer overeen met de invoer.
Een aanpak annuleert het vorige verzoek vóór elk nieuw verzoek. Een andere geeft elke aanroep een nummer en laat alleen de nieuwste aanroep de pagina bijwerken:
let latest = 0;
async function search(query) {
const request = ++latest;
try {
const data = await getJSON(searchUrl(query));
if (request !== latest) return;
renderResults(data.results);
} catch (error) {
if (request !== latest) return;
showError(error);
}
}
De controle voorkomt ook dat een oude fout een nieuwer succes vervangt. Pas dezelfde relevantiecontrole toe op laadmeldingen en het herstellen van bedieningselementen wanneer aanroepen overlappen.
Uitstellen tot na een rustperiode vermindert het aantal aanroepen dat start. Wis bij elke toetsaanslag de vorige timer en start een nieuwe, bijvoorbeeld voor 300 ms. Als je snel “parijs” typt, start na de pauze één verzoek. Dit bespaart verzoeken, maar voorkomt op zichzelf niet dat een eerder antwoord dat nog onderweg is laat binnenkomt.
Bepaal wat samen kan worden uitgevoerd
Onafhankelijke verzoeken kunnen samen starten:
const [user, posts] = await Promise.all([
getJSON(userUrl),
getJSON(postsUrl),
]);
Bij duur van 300 ms en 500 ms duren beide samen ongeveer 500 ms in plaats van ongeveer 800 ms na elkaar. Promise.all wordt afgewezen zodra één invoer wordt afgewezen, maar annuleert de andere bewerkingen niet.
Gebruik Promise.allSettled wanneer gedeeltelijke resultaten nuttig zijn. Dit wacht op elke invoer en rapporteert die als { status: "fulfilled", value } of { status: "rejected", reason }. Een dashboard kan dan geslaagde panelen naast een mislukt paneel tonen.
Afhankelijke verzoeken moeten na elkaar worden uitgevoerd. Als een tweede URL een ID nodig heeft die het eerste verzoek teruggeeft, wacht je op die ID voordat je het tweede verzoek opbouwt.
Belangrijkste punten
- Geef een annuleringssignaal door voordat je
abort()aanroept. - Vang fouten af bij zowel het ophalen als het lezen van de inhoud.
- Negeer verouderde resultaten en verouderde fouten.
- Uitstellen tot na een rustperiode vermindert aanroepen; een relevantiecontrole voorkomt verouderde updates.
- Gebruik
Promise.allvoor onafhankelijk werk dat samen moet slagen. - Gebruik
Promise.allSettledwanneer gedeeltelijke resultaten nuttig zijn. - Wacht op vereiste gegevens voordat je een afhankelijk verzoek start.
3Lees gegevens van andere oorsprongen en bescherm inloggegevens
Een verzoek kan er correct uitzien en toch mislukken in een browser doordat de pagina en de API bij verschillende oorsprongen horen. Die grens wordt gezamenlijk bepaald door browserregels en de antwoordheaders van de server. Je bepaalt de oorsprong, interpreteert voorafgaande toestemmingsverzoeken en CORS-fouten en onderscheidt toestemming om een antwoord te lezen van toestemming om een handeling uit te voeren. Voor inloggegevens is een afzonderlijke beslissing nodig: alles wat aan een browser wordt geleverd, kan door de gebruiker ervan worden bekeken.
3.1 Begrijp de oorsprongsgrens van de browser
Een oorsprong combineert het schema, de host en de poort van een URL. Een pad maakt er geen deel van uit. https://shop.example.com/cart en /help op dezelfde site delen een oorsprong. Als je dit wijzigt naar http://shop.example.com, https://api.example.com of https://shop.example.com:8443, verandert de oorsprong. HTTPS gebruikt normaal poort 443.
Wie staat toe dat het antwoord wordt gelezen?
Het beleid voor dezelfde oorsprong beperkt welke resources een paginascript mag lezen. Bij een fetch-verzoek naar een andere oorsprong laat CORS de API-server via antwoordheaders toegang verlenen. Een pagina op https://notes.example.org die https://api.example.com/weather aanroept, heeft toestemming van de API nodig om het antwoord te lezen.
Access-Control-Allow-Origin: https://notes.example.org verleent die oorsprong toegang. De waarde * staat elke oorsprong toe voor een verzoek zonder inloggegevens. Als het antwoord geen passende toestemming bevat, verbergt de browser het voor de pagina en wordt fetch afgewezen met een TypeError. De console geeft de CORS-diagnose; JavaScript ontvangt de gedetailleerde reden niet.
Als je Access-Control-Allow-Origin toevoegt aan het JavaScript-verzoek, verleent dat geen toestemming. Het is een antwoordheader die door de server wordt bepaald. Een eigen verzoekheader toevoegen kan in plaats daarvan een extra voorafgaande controle veroorzaken.
Waarom OPTIONS vóór POST verschijnt
Sommige verzoeken naar een andere oorsprong hebben een voorafgaand toestemmingsverzoek nodig. De browser verstuurt eerst OPTIONS, met de beoogde methode in Access-Control-Request-Method en niet-standaard toegestane headernamen in Access-Control-Request-Headers. De server staat die toe met Access-Control-Allow-Methods en Access-Control-Allow-Headers, samen met de toestemming voor de oorsprong.
Een eenvoudige GET, HEAD of POST met alleen toegestane headers kan zonder voorafgaand toestemmingsverzoek. De toegestane inhoudstypen omvatten text/plain, application/x-www-form-urlencoded en multipart/form-data. Een JSON-POST, een Authorization-header, PUT of DELETE vereist een voorafgaand toestemmingsverzoek, tenzij een geldige eerdere toestemming is gecachet. Als het voorafgaande verzoek wordt geweigerd, wordt het eigenlijke verzoek niet verstuurd.
Bij een eenvoudig verzoek kan het eigenlijke verzoek de server bereiken, ook als de browser later het lezen van het antwoord blokkeert. CORS vervangt daarom geen autorisatie of invoercontrole op de server.
Cookies stellen een extra eis
De standaardinstelling credentials: "same-origin" verstuurt cookies alleen voor verzoeken met dezelfde oorsprong. credentials: "include" staat toe dat daarvoor in aanmerking komende cookies ook met verzoeken naar andere oorsprongen meegaan. Cookiebeperkingen van SameSite en beleid voor cookies van derden blijven gelden.
Om JavaScript een antwoord op een verzoek met inloggegevens te laten lezen, moet de server Access-Control-Allow-Credentials: true versturen en de oorsprong van de pagina expliciet noemen. Access-Control-Allow-Origin: * werkt niet met inloggegevens. Deze headers dwingen een browser niet om een cookie te versturen die anders zou worden geblokkeerd.
Onderzoek zonder het probleem te verbergen
mode: "no-cors" geeft een ondoorzichtig antwoord met status 0 en zonder leesbare inhoud of headers. Het kan geen JSON aan een pagina leveren. Een verzoek dat werkt in curl bewijst evenmin dat de browser CORS-toestemming heeft: terminalclients handhaven dat browserbeleid niet.
Bekijk de console en het tabblad Network. Controleer of het voorafgaande toestemmingsverzoek is mislukt of dat het uiteindelijke antwoord geen toestemming bevatte. Herstel de antwoordconfiguratie van de API of laat de aanroep via je eigen server lopen. Stel pagina's tijdens de ontwikkeling beschikbaar via een lokale server: pagina's met file:// hebben vaak een ondoorzichtige oorsprong. Een lokale server heeft nog steeds CORS-toestemming nodig wanneer die een andere oorsprong aanroept.
Belangrijkste punten
- Een oorsprong bestaat uit schema, host en poort.
- De antwoordheaders van de server verlenen toestemming om vanaf een andere oorsprong te lezen.
- Een voorafgaand toestemmingsverzoek controleert een voorgestelde methode en headers vóór het eigenlijke verzoek.
- CORS kan een antwoord verbergen nadat een eenvoudig verzoek al is verwerkt.
- Antwoorden op verzoeken met inloggegevens vereisen een expliciete oorsprong en een header voor inloggegevens.
no-corslevert een ondoorzichtig antwoord op, geen leesbare JSON.
3.2 Houd geheime sleutels buiten de pagina
Een API-sleutel identificeert een aanroepende toepassing voor gebruik, limieten en facturering. Een toegangstoken verleent toegang voor een gebruiker of sessie. Iedereen die bruikbare inloggegevens bezit, kan mogelijk met de bijbehorende rechten handelen. Bepaal dus waar ze thuishoren voordat je ze aan een verzoek toevoegt.
Headers beschermen de plaats, niet de geheimhouding voor de gebruiker
Aanbieders kunnen Authorization: Bearer <token>, X-API-Key: <key> of een queryparameter zoals api_key vereisen. Volg de API-documentatie. Een header voorkomt dat de inloggegevens in een volledige URL terechtkomen die in logboeken en analyses kan belanden. Een Authorization-header of eigen header bij een aanroep naar een andere oorsprong leidt normaal tot een voorafgaand toestemmingsverzoek.
Een header is nog steeds zichtbaar in de ontwikkelaarstools. Bezoekers kunnen de JavaScript die ze downloaden en de verzoeken die deze verstuurt bekijken. Code minificeren of een waarde achter een variabele verbergen maakt die niet geheim.
Volg de sleutel in een weerverzoek
Stel dat browsercode https://api.weather.example/v1/current?city=Lima&key=sk_live_4f9a2c aanroept. Iedereen die Network opent, kan de sleutel kopiëren en het quotum van het account gebruiken. Die waarde verplaatsen naar een omgevingsvariabele tijdens het bouwen helpt niet als de build die invoegt in de JavaScript die aan de pagina wordt geleverd.
Een geheim op de server verandert de route:
- De pagina roept de eigen site aan op
/api/weather?city=Lima. - De server van die site voegt het geheim toe en neemt contact op met de weeraanbieder.
- De server geeft de weergegevens terug aan de pagina en houdt het geheim buiten het antwoord.
De server moet de toegang tot en het gebruik van het eigen API-eindpunt nog steeds beheersen. Het geheim voor de achterliggende dienst op een server bewaren maakt onbeperkt openbaar gebruik niet onschadelijk.
Sommige aanbieders geven browsersleutels uit die openbaar mogen zijn. Pas de domeinbeperkingen van de aanbieder toe, beperk toegestane API's en stel gebruiksquota in. Gebruik een sleutel alleen zo wanneer het gedocumenteerde ontwerp dat toestaat; een geheime serversleutel wordt geen browsersleutel door een domeinbeperking toe te voegen.
Reageer op openbaarmaking
Houd bestanden met inloggegevens buiten versiebeheer, bijvoorbeeld door .env in .gitignore op te nemen. Dit voorkomt dat het bestand wordt gecommit; het voorkomt niet dat een frontendbuild een waarde publiceert die de code insluit. Als een sleutel is uitgelekt, trek je die in en geef je een vervangende sleutel uit. Als je die uit de nieuwste commit verwijdert, blijven eerdere geschiedenis en eventuele kopieën intact.
Bescherm de uitwisseling en beperk verspilling
Gebruik HTTPS voor API-aanroepen zodat gegevens en inloggegevens onderweg zijn versleuteld. Een fetch van een HTTPS-pagina naar een HTTP-API wordt geblokkeerd als gemengde inhoud. Versleuteling voorkomt niet dat de persoon die de browser gebruikt het eigen verzoek ziet.
Een verzoeklimiet begrenst het gebruik, bijvoorbeeld tot 60 verzoeken per minuut. Aanroepen boven de limiet kunnen 429 Too Many Requests teruggeven. Cache geschikte resultaten, stel zoekinvoer uit tot na een rustperiode en voorkom dubbele aanroepen. Als de server Retry-After levert, respecteer je de wachttijd in plaats van steeds direct opnieuw te proberen.
Validatie aan de clientkant maakt formulieren gemakkelijker te gebruiken, maar iedereen kan een API-eindpunt aanroepen zonder je formulier. De server moet verzoeken zelf valideren en handelingen zelf autoriseren. Blijf strings bij het tonen van het antwoord als niet-vertrouwde tekst behandelen en voeg ze in met textContent.
Belangrijkste punten
- Code en verzoeken die aan de browser worden geleverd, maken de inloggegevens die ze bevatten zichtbaar.
- Een geheime sleutel hoort op de server die de aanbieder aanroept.
- Beperk openbare browsersleutels op domein, API en quotum.
- Trek een uitgelekte sleutel in; die alleen uit de huidige code verwijderen is onvoldoende.
- HTTPS versleutelt gegevens onderweg, terwijl de server verzoeken nog steeds valideert en autoriseert.
4Bewaar kleine hoeveelheden toestand in de browser
Een instelling of concept kan na het opnieuw laden bewaard blijven zonder een nieuw serververzoek. Browseropslag maakt dit gemakkelijk, maar de waarden zijn strings en de levensduur hangt af van de gekozen opslag. Je slaat kleine delen van de toestand op en herstelt ze, valideert oude gegevens voordat je ze gebruikt en geeft gecachte API-resultaten een vervaltijd. Je bepaalt ook welke gegevens elders thuishoren, omdat lokale opslag geen geheime kluis is en ook niet de enige veilige kopie van belangrijk werk.
4.1 Sla strings op en herstel hun typen
Web Storage biedt twee opslagplaatsen voor sleutel-waardeparen: localStorage en sessionStorage. Ze gebruiken dezelfde methoden, dus de belangrijkste keuze is hoe lang de gegevens moeten blijven bestaan en welke tabbladen ze moeten delen.
Kies de levensduur
| Opslag | Levensduur | Delen |
|---|---|---|
localStorage | Blijft na het sluiten van tabblad en browser bewaard totdat de gegevens worden verwijderd of gewist | Gedeeld door pagina's van dezelfde oorsprong |
sessionStorage | Blijft bewaard bij opnieuw laden tijdens de paginasessie van het tabblad | Apart voor elk tabblad en elke oorsprong |
Als je het tabblad sluit, eindigt de sessieopslag ervan. Een nieuw geopende pagina met een opener kan beginnen met een kopie van de sessieopslag van de opener, maar latere wijzigingen blijven gescheiden. Gebruik sessieopslag niet om informatie geheim te houden voor scripts.
Opslag volgt oorsprongen. https://app.example.com kan de opslag niet delen met http://app.example.com. Paden op dezelfde oorsprong delen die wel, dus een voorvoegsel zoals "notes-app:settings" helpt om de sleutels van meerdere apps te onderscheiden.
Gebruik de opslagmethoden
localStorage.setItem("notes-app:theme", "dark");
const theme = localStorage.getItem("notes-app:theme");
localStorage.removeItem("notes-app:theme");
setItem maakt een item of overschrijft het. getItem geeft de stringwaarde terug of null als het item ontbreekt. removeItem verwijdert één item. clear() verwijdert alle items uit dat opslaggebied voor de oorsprong, wat andere functies op dezelfde site kan beïnvloeden. Met length en key(index) kun je de sleutels bekijken.
Gebruik deze methoden in plaats van eigenschapstoewijzingen zoals localStorage.theme = "dark". Sleutels zoals "length" of "key" kunnen botsen met ingebouwde leden wanneer je ze als eigenschappen benadert.
Converteer waarden bewust
Na localStorage.setItem("count", 5) geeft uitlezen "5". Als je daar rechtstreeks 1 bij optelt, ontstaat "51". Number(localStorage.getItem("count")) + 1 levert 6 op.
Een opgeslagen booleaanse waarde heeft een vergelijkbare valkuil. setItem("darkMode", false) slaat "false" op en een niet-lege string is truthy. Lees de waarde met localStorage.getItem("darkMode") === "true" wanneer dat de twee verwachte opgeslagen strings zijn.
Objecten en arrays hebben JSON nodig:
localStorage.setItem("settings", JSON.stringify({
theme: "dark",
fontSize: 18,
}));
const settings = JSON.parse(localStorage.getItem("settings"))
?? { theme: "light", fontSize: 16 };
Zonder serialisatie wordt een gewoon object "[object Object]". JSON.parse(null) geeft null, dus de standaardwaarde vangt een ontbrekend item op. Een onjuist gevormde opgeslagen string vereist nog steeds try/catch en ontlede gegevens hebben vóór gebruik een structuurcontrole nodig.
Houd de belasting klein
Aanroepen van Web Storage zijn synchroon: JavaScript wacht op elke aanroep op de hoofdthread. Gebruik de opslag voor instellingen, een concept of een korte lijst, niet voor grote collecties of bestanden. IndexedDB biedt asynchrone opslag voor grotere hoeveelheden gestructureerde gegevens.
Actuele browsers staan gewoonlijk ongeveer 5 MiB per Web Storage-gebied per oorsprong toe. Een volle opslag kan ertoe leiden dat setItem een QuotaExceededError opwerpt; toegang kan ook mislukken door privacyinstellingen van de browser. Handel fouten af zonder de rest van de app te blokkeren. Ontwikkelaarstools tonen de opslagplaatsen in het tabblad Application van Chrome en Edge of het tabblad Storage van Firefox. Daar helpt het verwijderen van items om eerste bezoeken te testen.
Belangrijkste punten
- Kies
localStoragevoor blijvende gedeelde instellingen ensessionStoragevoor toestand tijdens een tabbladsessie. - Opslaggebieden zijn per oorsprong gescheiden.
getItemgeeft een string ofnullterug.- Serialiseer objecten met JSON en herstel hun typen bij het uitlezen.
- Handel opslagfouten af en houd synchrone schrijfbewerkingen klein.
4.2 Herstel toestand en laat gecachte gegevens vervallen
Een app laadt meestal bij het starten en slaat op bij een wijziging. Lees een opgeslagen lijst wanneer de pagina wordt geopend, render die en sla de bijgewerkte lijst op na een bewerking. Browseropslag is een handige kopie: die kan ontbreken, beschadigd of verouderd zijn of worden gewist.
Valideer voordat je herstelt
Deze laadfunctie verwacht een opgeslagen array met strings:
function loadTodos() {
try {
const value = JSON.parse(localStorage.getItem("todos"));
if (Array.isArray(value) && value.every(item => typeof item === "string")) {
return value;
}
} catch {
// Continue with an empty list if reading or parsing fails.
}
return [];
}
JSON.parse alleen bewijst niet dat de waarde een array is of dat de items bij de app passen. Geldige JSON zoals 42 heeft nog steeds de verkeerde structuur. Een waarde met een versienummer zoals { version: 2, todos: [...] } laat nieuwere code oudere formaten herkennen en die converteren of een standaardwaarde herstellen.
Sla de lijst in het geheugen na elke wijziging op met localStorage.setItem("todos", JSON.stringify(todos)). Vang ook schrijffouten af; een pagina moet kunnen blijven werken, zelfs wanneer die de toestand voor de volgende keer laden niet kan bewaren. Een formulierconcept dat alleen bij één bezoek hoort, kan sessionStorage gebruiken.
Geef gecachte antwoorden een tijdstempel
localStorage.setItem("weather", JSON.stringify({
savedAt: Date.now(),
data,
}));
Valideer bij een latere keer laden eerst de structuur en het tijdstempel van het gecachte object. De ouderdom is Date.now() - savedAt. Gebruik het alleen zolang die ouderdom kleiner is dan 10 * 60 * 1000, ofwel 600.000 ms. Een waarde die om 10.00.00 uur is opgeslagen, is om 10.07.30 uur 450.000 ms oud en kan worden gebruikt. Om 10.12.00 uur is die 720.000 ms oud, dus haal je een nieuwe waarde op. Bij precies 600.000 ms is de waarde volgens deze regel vervallen.
De vervalgrens maakt deel uit van de applogica: localStorage verwijdert een item niet wanneer je versheidsinterval eindigt. Wijs een ontbrekend of ongeldig tijdstempel af in plaats van een onbekende ouderdom als vers te behandelen. Je kunt verouderde gegevens zichtbaar houden tijdens een mislukte verversing als ze als oud zijn aangeduid.
Synchroniseer andere tabbladen
Wanneer één tabblad localStorage wijzigt, ontvangen andere tabbladen met dezelfde oorsprong een storage-event. Het schrijvende tabblad ontvangt het eigen event niet. Het event bevat key, oldValue, newValue en url.
window.addEventListener("storage", (event) => {
if (event.key === "theme") applyTheme(event.newValue);
});
Pas het thema ook direct toe in het schrijvende tabblad. Handel null af wanneer een sleutel wordt verwijderd. Een storage-event vervangt het bijwerken van de toestand van je eigen pagina niet.
Bepaal wat elders thuishoort
Plaats geen wachtwoorden, betaalkaartnummers of geheime API-sleutels in Web Storage. Scripts op de oorsprong kunnen die opslag lezen, inclusief code van derden en geïnjecteerde scripts. Wis relevante persoonsgegevens bij het uitloggen op gedeelde apparaten. Bewaar belangrijk werk op een server of bied een exportmogelijkheid, omdat gebruikers sitegegevens kunnen wissen en privésessies die verwijderen.
Cookies verschillen: passende verzoeken sturen ze naar de server en HttpOnly-cookies kunnen niet door paginascripts worden gelezen. Ze zijn klein, ongeveer 4 KB per stuk. Web Storage blijft in de browser en is leesbaar voor scripts. IndexedDB is geschikt voor grotere hoeveelheden gestructureerde gegevens via een asynchrone API.
Belangrijkste punten
- Valideer ontlede gegevens en gebruik een terugvaloptie als ze ontbreken of beschadigd zijn.
- De versheid van een cache volgt uit een tijdstempel en een door de app bepaalde ouderdomsgrens.
- Het
storage-event bereikt andere tabbladen met dezelfde oorsprong, niet het schrijvende tabblad. - Houd geheimen en onvervangbare gegevens buiten Web Storage.
5Gebruik locatie- en klembordfuncties
Browser-API's verbinden een pagina met functies zoals locatie en het klembord. De beschikbaarheid hangt af van de browser, de beveiligingscontext van de pagina en de keuzes van de gebruiker. Je detecteert een functie voordat je die aanroept, vraagt op een passend moment om toestemming en handelt succes of weigering af. Een volledige interactie omvat zichtbare feedback en een andere manier om de taak af te ronden, zoals een stad invoeren of geselecteerde tekst kopiëren met het toetsenbord.
5.1 Vraag een locatie op met een terugvaloptie
Geolocatie is een browser-API: een functie die de browser biedt, los van de JavaScript-taal. Net als andere apparaatfuncties kan die niet beschikbaar zijn of worden geweigerd. Een weerpagina moet blijven werken wanneer een lezer ervoor kiest een stad te typen.
Controleer de functie en de context
Detecteer de functie zelf met "geolocation" in navigator. De naam van een browser controleren is minder betrouwbaar: versies en instellingen veranderen wat beschikbaar is. Geolocatie heeft een veilige context nodig, normaal gesproken HTTPS; http://localhost voldoet ook voor ontwikkeling. window.isSecureContext geeft aan of de huidige pagina voldoet. Gewoon HTTP op het netwerkadres van een ander apparaat is niet hetzelfde als localhost.
Leg uit waarom locatie nuttig is en vraag die op wanneer de lezer op “Gebruik mijn locatie” klikt. De browser beheert het toestemmingsverzoek. Iemand kan toestemming geven of weigeren en een eerdere weigering kan ertoe leiden dat een latere aanroep zonder nieuw verzoek mislukt. De gebruiker kan die beslissing wijzigen in de site-instellingen.
Lees het resultaat van de callback
navigator.geolocation.getCurrentPosition(success, error, options) gebruikt callbacks. Bij succes bevat position.coords de breedtegraad en lengtegraad in decimale graden en accuracy in meters. De nauwkeurigheid is een geschatte onzekerheidsstraal, geen extra precisie in decimalen. Bij een fout betekent code 1 dat toestemming is geweigerd, 2 dat de positie niet beschikbaar is en 3 dat de tijdslimiet is overschreden.
De opties bepalen de poging:
enableHighAccuracy: vraagt om hogere nauwkeurigheid; standaardfalse.timeout: maximale wachttijd in milliseconden; standaardInfinity.maximumAge: maximale ouderdom van een acceptabele gecachte positie; standaard0.
Gebruik een eindige tijdslimiet zodat de pagina niet hoeft te blijven wachten. watchPosition volgt wijzigingen in de loop van de tijd en geeft een ID terug; geef die ID door aan clearWatch wanneer het volgen moet stoppen.
Verpak callbacks wanneer je await gebruikt
function getPosition(options) {
return new Promise((resolve, reject) => {
navigator.geolocation.getCurrentPosition(resolve, reject, options);
});
}
async function useLocation() {
if (!("geolocation" in navigator)) {
showCityInput();
return;
}
try {
const { coords } = await getPosition({ timeout: 10000 });
const url = new URL("https://api.example.com/weather");
url.searchParams.set("lat", coords.latitude.toFixed(2));
url.searchParams.set("lon", coords.longitude.toFixed(2));
await loadWeather(url);
} catch {
showCityInput();
}
}
Hier toont showCityInput het bedieningselement voor handmatige invoer en vraagt en rendert loadWeather het weer. Koppel useLocation aan de locatieknop. De catch dekt zowel een locatiefout als het weerverzoek; in beide gevallen blijft handmatige invoer beschikbaar.
Vraag alleen nuttige precisie
Een positie met breedtegraad 52.3676, lengtegraad 4.9041 en nauwkeurigheid 35 heeft een geschatte straal van ongeveer 35 m. Afronden op 52.37 en 4.90 vermindert de precisie die naar de weerdienst wordt gestuurd. Een interval van 0,01° breedtegraad is ongeveer 1,1 km; de afstand tussen lengtegraden varieert met de breedtegraad. Die regionale precisie is geschikt voor een weersverwachting zonder de meest gedetailleerde coördinaten te delen.
Waar de Permissions API beschikbaar is, rapporteert navigator.permissions.query({ name: "geolocation" }) de waarde "granted", "denied" of "prompt". Detecteer en handel ook die API af. De toestand helpt de interface aan te passen, maar vervangt de foutafhandeling voor de locatieaanroep niet.
Belangrijkste punten
- Detecteer geolocatie en gebruik een veilige context.
- Vraag de locatie op na een duidelijke gebruikersactie en vermeld het doel.
- Breedtegraad en lengtegraad gebruiken graden; nauwkeurigheid gebruikt meters.
- Stel een eindige tijdslimiet in en bied handmatige invoer aan bij een fout.
- Verstuur alleen de locatieprecisie die de functie nodig heeft.
- De toestemmingstoestand garandeert geen bruikbare positie.
5.2 Kopieer tekst en leer een andere browser-API kennen
Met de klembord-API kan een pagina tekst kopiëren zonder de lezer te vragen die eerst te selecteren. Net als geolocatie vereist dit functiecontroles, een passende gebruikersactie, foutafhandeling en een terugvaloptie.
Kopieer tijdens de klik
navigator.clipboard.writeText(text) geeft een promise terug. Wacht daarop voordat je succes meldt. Een veilige context is vereist en een geweigerde bewerking kan worden afgewezen met NotAllowedError. Roep de methode rechtstreeks aan vanuit een klikhandler: Firefox en Safari vereisen een recente gebruikersinteractie, terwijl de eisen van Chromium ook kunnen afhangen van toestemming om naar het klembord te schrijven.
copyButton.addEventListener("click", async () => {
try {
if (!navigator.clipboard?.writeText) {
throw new Error("Copy unavailable");
}
await navigator.clipboard.writeText(codeField.value);
copyButton.textContent = "Copied!";
} catch {
codeField.focus();
codeField.select();
copyButton.textContent = "Copy selected text: Ctrl+C / Cmd+C";
}
setTimeout(() => {
copyButton.textContent = "Copy";
}, 2000);
});
codeField is een tekstinvoerveld of tekstvak en copyButton is de knop van de pagina. Als kopiëren mislukt, biedt het selecteren van de tekst een route via het toetsenbord: Ctrl+C op veel systemen of Cmd+C op macOS. Het label wordt na 2000 ms weer “Copy”. Toon nooit “Copied!” voordat de promise succesvol is voltooid.
Lezen gebruikt navigator.clipboard.readText() en kent strengere controles omdat een klembord privémateriaal uit andere apps kan bevatten. Een browser kan toestemming vereisen of een plakverzoek tonen. Toestemming om te schrijven betekent niet dat er toestemming is om te lezen.
Beschouw verbindingsstatus als aanwijzing
navigator.onLine en de events online en offline van het venster helpen om een verbindingsmelding te tonen. Ze bewijzen niet dat je API bereikbaar is. Een apparaat kan een netwerkverbinding hebben terwijl de API-server uitgevallen of onbereikbaar is.
window.addEventListener("offline", () => {
status.textContent = "You are offline.";
});
Blijf fouten rond fetch afhandelen, ook wanneer navigator.onLine waar is. Gebruik een geschikt livegebied voor de statusmelding.
Lees een deelbare zoekopdracht
De URL-API leest behalve voor het bouwen van API-URL's ook de querystring van de pagina zelf. Op https://books.example.org/search?q=dune geeft new URL(location.href).searchParams.get("q") de waarde "dune" terug. Lees die waarde bij het laden om een zoekopdracht vanuit een gedeelde link te herstellen. Een ontbrekende parameter geeft null terug, dus bepaal wat het beginscherm dan moet tonen.
Gebruik één leermethode
Lees voor een andere browser-API de syntaxis, regels voor veilige context en toestemming, ondersteuningstabel en Baseline-status op MDN. Detecteer daarna de functie, roep die zo nodig aan vanuit een gebruikersactie, handel de promise of callbacks af en bied een alternatief als de functie ontbreekt of wordt geweigerd.
De Notifications API toont systeemmeldingen na toestemming; Web Share opent een deelmenu van het apparaat waar dat wordt ondersteund; Canvas tekent afbeeldingen; media-API's sturen audio en video aan. Een kaarten-API van een derde partij kan een bibliotheek en een sleutel van de aanbieder toevoegen. Voor de inloggegevens gelden dezelfde regels voor geheime sleutels als bij elke andere dienst. Als je één browser via localhost test, bewijst dat niet dat een ander apparaat of een andere browser dezelfde ondersteuning en context heeft.
Belangrijkste punten
- Wacht op
writeTextvoordat je meldt dat het kopiëren is geslaagd. - Behoud een terugvaloptie om met het toetsenbord te kopiëren als toegang tot het klembord mislukt.
- Voor het lezen van het klembord gelden afzonderlijke, strengere toestemmingsregels.
- Een onlinestatus bewijst niet dat de API bereikbaar is.
- Gebruik URL-parameters om een deelbare zoekopdracht te herstellen.
- Controleer ondersteuning, detecteer functies en handel weigering af voor elke browser-API.
Gegevens ophalen en browser-API's: voorbeelden
1Bouw een leeslijst en werk die bij
14 stappen
- 1IntroductieVolg één uitwisseling
Een leeslijstpagina moet boeken laden en een notitie over een van die boeken toevoegen. De pagina is de client; de API is de server. Elke uitwisseling heeft een verzoek dat de handeling beschrijft en een antwoord dat de uitkomst beschrijft.
We lezen eerst de uitwisseling, verbinden daarna de twee asynchrone stappen bij het laden van JSON en dienen ten slotte een wijziging in. Het antwoord van de server bepaalt wat de pagina daarna veilig kan tonen.
- 2VoorbeeldLees de resource en filters
De pagina vraagt
GET https://api.example.com/books?author=Le%20Guin&limit=5op.GETvraagt om te lezen./booksduidt de resource aan. De query filtert op auteur en beperkt het aantal resultaten.%20staat voor de spatie in “Le Guin”. De API-documentatie bepaalt deze parameternamen; de pagina kan niet zomaar een andere naam kiezen en verwachten dat de dienst die begrijpt. - 3KernpuntOnderscheid status en verbinding
Een antwoord kan
200 OKmet een boek of404 Not Foundmet een fout melden. Beide bewijzen dat een server heeft geantwoord. Een verbindingsfout levert geen HTTP-status aan de pagina.Bekijk het tabblad Network voor de volledige URL, methode, status, headers en inhoud. Als de API de verwachte JSON teruggaf, onderzoek je vervolgens de code die die gegevens leest of toont.
- 4UitdagingKies een methode voor een wijziging
Een notitie bestaat al. De pagina moet alleen het veld
donewijzigen en de tekst behouden. Welke HTTP-methode past bij die bewerking en waarom zouGETverkeerd zijn?---reveal---
Gebruik
PATCHvoor de gedeeltelijke wijziging.GETis een veilige leesmethode en mag niet worden gebruikt om een gegevenswijziging aan te vragen.PUTzou een volledige vervanging beschrijven en zou velden die in de inhoud ontbreken kunnen terugzetten. - 5UitlegWacht op het antwoord
Begin met
const response = await fetch(url). Dit wacht totdat de antwoordheaders binnenkomen en levert eenResponseop, niet de ontlede boeken.Het antwoord kan nog steeds een HTTP-fout zijn.
fetchwordt bij een404succesvol voltooid omdat er een antwoord is. Controleerresponse.okvoordat je de bewerking als geslaagd beschouwt; dit is waar voor statuscodes200tot en met299. - 6VoorbeeldControleer en lees de inhoud
Ga verder binnen de asynchrone functie:
if (!response.ok) { throw new Error(`HTTP error ${response.status}`); } const data = await response.json();De tweede wachtstap leest en ontleedt de inhoud. Nu is
dataeen JavaScript-waarde. Een omringendetry/catchkan zowel de hier opgeworpen statusfout als fouten bij het ophalen of ontleden van de inhoud afhandelen. - 7VoorbeeldZoek de geneste array
Stel dat de inhoud
{"results":[{"title":"Dune"}],"total":1}is.De eerste stap,
data.results, bereikt de array.[0]bereikt het eerste object daarin..titlegeeft"Dune". Een renderfunctie moetdata.resultsontvangen, niet het hele buitenste object. De voorbeeldweergave van het antwoord in Network is nuttig wanneer de structuur van de API verschilt van wat de pagina verwachtte. - 8UitdagingOnderzoek de ontbrekende waarde
De code gebruikt
const data = response.json()en probeert daarnadata.results[0]. De inhoud is inderdaad geldige JSON met een arrayresults. Wat ontbreekt er?---reveal---
Wacht op de inhoud:
const data = await response.json(). Zonder die wachtstap isdataeen promise en heeft die geen eigenschapresults. De eersteawait fetch(...)wachtte niet ook op het ontleden van de JSON. - 9TipBehoud leestekens in een zoekopdracht
Bouw queryparameters met de URL-API:
const url = new URL("https://api.example.com/search"); url.searchParams.set("q", "rock & roll");De waarde wordt
rock+%26+roll. De ampersand blijft binnen de zoekterm in plaats van de query te splitsen. Gebruik het ontlede antwoord na het laden opnieuw: een tweede methode aanroepen om de inhoud van hetzelfde antwoord te lezen mislukt omdat de inhoud al is gelezen. - 10VoorbeeldBereid een JSON-verzending voor
Om een notitie aan te maken, serialiseer je de velden en vermeld je hun formaat:
const response = await fetch("https://api.example.com/notes", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ title: "Read", done: false }), });De methode vraagt om aanmaken, de header geeft JSON aan en de inhoud bevat JSON-tekst in plaats van een gewoon object.
- 11VerbandGebruik het opgeslagen record
De server kan
201 Createdteruggeven met{"id":31,"title":"Read","done":false}. Voeg dat teruggegeven record toe aan de toestand van de pagina. Met de ID kan een latere handeling/notes/31aanroepen.Geef voor een formulier met bestanden
FormDatadoor in plaats van JSON en laat de browser het scheidingsteken voor de meerdelige inhoud instellen. EenGET-verzoek kan viafetchgeen inhoud bevatten; zoekvelden horen in de querystring. - 12UitdagingHandel succes zonder inhoud af
Het verwijderen van een opgeslagen notitie geeft
204terug. De code controleertresponse.ok, roept daarnaresponse.json()aan en toont een fout. Is de verwijdering noodzakelijkerwijs mislukt en wat moet veranderen?---reveal---
Nee:
204meldt succesvolle voltooiing zonder inhoud. Sla voor die status het ontleden van JSON over en werk de pagina bij na de statuscontrole. De ontleedfout ontstond doordat de code lege inhoud probeerde te lezen, niet doordat vaststaat dat de verwijdering is mislukt. - 13UitdagingBekijk een volledige verzendstroom
Een opslagknop kan tweemaal worden aangeklikt terwijl een
POSTloopt. Een succesvol antwoord levert een nieuwe ID. Noem de twee handelingen van de pagina die een onbedoeld duplicaat voorkomen en die ID bewaren.---reveal---
Schakel de knop uit tijdens het verzoek en herstel die in
finally. Werk de pagina bij succes bij vanuit het teruggegeven record, inclusief de ID. De knop voorkomt herhaalde klikken; het serverresultaat levert waarden die niet in de ingediende gegevens bestonden. - 14SamenvattingControleer de uitwisseling bij elke grens
Wanneer een verzoek zich onverwacht gedraagt, onderzoek je de bewerking in volgorde: de gedocumenteerde URL en methode, de werkelijke status, de gekozen methode om de inhoud te lezen en de gegevensstructuur die aan de pagina wordt doorgegeven.
Controleer bij een schrijfbewerking ook het inhoudstype en de geserialiseerde inhoud. Succes zonder inhoud vereist geen JSON-lezer. Een antwoord op een aanmaakverzoek moet het opgeslagen record leveren dat voor de volgende wijziging of verwijdering wordt gebruikt.
2Bouw een zoekpagina die actueel blijft
18 stappen
Sla deze les op om elke Walkthrough stap voor stap te volgen.
- 1IntroductieHoud het scherm gekoppeld aan de zoekopdracht
- 2VoorbeeldVervang de vorige lijst
- 3KernpuntHoud nul en ontbrekende gegevens uit elkaar
- 4UitdagingVerwerk externe tekst en links
- 5VoorbeeldLees de tijdseenheid
- 6UitlegKies de tijdzone voor de weergave
- 7VoorbeeldMaak gedocumenteerde kleinere munteenheden op
- 8UitdagingHoud landinstelling en waarde gescheiden
- 9UitlegBegin met zichtbaar wachten
- 10VoorbeeldRond alle paden af
- 11UitdagingHerken een geslaagde lege zoekopdracht
- 12TipWacht voor een nieuwe poging bij een tijdelijk probleem
- 13VoorbeeldLet op de volgorde van voltooiing
- 14VoorbeeldAnnuleer een verouderd verzoek
- 15VerbandVerminder aanroepen tijdens het typen
- 16UitdagingKies voor gedeeltelijk succes
- 17UitdagingBescherm de hele huidige interactie
- 18SamenvattingTest de interface met onvolmaakte antwoorden
3Onderzoek een API-aanroep naar een andere oorsprong
10 stappen
Sla deze les op om elke Walkthrough stap voor stap te volgen.
- 1IntroductieHoud twee toestemmingsvragen gescheiden
- 2VoorbeeldVergelijk de volledige oorsprongen
- 3UitlegLees de toestemming van de server
- 4VoorbeeldVolg eerst het voorafgaande toestemmingsverzoek
- 5UitdagingLeg uit waarom iets alleen in de terminal slaagt
- 6VoorbeeldZoek de zichtbare sleutel
- 7VerbandVerplaats de grens van het geheim
- 8UitdagingOnderscheid transport en geheimhouding
- 9UitdagingControleer cookies en leesbare antwoorden
- 10SamenvattingOnderzoek welke grens de fout veroorzaakte
4Herstel een opgeslagen lijst zonder de pagina te verstoren
12 stappen
Sla deze les op om elke Walkthrough stap voor stap te volgen.
- 1IntroductieBewaar een handige lokale kopie
- 2UitlegKies wat bewaard moet blijven
- 3VoorbeeldBewaar een array als tekst
- 4UitdagingHerstel het bedoelde type
- 5TipHandel een schrijfbewerking af die niet past
- 6VoorbeeldControleer meer dan de JSON-syntaxis
- 7VoorbeeldVoeg een cachetijd toe
- 8UitdagingBereken welke cache vers is
- 9VerbandVolg een thema over tabbladen
- 10KernpuntBescherm belangrijke gegevens
- 11UitdagingHerstel van een oud opgeslagen formaat
- 12SamenvattingTest een eerste en een terugkerend bezoek
5Voeg bruikbare locatie- en kopieerknoppen toe
13 stappen
Sla deze les op om elke Walkthrough stap voor stap te volgen.
- 1IntroductieMaak de handeling begrijpelijk
- 2UitlegControleer de context en functie
- 3TipVraag toestemming wanneer de functie nuttig is
- 4VoorbeeldStel een eindige wachttijd in
- 5VoorbeeldLees alleen nuttige precisie
- 6UitdagingHerstel na een weigering
- 7VoorbeeldSchrijf tijdens de klik
- 8KernpuntWacht voordat je het kopiëren als geslaagd meldt
- 9UitdagingBeschouw een verbindingssignaal als aanwijzing
- 10VerbandHerstel een zoekopdracht vanuit een link
- 11TipControleer een andere browserfunctie
- 12UitdagingBekijk beide knoppen samen
- 13SamenvattingTest ook de keuzes van de gebruiker
Gegevens ophalen en browser-API's: oefenvragen
Set 1: Verzoeken, resultaten en browserfuncties10 Oefenvragen
Vraag 1 van 10
403. Wat vertelt die status aan de pagina?Toon antwoordVerberg antwoord
403-antwoord betekent dat de server het verzoek begreep en weigert uit te voeren. Het bewijst niet dat de gebruiker geldige inloggegevens heeft opgegeven of dat inloggen de weigering oplost. Een mislukte netwerkverbinding zou geen HTTP-status opleveren die de pagina kan lezen.Vraag 2 van 10
200 terug met {"items":[{"name":"Cedar"}]}. Welke toewijzing slaat de naam van het eerste item op na const response = await fetch(url)?Toon antwoordVerberg antwoord
json() om de inhoud te lezen en te ontleden en volg daarna de buitenste eigenschap items naar het eerste object van de array. Als je json() zonder await aanroept, houd je een promise over die geen array items heeft. Lezen met text() geeft een string, niet het ontlede object dat nodig is om eigenschappen te benaderen.Vraag 3 van 10
body krijgen wanneer je { label: "Read" } verstuurt?Toon antwoordVerberg antwoord
JSON.stringify zet het object om in geldige JSON-tekst voor de verzoekinhoud. Een gewoon object converteren met String of toString() levert "[object Object]" op, wat het JSON-eindpunt niet kan ontleden. Het verzoek heeft ook de gedocumenteerde methode en een header met het JSON-inhoudstype nodig.Vraag 4 van 10
{ remaining: 0, owner: null } terug. Hoe kan de pagina het resterende aantal tonen en voor de ontbrekende naam van de eigenaar "Unknown" gebruiken?Toon antwoordVerberg antwoord
name uit null wordt gelezen. Als je || voor het aantal gebruikt, wordt nul vervangen omdat nul falsy is. Een terugvaloptie na data.owner.name helpt niet wanneer het opvragen van name al een fout heeft opgeworpen.Vraag 5 van 10
amount: 3785, currency: "USD" als een geheel aantal kleinere munteenheden. Welk getal moet aan de valutaopmaakfunctie worden doorgegeven?Toon antwoordVerberg antwoord
3785 rechtstreeks doorgeeft, wordt een bedrag getoond dat 100 keer te groot is. Intl.NumberFormat maakt het getal op dat het ontvangt; het leidt niet af dat een API-bedrag in centen is.Vraag 6 van 10
Toon antwoordVerberg antwoord
finally wordt na het beschermde werk uitgevoerd, of dat nu slaagt of een fout opwerpt. Het is dus de juiste plaats voor opruiming die op beide paden nodig is. Als de knop alleen in catch wordt hersteld, gebeurt dat niet bij succes; als dat pas na het renderen gebeurt, ontbreekt het bij een fout. Een timer zou bedieningselementen herstellen zonder te weten of het verzoek is voltooid.Vraag 7 van 10
https://studio.example.org/edit. Wat is de oorsprong van die pagina?Toon antwoordVerberg antwoord
/edit duidt een resource binnen de oorsprong aan en maakt geen deel uit van de oorsprong zelf. Als je het schema wijzigt naar HTTP, ontstaat een andere oorsprong, ook bij dezelfde host.Vraag 8 van 10
Toon antwoordVerberg antwoord
Vraag 9 van 10
localStorage.setItem("visits", 8) de waarde van localStorage.getItem("visits") + 1?Toon antwoordVerberg antwoord
"8" terug, dus + 1 schakelt strings aaneen en geeft "81". Het numerieke type dat aan setItem is doorgegeven, wordt niet hersteld. Converteer de opgeslagen string met Number voordat je optelt als het bedoelde resultaat het getal 9 is.Vraag 10 van 10
1. Welke reactie aan de gebruiker past bij deze fout?Toon antwoordVerberg antwoord
1 betekent dat toestemming is geweigerd, dus bied een andere manier aan om de locatie in te voeren. Een overschreden tijdslimiet heeft code 3 en verklaart deze fout niet. Herhaalde verzoeken kunnen toestemming niet afdwingen; bij een onthouden weigering moet de gebruiker mogelijk de site-instellingen van de browser wijzigen.Set 2: Volg gegevens door de interface10 Oefenvragen
Sla deze les op om elk antwoord te zien en elke set te oefenen.
Vraag 1 van 10
fetch geeft een Response met status 502 terug. De code heeft een catch-handler maar controleert nooit response.ok. Waarom verschijnt de HTTP-foutmelding mogelijk nooit?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 2 van 10
204 terug. Wat moet de pagina doen voordat ze JSON probeert te ontleden?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 3 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 4 van 10
Promise.all, afgezien van bijkomende verwerkingstijd?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 5 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 6 van 10
POST met Content-Type: application/json. Er is geen toestemming voor een voorafgaand verzoek gecachet. Wat moet de browser controleren voordat die de POST verstuurt?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 7 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 8 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 9 van 10
http://localhost, maar de locatiefunctie ontbreekt wanneer de app op een telefoon via een HTTP-netwerkadres wordt geopend. De app stopt ook met werken wanneer desktopgebruikers locatietoegang weigeren. Welk ontwerp verhelpt beide problemen?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 10 van 10
navigator.clipboard.writeText(text). Op welk moment moet die “Copied!” tonen?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Set 3: Spoor fouten op in verzoeken, opslag en toestemming10 Oefenvragen
Sla deze les op om elk antwoord te zien en elke set te oefenen.
Vraag 1 van 10
PUT /profiles/29 als vervanging van het profiel. Wat betekent idempotentie wanneer hetzelfde volledige verzoek tweemaal wordt verstuurd?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 2 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 3 van 10
new Date en toont januari 1970. Welke conversie moet vóór het opmaken van de datum plaatsvinden?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 4 van 10
503 met Retry-After: 12 teruggeeft. Welk gedrag maakt de toestand duidelijk en ondersteunt herstel?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 5 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 6 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 7 van 10
if (localStorage.getItem("compact")). De opgeslagen tekst is "false", maar toch gaat de compacte modus aan. Waarom?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 8 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 9 van 10
-12.0464, lengtegraad -77.0428 en nauwkeurigheid 80. Wat beschrijft 80?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 10 van 10
https://recipes.example.org/search?q=green+tea leest new URL(location.href).searchParams.get("q"). Welke waarde krijgt de pagina?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Set 4: Ontwerp betrouwbare API-functies10 Oefenvragen
Sla deze les op om elk antwoord te zien en elke set te oefenen.
Vraag 1 van 10
429. Wat betekent die status?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 2 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 3 van 10
<b>-tekst, een javascript:-link en remaining: 0. De pagina moet de letterlijke titel tonen, alleen gewone weblinks toestaan en het aantal behouden. Welk renderplan voldoet aan alle drie eisen?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 4 van 10
Intl.DateTimeFormat en een vaste landinstelling en-US, maar zonder de optie timeZone. Hun weergegeven kloktijden verschillen. Wat verklaart het verschil?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 5 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 6 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 7 van 10
PATCH naar een andere oorsprong gebruikt credentials: "include". Het voorafgaande toestemmingsverzoek staat dit toe. Het uiteindelijke antwoord heeft een wildcard voor toegestane oorsprongen en staat inloggegevens toe, waardoor JavaScript het niet kan lezen. De server neemt ook aan dat CORS gebruikerscontroles overbodig maakt. Welk antwoord- en toegangsbeleid herstelt dit ontwerp?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 8 van 10
Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 9 van 10
.map aan. Sommige gebruikers hebben geldige JSON {"version":1,"items":[]} van oudere code, anderen hebben beschadigde tekst. Welk herstelplan behandelt beide gevallen?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Vraag 10 van 10
navigator.onLine === true, maar een API-aanroep wordt afgewezen. Wat moet de pagina afleiden over de verbinding en vervolgens afhandelen?Toon antwoordVerberg antwoord
Sla deze les op om dit antwoord te zien.
Kom je niet uit je eigen opgave? Huiswerkhulp
Kernbegrippen
A
AbortController
AbortSignal
AbortSignal.timeout(4000) begrenst een verzoek tot vier seconden actieve tijd.antwoordinhoud
API-eindpunt
POST om een notitie aan te maken en geeft de identificatiecode van het nieuwe record terug.API-sleutel
B
Baseline
beleid voor dezelfde oorsprong
C
cache
CORS
cross-site scripting
textContent voor API-titels te gebruiken, voorkom je de HTML-interpretatie die cross-site scripting mogelijk kan maken.E
exponentieel oplopende wachttijd
F
FormData
functiedetectie
"geolocation" in navigator bepaalt of de pagina de apparaatlocatie kan aanbieden.G
gebruikersactivering
gemengde inhoud
geolocatie
H
header
Content-Type-header vertelt het ontvangende programma dat de bijbehorende inhoud JSON bevat.HTTP-antwoord
404 en legt in de inhoud uit dat het opgevraagde boek niet is gevonden.HTTP-verzoek
/books op en bevat een queryparameter die het aantal resultaten beperkt.HttpOnly
I
idempotentie
IndexedDB
Intl.NumberFormat
Intl.NumberFormat opnieuw voor elke prijs in plaats van voor elk item een valutastring opnieuw op te bouwen.J
JSON
results voordat ze lijstitems opbouwt.K
klembord-API
L
laadstatus
landinstelling
en-US schrijft een datum anders dan en-GB, ook wanneer beide hetzelfde moment opmaken.leegtestatus
livegebied
role="status" kondigt “Laden…” en de latere melding over zoekresultaten aan.localStorage
locatienauwkeurigheid
O
onderverdeling van een munteenheid
4680 voor 46.80 Amerikaanse dollar.ondoorzichtig antwoord
ontleedfout
204 veroorzaakt een JSON-ontleedfout, ook al heeft de server de bewerking succesvol voltooid.oorsprong
opslagquotum
optionele ketenvorming
?. null of undefined is en geeft undefined terug.book.author?.name omgaan met een boek waarvan het auteurobject in het antwoord ontbreekt.P
paginering
Promise.all
Promise.allSettled
Q
queryparameter
?, die een API-eindpunt gebruikt voor invoer zoals zoekopdrachten of paginalimieten.limit=12 vraagt het zoek-eindpunt om maximaal twaalf resultaten terug te geven.R
raceconditie
renderen
Response-object
200, maar de pagina wacht nog op json() om de boekgegevens te verkrijgen.Retry-After
Retry-After-waarde van 15 vraagt de pagina om vijftien seconden te wachten vóór een volgend verzoek.S
scheidingsteken voor meerdelige inhoud
serialisatie
JSON.stringify bewaart de velden van een notitie wanneer die als JSON-verzoekinhoud worden verstuurd.sessionStorage
statuscode
201 vertelt de pagina dat de server als antwoord op het verzoek een resource heeft aangemaakt.storage-event
synchrone bewerking
T
terugval bij null of undefined
?? alleen een terugvalwaarde wanneer de waarde links null of undefined is, en behoudt geldige nullen.terugvaloptie
textContent
textContent toewijst, worden de punthaken letterlijk weergegeven en wordt er geen HTML-element gemaakt.tijdzone
toegangstoken
toestemming
U
uitstellen tot na een rustperiode
Unix-tijdstempel
URL-codering
UTC
Z aan het einde van een ISO-datum en -tijd.V
veilige context
vervalgrens
verzoekinhoud
verzoeklimiet
voorafgaand toestemmingsverzoek
W
Web Storage
web-API
Over deze les
Door StudeliFout melden
Maak je eigen Studiemateriaal
Maak van je aantekeningen, slides en documenten Leermodules, Oefenvragen, Flashcards en 6 andere tools.