Õppige selgeks Fetch API edasijõudnute tehnikad: päringute vaheltlõikamine muutmiseks ja vastuste vahemällu salvestamine optimaalse jõudluse saavutamiseks. Tutvuge parimate tavadega globaalsete rakenduste jaoks.
Fetch API edasijõudnutele: päringute vaheltlõikamine ja vastuste vahemällu salvestamine
Fetch API on muutunud standardiks võrgupäringute tegemisel kaasaegses JavaScriptis. Kuigi põhikäsitlus on lihtne, nõuab selle täieliku potentsiaali avamine edasijõudnute tehnikate, nagu päringute vaheltlõikamine ja vastuste vahemällu salvestamine, mõistmist. See artikkel uurib neid kontseptsioone üksikasjalikult, pakkudes praktilisi näiteid ja parimaid tavasid suure jõudlusega, globaalselt kättesaadavate veebirakenduste loomiseks.
Fetch API mõistmine
Fetch API pakub võimsat ja paindlikku liidest ressursside hankimiseks üle võrgu. See kasutab Promises-objekte, mis muudab asünkroonsete operatsioonide haldamise ja mõistmise lihtsamaks. Enne edasijõudnute teemade juurde sukeldumist vaatame lühidalt üle põhitõed:
Fetch'i põhikasutus
Lihtne Fetch-päring näeb välja selline:
fetch('https://api.example.com/data')
.then(response => {
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
return response.json();
})
.then(data => {
console.log('Data:', data);
})
.catch(error => {
console.error('Fetch error:', error);
});
See kood hangib andmed määratud URL-ilt, kontrollib HTTP-vigade olemasolu, pargib vastuse JSON-vormingus ja logib andmed konsooli. Vigade käsitlemine on robustse rakenduse tagamiseks ülioluline.
Päringute vaheltlõikamine
Päringute vaheltlõikamine hõlmab võrgupäringute muutmist või jälgimist enne nende serverisse saatmist. See võib olla kasulik mitmel eesmärgil, sealhulgas:
- Autentimispäiste lisamine
- Päringu andmete teisendamine
- Päringute logimine silumiseks
- API vastuste jäljendamine arenduse ajal
Päringute vaheltlõikamine saavutatakse tavaliselt Service Workeri abil, mis toimib veebirakenduse ja võrgu vahelise proksina.
Service Workerid: vaheltlõikamise alus
Service Worker on JavaScripti fail, mis töötab taustal, eraldi peamisest brauseri lõimest. See suudab vahele lõigata võrgupäringuid, salvestada vastuseid vahemällu ja pakkuda võrguühenduseta funktsionaalsust. Service Workeri kasutamiseks peate selle esmalt registreerima:
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/service-worker.js')
.then(registration => {
console.log('Service Worker registered with scope:', registration.scope);
})
.catch(error => {
console.error('Service Worker registration failed:', error);
});
}
See kood kontrollib, kas brauser toetab Service Workereid ja registreerib faili service-worker.js
. Skoobi ala määratleb, milliseid URL-e Service Worker kontrollib.
Päringute vaheltlõikamise rakendamine
Failis service-worker.js
saate päringuid vahele lõigata sündmuse fetch
abil:
self.addEventListener('fetch', event => {
// Intercept all fetch requests
event.respondWith(
new Promise(resolve => {
// Clone the request to avoid modifying the original
const req = event.request.clone();
// Modify the request (e.g., add an authentication header)
const headers = new Headers(req.headers);
headers.append('Authorization', 'Bearer your_api_key');
const modifiedReq = new Request(req.url, {
method: req.method,
headers: headers,
body: req.body,
mode: 'cors',
credentials: req.credentials,
cache: req.cache,
redirect: req.redirect,
referrer: req.referrer,
integrity: req.integrity
});
// Make the modified request
fetch(modifiedReq)
.then(response => resolve(response))
.catch(error => {
console.error('Fetch error in Service Worker:', error);
// Optionally, return a default response or error page
resolve(new Response('Offline', { status: 503, statusText: 'Service Unavailable' }));
});
})
);
});
See kood lõikab vahele iga fetch
-päringu, kloonib selle, lisab päise Authorization
ja teeb seejärel muudetud päringu. Meetod event.respondWith()
ütleb brauserile, kuidas päringut käsitleda. On ülioluline päring kloonida; vastasel juhul muudate algset päringut, mis võib põhjustada ootamatut käitumist. Samuti tagab see, et kõik algsed päringuvalikud edastatakse ühilduvuse tagamiseks. Pange tähele veakäsitlust: oluline on pakkuda tagavara juhuks, kui päring ebaõnnestub (nt võrguühenduseta olekus).
Näide: Autentimispäiste lisamine
Levinud kasutusjuht päringute vaheltlõikamiseks on autentimispäiste lisamine API-päringutele. See tagab, et kaitstud ressurssidele pääsevad juurde ainult volitatud kasutajad.
self.addEventListener('fetch', event => {
if (event.request.url.startsWith('https://api.example.com')) {
event.respondWith(
new Promise(resolve => {
const req = event.request.clone();
const headers = new Headers(req.headers);
// Replace with actual authentication logic (e.g., retrieving token from local storage)
const token = localStorage.getItem('api_token');
if (token) {
headers.append('Authorization', `Bearer ${token}`);
} else {
console.warn("No API token found, request may fail.");
}
const modifiedReq = new Request(req.url, {
method: req.method,
headers: headers,
body: req.body,
mode: 'cors',
credentials: req.credentials,
cache: req.cache,
redirect: req.redirect,
referrer: req.referrer,
integrity: req.integrity
});
fetch(modifiedReq)
.then(response => resolve(response))
.catch(error => {
console.error('Fetch error in Service Worker:', error);
resolve(new Response('Offline', { status: 503, statusText: 'Service Unavailable' }));
});
})
);
} else {
// Let the browser handle the request as usual
event.respondWith(fetch(event.request));
}
});
See kood lisab päise Authorization
päringutele, mis algavad aadressiga https://api.example.com
. See hangib API-tõendi kohalikust salvestusruumist. On ülioluline rakendada nõuetekohaseid tõendihaldus- ja turvameetmeid, näiteks HTTPS ja turvaline salvestusruum.
Näide: Päringu andmete teisendamine
Päringute vaheltlõikamist saab kasutada ka päringu andmete teisendamiseks enne nende serverisse saatmist. Näiteks võite soovida andmeid teisendada kindlasse vormingusse või lisada täiendavaid parameetreid.
self.addEventListener('fetch', event => {
if (event.request.url.includes('/submit-form')) {
event.respondWith(
new Promise(resolve => {
const req = event.request.clone();
req.text().then(body => {
try {
const parsedBody = JSON.parse(body);
// Transform the data (e.g., add a timestamp)
parsedBody.timestamp = new Date().toISOString();
// Convert the transformed data back to JSON
const transformedBody = JSON.stringify(parsedBody);
const modifiedReq = new Request(req.url, {
method: req.method,
headers: req.headers,
body: transformedBody,
mode: 'cors',
credentials: req.credentials,
cache: req.cache,
redirect: req.redirect,
referrer: req.referrer,
integrity: req.integrity
});
fetch(modifiedReq)
.then(response => resolve(response))
.catch(error => {
console.error('Fetch error in Service Worker:', error);
resolve(new Response('Offline', { status: 503, statusText: 'Service Unavailable' }));
});
} catch (error) {
console.error("Error parsing request body:", error);
resolve(fetch(event.request)); // Fallback to original request
}
});
})
);
} else {
event.respondWith(fetch(event.request));
}
});
See kood lõikab vahele päringud aadressile /submit-form
, pargib päringu keha JSON-vormingus, lisab ajatempli ja saadab seejärel teisendatud andmed serverisse. Veakäsitlemine on hädavajalik tagamaks, et rakendus ei lähe katki, kui päringu keha ei ole kehtiv JSON.
Vastuste vahemällu salvestamine
Vastuste vahemällu salvestamine hõlmab API-päringute vastuste talletamist brauseri vahemälus. See võib oluliselt parandada jõudlust, vähendades võrgupäringute arvu. Kui vahemällu salvestatud vastus on saadaval, saab brauser selle otse vahemälust serveerida, ilma et peaks serverisse uut päringut tegema.
Vastuste vahemällu salvestamise eelised
- Parem jõudlus: Kiiremad laadimisajad ja reageerimisvõimelisem kasutajakogemus.
- Vähenenud ribalaiuse tarbimine: Võrgu kaudu edastatakse vähem andmeid, mis säästab ribalaiust nii kasutaja kui ka serveri jaoks.
- Võrguühenduseta funktsionaalsus: Vahemällu salvestatud vastuseid saab serveerida isegi siis, kui kasutaja on võrguühenduseta, pakkudes sujuvat kogemust.
- Kulude kokkuhoid: Madalam ribalaiuse tarbimine tähendab madalamaid kulusid nii kasutajatele kui ka teenusepakkujatele, eriti piirkondades, kus on kallid või piiratud andmesidepaketid.
Vastuste vahemällu salvestamine Service Workeritega
Service Workerid pakuvad võimsat mehhanismi vastuste vahemällu salvestamiseks. Vastuste talletamiseks ja hankimiseks saate kasutada Cache
API-t.
const cacheName = 'my-app-cache-v1';
const cacheableUrls = [
'/',
'/index.html',
'/styles.css',
'/script.js',
'https://api.example.com/data'
];
// Install event: Cache static assets
self.addEventListener('install', event => {
event.waitUntil(
caches.open(cacheName)
.then(cache => {
console.log('Caching app shell');
return cache.addAll(cacheableUrls);
})
);
});
// Activate event: Clean up old caches
self.addEventListener('activate', event => {
event.waitUntil(
caches.keys().then(cacheNames => {
return Promise.all(
cacheNames.filter(name => name !== cacheName)
.map(name => caches.delete(name))
);
})
);
});
// Fetch event: Serve cached responses or fetch from the network
self.addEventListener('fetch', event => {
event.respondWith(
caches.match(event.request)
.then(response => {
// Cache hit - return response
if (response) {
return response;
}
// Not in cache - fetch from network
return fetch(event.request).then(
response => {
// Check if we received a valid response
if (!response || response.status !== 200 || response.type !== 'basic') {
return response;
}
// Clone the response (because it's a stream and can only be consumed once)
const responseToCache = response.clone();
caches.open(cacheName)
.then(cache => {
cache.put(event.request, responseToCache);
});
return response;
}
).catch(error => {
// Handle network error
console.error("Fetch failed:", error);
// Optionally, provide a fallback response (e.g., offline page)
return caches.match('/offline.html');
});
})
);
});
See kood salvestab staatilised varad installimise sündmuse ajal ja serveerib vahemällu salvestatud vastuseid fetch-sündmuse ajal. Kui vastust ei leita vahemälust, hangib see selle võrgust, salvestab vahemällu ja seejärel tagastab selle. Sündmust `activate` kasutatakse vanade vahemälude puhastamiseks, kui Service Workerit värskendatakse. See lähenemine tagab ka, et vahemällu salvestatakse ainult kehtivad vastused (staatus 200 ja tüüp 'basic').
Vahemälu strateegiad
Sõltuvalt teie rakenduse vajadustest on mitu erinevat vahemälu strateegiat, mida saate kasutada:
- Vahemälu-enne (Cache-First): Püütakse vastus serveerida kõigepealt vahemälust. Kui seda ei leita, hangitakse see võrgust ja salvestatakse vahemällu. See sobib hästi staatilistele varadele ja ressurssidele, mis ei muutu sageli.
- Võrk-enne (Network-First): Püütakse vastus hankida kõigepealt võrgust. Kui see ebaõnnestub, serveeritakse see vahemälust. See sobib hästi dünaamilistele andmetele, mis peavad olema ajakohased.
- Vahemälu, seejärel võrk (Cache, then Network): Serveeritakse vastus kohe vahemälust ja seejärel värskendatakse vahemälu võrgust saadud uusima versiooniga. See tagab kiire esialgse laadimise ja kindlustab, et kasutajal on alati (lõpuks) uusimad andmed.
- Vana-kuni-uuesti-valideerimine (Stale-While-Revalidate): Tagastatakse kohe vahemällu salvestatud vastus, samal ajal kontrollides võrgust uuendatud versiooni. Vahemälu värskendatakse taustal, kui uuem versioon on saadaval. Sarnane "Vahemälu, seejärel võrk" strateegiale, kuid pakub sujuvamat kasutajakogemust.
Vahemälu strateegia valik sõltub teie rakenduse konkreetsetest nõuetest. Arvestage selliste teguritega nagu värskenduste sagedus, värskuse tähtsus ja saadaolev ribalaius.
Näide: API vastuste vahemällu salvestamine
Siin on näide API vastuste vahemällu salvestamisest, kasutades Vahemälu-enne strateegiat:
self.addEventListener('fetch', event => {
if (event.request.url.startsWith('https://api.example.com')) {
event.respondWith(
caches.match(event.request)
.then(response => {
// Cache hit - return response
if (response) {
return response;
}
// Not in cache - fetch from network
return fetch(event.request).then(
response => {
// Check if we received a valid response
if (!response || response.status !== 200 || response.type !== 'basic') {
return response;
}
// Clone the response (because it's a stream and can only be consumed once)
const responseToCache = response.clone();
caches.open(cacheName)
.then(cache => {
cache.put(event.request, responseToCache);
});
return response;
}
);
})
);
} else {
// Let the browser handle the request as usual
event.respondWith(fetch(event.request));
}
});
See kood salvestab vahemällu API vastused aadressilt https://api.example.com
. Kui tehakse päring, kontrollib Service Worker esmalt, kas vastus on juba vahemälus. Kui on, tagastatakse vahemällu salvestatud vastus. Kui ei, tehakse päring võrku ja vastus salvestatakse vahemällu enne selle tagastamist.
Edasijõudnute kaalutlused
Vahemälu tühistamine
Üks suurimaid väljakutseid vahemälu kasutamisel on vahemälu tühistamine (cache invalidation). Kui andmed serveris muutuvad, peate tagama, et vahemälu värskendatakse. Vahemälu tühistamiseks on mitu strateegiat:
- Vahemälu lõhkumine (Cache Busting): Lisage ressursi URL-ile versiooninumber või ajatempel. Kui ressurss muutub, muutub ka URL ja brauser hangib uue versiooni.
- Ajapõhine aegumine: Määrake vahemällu salvestatud vastustele maksimaalne vanus. Pärast aegumisaja möödumist hangib brauser serverist uue versiooni. Maksimaalse vanuse määramiseks kasutage päist
Cache-Control
. - Käsitsi tühistamine: Kasutage meetodit
caches.delete()
vahemällu salvestatud vastuste käsitsi eemaldamiseks. Selle võib käivitada serveripoolne sündmus või kasutaja tegevus. - WebSockets reaalajas värskenduste jaoks: Kasutage WebSockets-tehnoloogiat värskenduste serverist kliendile edastamiseks, tühistades vajadusel vahemälu.
Sisuedastusvõrgud (CDN-id)
Sisuedastusvõrgud (CDN-id) on hajutatud serverite võrgustikud, mis salvestavad sisu kasutajatele lähemale. CDN-i kasutamine võib oluliselt parandada jõudlust kasutajatele üle maailma, vähendades latentsust ja ribalaiuse tarbimist. Populaarsed CDN-i pakkujad on Cloudflare, Amazon CloudFront ja Akamai. CDN-idega integreerimisel veenduge, et päised Cache-Control
oleksid optimaalse vahemälu käitumise jaoks õigesti konfigureeritud.
Turvakaalutlused
Päringute vaheltlõikamise ja vastuste vahemällu salvestamise rakendamisel on oluline arvestada turvalisusega seotud tagajärgedega:
- HTTPS: Kasutage alati HTTPS-i, et kaitsta andmeid edastamise ajal.
- CORS: Konfigureerige päritoluülese ressursijagamise (CORS) poliitikaid õigesti, et vältida volitamata juurdepääsu ressurssidele.
- Andmete puhastamine: Puhastage kasutaja sisendit, et vältida saidiüleste skriptimisrünnakute (XSS) ohtu.
- Turvaline salvestusruum: Hoidke tundlikke andmeid, nagu API-võtmed ja tõendid, turvaliselt (nt kasutades HTTPS-only küpsiseid või turvalist salvestus-API-t).
- Alloleva ressursi terviklikkus (SRI): Kasutage SRI-d, et tagada, et kolmandate osapoolte CDN-idest hangitud ressursse ei oleks rikutud.
Service Workerite silumine
Service Workerite silumine võib olla keeruline, kuid brauseri arendajatööriistad pakuvad mitmeid abistavaid funktsioone:
- Rakenduse vahekaart (Application Tab): Chrome DevTools'i rakenduse vahekaart pakub teavet Service Workerite kohta, sealhulgas nende olekut, skoopi ja vahemälu salvestusruumi.
- Konsooli logimine: Kasutage
console.log()
lauseid teabe logimiseks Service Workeri tegevuse kohta. - Katkestuspunktid (Breakpoints): Seadke katkestuspunkte Service Workeri koodi, et samm-sammult täitmist läbida ja muutujaid kontrollida.
- Uuenda uuestilaadimisel (Update on Reload): Lubage rakenduse vahekaardil valik "Uuenda uuestilaadimisel", et tagada Service Workeri värskendamine iga kord, kui lehte uuesti laadite.
- Tühista Service Workeri registreerimine (Unregister Service Worker): Kasutage rakenduse vahekaardil nuppu "Tühista registreerimine", et Service Worker eemaldada. See võib olla kasulik probleemide lahendamisel või puhtalt lehelt alustamisel.
Kokkuvõte
Päringute vaheltlõikamine ja vastuste vahemällu salvestamine on võimsad tehnikad, mis võivad oluliselt parandada veebirakenduste jõudlust ja kasutajakogemust. Service Workerite abil saate võrgupäringuid vahele lõigata, neid vastavalt vajadusele muuta ja vastuseid vahemällu salvestada võrguühenduseta funktsionaalsuse ja kiiremate laadimisaegade jaoks. Õigesti rakendatuna aitavad need tehnikad teil luua suure jõudlusega, globaalselt kättesaadavaid veebirakendusi, mis pakuvad sujuvat kasutajakogemust isegi keerulistes võrgutingimustes. Nende tehnikate rakendamisel arvestage kasutajate mitmekesiste võrgutingimuste ja andmesidekuludega üle maailma, et tagada optimaalne kättesaadavus ja kaasatus. Seadke alati esikohale turvalisus, et kaitsta tundlikke andmeid ja vältida haavatavusi.
Nende edasijõudnute Fetch API tehnikate valdamisega saate viia oma veebiarenduse oskused järgmisele tasemele ja luua tõeliselt erakordseid veebirakendusi.