Išnagrinėkite pažangius Express.js tarpinės programinės įrangos modelius, kad sukurtumėte tvirtas, mastelio keitimui pritaikytas ir prižiūrimas žiniatinklio programas, skirtas pasaulinei auditorijai. Sužinokite apie klaidų tvarkymą, autentifikavimą, užklausų ribojimą ir kt.
Express.js tarpinė programinė įranga: pažangių modelių įsisavinimas mastelio keitimui pritaikytoms programoms
Express.js – greita, neprimetanti nuomonės, minimalistinė Node.js žiniatinklio sistema – yra žiniatinklio programų ir API kūrimo pagrindas. Jos esmė – galinga tarpinės programinės įrangos koncepcija. Šis tinklaraščio įrašas gilinsis į pažangius tarpinės programinės įrangos modelius, suteikdamas jums žinių ir praktinių pavyzdžių, kaip kurti tvirtas, mastelio keitimui pritaikytas ir prižiūrimas programas, tinkamas pasaulinei auditorijai. Išnagrinėsime klaidų tvarkymo, autentifikavimo, autorizavimo, užklausų ribojimo ir kitus svarbius šiuolaikinių žiniatinklio programų kūrimo aspektus.
Tarpinės programinės įrangos supratimas: pagrindas
Tarpinės programinės įrangos funkcijos Express.js yra funkcijos, turinčios prieigą prie užklausos objekto (req
), atsakymo objekto (res
) ir kitos tarpinės programinės įrangos funkcijos programos užklausos-atsakymo cikle. Tarpinės programinės įrangos funkcijos gali atlikti įvairias užduotis, įskaitant:
- Bet kokio kodo vykdymą.
- Užklausos ir atsakymo objektų pakeitimų atlikimą.
- Užklausos-atsakymo ciklo užbaigimą.
- Kitos tarpinės programinės įrangos funkcijos iškvietimą.
Tarpinė programinė įranga iš esmės yra konvejeris. Kiekviena tarpinės programinės įrangos dalis atlieka savo specifinę funkciją, o tada, pasirinktinai, perduoda valdymą kitai tarpinei programinei įrangai grandinėje. Šis modulinis požiūris skatina kodo pakartotinį panaudojimą, atsakomybių atskyrimą ir švaresnę programos architektūrą.
Tarpinės programinės įrangos anatomija
Tipinė tarpinės programinės įrangos funkcija turi tokią struktūrą:
function myMiddleware(req, res, next) {
// Atlikti veiksmus
// Pavyzdys: registruoti užklausos informaciją
console.log(`Užklausa: ${req.method} ${req.url}`);
// Iškviesti kitą tarpinę programinę įrangą
next();
}
Funkcija next()
yra labai svarbi. Ji signalizuoja Express.js, kad dabartinė tarpinė programinė įranga baigė savo darbą ir valdymas turėtų būti perduotas kitai tarpinės programinės įrangos funkcijai. Jei next()
funkcija neiškviečiama, užklausa bus sustabdyta, o atsakymas niekada nebus išsiųstas.
Tarpinės programinės įrangos tipai
Express.js siūlo kelis tarpinės programinės įrangos tipus, kurių kiekvienas skirtas skirtingam tikslui:
- Programos lygio tarpinė programinė įranga: taikoma visiems maršrutams arba konkretiems maršrutams.
- Maršrutizatoriaus lygio tarpinė programinė įranga: taikoma maršrutams, apibrėžtiems maršrutizatoriaus egzemplioriuje.
- Klaidų tvarkymo tarpinė programinė įranga: specialiai sukurta klaidoms tvarkyti. Ji dedama *po* maršrutų apibrėžimų tarpinės programinės įrangos eilėje.
- Integruota tarpinė programinė įranga: įtraukta Express.js (pvz.,
express.static
statiniams failams pateikti). - Trečiųjų šalių tarpinė programinė įranga: įdiegta iš npm paketų (pvz., body-parser, cookie-parser).
Pažangūs tarpinės programinės įrangos modeliai
Panagrinėkime keletą pažangių modelių, kurie gali žymiai pagerinti jūsų Express.js programos funkcionalumą, saugumą ir prižiūrimumą.
1. Klaidų tvarkymo tarpinė programinė įranga
Efektyvus klaidų tvarkymas yra būtinas kuriant patikimas programas. Express.js siūlo specialią klaidų tvarkymo tarpinės programinės įrangos funkciją, kuri dedama *paskutinė* tarpinės programinės įrangos eilėje. Ši funkcija priima keturis argumentus: (err, req, res, next)
.
Štai pavyzdys:
// Klaidų tvarkymo tarpinė programinė įranga
app.use((err, req, res, next) => {
console.error(err.stack); // Registruoti klaidą derinimo tikslais
res.status(500).send('Kažkas sugedo!'); // Atsakyti su atitinkamu būsenos kodu
});
Svarbiausi klaidų tvarkymo aspektai:
- Klaidų registravimas: Naudokite registravimo biblioteką (pvz., Winston, Bunyan), kad įrašytumėte klaidas derinimo ir stebėjimo tikslais. Apsvarstykite galimybę registruoti skirtingus svarbos lygius (pvz.,
error
,warn
,info
,debug
). - Būsenos kodai: Grąžinkite tinkamus HTTP būsenos kodus (pvz., 400 – bloga užklausa, 401 – neautorizuota, 500 – vidinė serverio klaida), kad praneštumėte klientui apie klaidos pobūdį.
- Klaidų pranešimai: Pateikite informatyvius, tačiau saugius klaidų pranešimus klientui. Venkite atskleisti jautrią informaciją atsakyme. Apsvarstykite galimybę naudoti unikalų klaidos kodą problemoms sekti viduje, grąžinant bendrinį pranešimą vartotojui.
- Centralizuotas klaidų tvarkymas: Grupuokite klaidų tvarkymą specialioje tarpinės programinės įrangos funkcijoje, siekdami geresnės organizacijos ir prižiūrimumo. Sukurkite pasirinktines klaidų klases skirtingiems klaidų scenarijams.
2. Autentifikavimo ir autorizavimo tarpinė programinė įranga
Saugoti savo API ir apsaugoti jautrius duomenis yra labai svarbu. Autentifikavimas patvirtina vartotojo tapatybę, o autorizavimas nustato, ką vartotojui leidžiama daryti.
Autentifikavimo strategijos:
- JSON žiniatinklio ženklai (JWT): Populiarus be būsenos autentifikavimo metodas, tinkamas API. Serveris išduoda JWT klientui sėkmingai prisijungus. Vėliau klientas įtraukia šį ženklą į vėlesnes užklausas. Dažnai naudojamos bibliotekos, tokios kaip
jsonwebtoken
. - Sesijos: Vartotojų sesijų palaikymas naudojant slapukus. Tai tinka žiniatinklio programoms, tačiau gali būti mažiau pritaikoma mastelio keitimui nei JWT. Bibliotekos, tokios kaip
express-session
, palengvina sesijų valdymą. - OAuth 2.0: Plačiai paplitęs standartas deleguotam autorizavimui, leidžiantis vartotojams suteikti prieigą prie savo išteklių nesidalinant savo prisijungimo duomenimis tiesiogiai (pvz., prisijungiant per Google, Facebook ir kt.). Įgyvendinkite OAuth srautą naudodami bibliotekas, tokias kaip
passport.js
su specifinėmis OAuth strategijomis.
Autorizavimo strategijos:
- Vaidmenimis pagrįsta prieigos kontrolė (RBAC): Priskirkite vaidmenis (pvz., administratorius, redaktorius, vartotojas) vartotojams ir suteikite leidimus pagal šiuos vaidmenis.
- Atributais pagrįsta prieigos kontrolė (ABAC): Lankstesnis požiūris, kuris naudoja vartotojo, ištekliaus ir aplinkos atributus prieigai nustatyti.
Pavyzdys (JWT autentifikavimas):
const jwt = require('jsonwebtoken');
const secretKey = 'JŪSŲ_SLAPTAS_RAKTAS'; // Pakeiskite stipriu, aplinkos kintamuoju pagrįstu raktu
// Tarpinė programinė įranga JWT ženklams patikrinti
function authenticateToken(req, res, next) {
const authHeader = req.headers['authorization'];
const token = authHeader && authHeader.split(' ')[1];
if (token == null) return res.sendStatus(401); // Neautorizuota
jwt.verify(token, secretKey, (err, user) => {
if (err) return res.sendStatus(403); // Uždrausta
req.user = user; // Pridėti vartotojo duomenis prie užklausos
next();
});
}
// Pavyzdinis maršrutas, apsaugotas autentifikavimu
app.get('/profile', authenticateToken, (req, res) => {
res.json({ message: `Sveiki, ${req.user.username}` });
});
Svarbūs saugumo aspektai:
- Saugus prisijungimo duomenų saugojimas: Niekada nesaugokite slaptažodžių atviru tekstu. Naudokite stiprius slaptažodžių maišos algoritmus, tokius kaip bcrypt ar Argon2.
- HTTPS: Visada naudokite HTTPS, kad šifruotumėte ryšį tarp kliento ir serverio.
- Įvesties tikrinimas: Tikrinkite visą vartotojo įvestį, kad išvengtumėte saugumo pažeidžiamumų, tokių kaip SQL injekcija ir tarpvietinis scenarijų rašymas (XSS).
- Reguliarūs saugumo auditai: Atlikite reguliarius saugumo auditus, kad nustatytumėte ir pašalintumėte galimus pažeidžiamumus.
- Aplinkos kintamieji: Saugokite jautrią informaciją (API raktus, duomenų bazės prisijungimo duomenis, slaptus raktus) kaip aplinkos kintamuosius, o ne įrašydami juos į kodą. Tai palengvina konfigūracijos valdymą ir skatina geriausias saugumo praktikas.
3. Užklausų ribojimo tarpinė programinė įranga
Užklausų ribojimas apsaugo jūsų API nuo piktnaudžiavimo, pavyzdžiui, paslaugos trikdymo (DoS) atakų ir pernelyg didelio išteklių naudojimo. Jis apriboja užklausų, kurias klientas gali pateikti per tam tikrą laiko tarpą, skaičių.
Užklausų ribojimui dažnai naudojamos bibliotekos, tokios kaip express-rate-limit
. Taip pat apsvarstykite paketą helmet
, kuris apima pagrindinę užklausų ribojimo funkciją bei daugybę kitų saugumo patobulinimų.
Pavyzdys (naudojant express-rate-limit):
const rateLimit = require('express-rate-limit');
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minučių
max: 100, // Apriboti kiekvieną IP iki 100 užklausų per windowMs
message: 'Per daug užklausų iš šio IP adreso, bandykite dar kartą po 15 minučių',
});
// Pritaikyti užklausų ribojimą konkretiems maršrutams
app.use('/api/', limiter);
// Arba pritaikyti visiems maršrutams (paprastai mažiau pageidautina, nebent visas srautas turėtų būti traktuojamas vienodai)
// app.use(limiter);
Užklausų ribojimo pritaikymo parinktys apima:
- IP adresu pagrįstas užklausų ribojimas: Dažniausias metodas.
- Vartotoju pagrįstas užklausų ribojimas: Reikalauja vartotojo autentifikavimo.
- Užklausos metodu pagrįstas užklausų ribojimas: Apriboti konkrečius HTTP metodus (pvz., POST užklausas).
- Pasirinktinis saugojimas: Saugokite užklausų ribojimo informaciją duomenų bazėje (pvz., Redis, MongoDB), kad būtų geriau pritaikoma mastelio keitimui keliuose serverio egzemplioriuose.
4. Užklausos turinio analizavimo tarpinė programinė įranga
Express.js pagal nutylėjimą neanalizuoja užklausos turinio. Jums reikės naudoti tarpinę programinę įrangą, kad apdorotumėte skirtingus turinio formatus, tokius kaip JSON ir URL koduoti duomenys. Nors senesnėse implementacijose galėjo būti naudojami paketai, tokie kaip `body-parser`, dabartinė geriausia praktika yra naudoti Express integruotą tarpinę programinę įrangą, prieinamą nuo Express v4.16.
Pavyzdys (naudojant integruotą tarpinę programinę įrangą):
app.use(express.json()); // Analizuoja JSON koduotus užklausų turinius
app.use(express.urlencoded({ extended: true })); // Analizuoja URL koduotus užklausų turinius
express.json()
tarpinė programinė įranga analizuoja gaunamas užklausas su JSON turiniu ir padaro išanalizuotus duomenis prieinamus req.body
. express.urlencoded()
tarpinė programinė įranga analizuoja gaunamas užklausas su URL koduotu turiniu. Parinktis { extended: true }
leidžia analizuoti sudėtingus objektus ir masyvus.
5. Registravimo tarpinė programinė įranga
Efektyvus registravimas yra būtinas derinant, stebint ir audituojant jūsų programą. Tarpinė programinė įranga gali perimti užklausas ir atsakymus, kad registruotų atitinkamą informaciją.
Pavyzdys (paprasta registravimo tarpinė programinė įranga):
const morgan = require('morgan'); // Populiarus HTTP užklausų registratorius
app.use(morgan('dev')); // Registruoti užklausas 'dev' formatu
// Kitas pavyzdys, pasirinktinis formatavimas
app.use((req, res, next) => {
console.log(`${req.method} ${req.url} - ${new Date().toISOString()}`);
next();
});
Gamybinėms aplinkoms apsvarstykite galimybę naudoti patikimesnę registravimo biblioteką (pvz., Winston, Bunyan) su šiomis funkcijomis:
- Registravimo lygiai: Naudokite skirtingus registravimo lygius (pvz.,
debug
,info
,warn
,error
), kad kategorizuotumėte žurnalų įrašus pagal jų svarbą. - Žurnalų rotacija: Įdiekite žurnalų rotaciją, kad valdytumėte žurnalų failų dydį ir išvengtumėte disko vietos problemų.
- Centralizuotas registravimas: Siųskite žurnalus į centralizuotą registravimo paslaugą (pvz., ELK rinkinys (Elasticsearch, Logstash, Kibana), Splunk), kad būtų lengviau stebėti ir analizuoti.
6. Užklausų tikrinimo tarpinė programinė įranga
Tikrinkite gaunamas užklausas, kad užtikrintumėte duomenų vientisumą ir išvengtumėte netikėto elgesio. Tai gali apimti užklausos antraščių, užklausos parametrų ir užklausos turinio duomenų tikrinimą.
Bibliotekos užklausų tikrinimui:
- Joi: Galinga ir lanksti tikrinimo biblioteka, skirta schemoms apibrėžti ir duomenims tikrinti.
- Ajv: Greitas JSON schemos tikrintuvas.
- Express-validator: Rinkinys express tarpinės programinės įrangos, apgaubiančios validator.js, kad būtų lengva naudoti su Express.
Pavyzdys (naudojant Joi):
const Joi = require('joi');
const userSchema = Joi.object({
username: Joi.string().min(3).max(30).required(),
email: Joi.string().email().required(),
password: Joi.string().min(6).required(),
});
function validateUser(req, res, next) {
const { error } = userSchema.validate(req.body, { abortEarly: false }); // Nustatykite abortEarly į false, kad gautumėte visas klaidas
if (error) {
return res.status(400).json({ errors: error.details.map(err => err.message) }); // Grąžinti išsamius klaidų pranešimus
}
next();
}
app.post('/users', validateUser, (req, res) => {
// Vartotojo duomenys yra teisingi, tęsti su vartotojo kūrimu
res.status(201).json({ message: 'Vartotojas sėkmingai sukurtas' });
});
Geriausios praktikos užklausų tikrinimui:
- Schemomis pagrįstas tikrinimas: Apibrėžkite schemas, kad nurodytumėte numatomą jūsų duomenų struktūrą ir tipus.
- Klaidų tvarkymas: Grąžinkite informatyvius klaidų pranešimus klientui, kai tikrinimas nepavyksta.
- Įvesties valymas: Valykite vartotojo įvestį, kad išvengtumėte pažeidžiamumų, tokių kaip tarpvietinis scenarijų rašymas (XSS). Kol įvesties tikrinimas sutelktas į tai, *kas* yra priimtina, valymas sutelktas į tai, *kaip* įvestis yra pateikiama, kad būtų pašalinti žalingi elementai.
- Centralizuotas tikrinimas: Kurkite pakartotinai naudojamas tikrinimo tarpinės programinės įrangos funkcijas, kad išvengtumėte kodo dubliavimo.
7. Atsakymo suspaudimo tarpinė programinė įranga
Pagerinkite savo programos našumą suspausdami atsakymus prieš siunčiant juos klientui. Tai sumažina perduodamų duomenų kiekį, todėl įkėlimo laikas sutrumpėja.
Pavyzdys (naudojant suspaudimo tarpinę programinę įrangą):
const compression = require('compression');
app.use(compression()); // Įjungti atsakymų suspaudimą (pvz., gzip)
compression
tarpinė programinė įranga automatiškai suspaudžia atsakymus naudojant gzip arba deflate, atsižvelgiant į kliento Accept-Encoding
antraštę. Tai ypač naudinga teikiant statinius išteklius ir didelius JSON atsakymus.
8. CORS (skirtingų šaltinių išteklių dalijimosi) tarpinė programinė įranga
Jei jūsų API ar žiniatinklio programa turi priimti užklausas iš skirtingų domenų (šaltinių), jums reikės konfigūruoti CORS. Tai apima atitinkamų HTTP antraščių nustatymą, kad būtų leidžiamos skirtingų šaltinių užklausos.
Pavyzdys (naudojant CORS tarpinę programinę įrangą):
const cors = require('cors');
const corsOptions = {
origin: 'https://jusu-leidziamas-domenas.com',
methods: 'GET,POST,PUT,DELETE',
allowedHeaders: 'Content-Type,Authorization'
};
app.use(cors(corsOptions));
// ARBA leisti visus šaltinius (kūrimo ar vidinėms API - naudoti atsargiai!)
// app.use(cors());
Svarbūs CORS aspektai:
- Šaltinis: Nurodykite leidžiamus šaltinius (domenus), kad išvengtumėte neautorizuotos prieigos. Paprastai saugiau yra įtraukti konkrečius šaltinius į baltąjį sąrašą, nei leisti visus šaltinius (
*
). - Metodai: Apibrėžkite leidžiamus HTTP metodus (pvz., GET, POST, PUT, DELETE).
- Antraštės: Nurodykite leidžiamas užklausos antraštes.
- Parengiamosios užklausos (Preflight Requests): Sudėtingoms užklausoms (pvz., su pasirinktinėmis antraštėmis ar metodais, išskyrus GET, POST, HEAD) naršyklė išsiųs parengiamąją užklausą (OPTIONS), kad patikrintų, ar tikroji užklausa yra leidžiama. Serveris turi atsakyti su atitinkamomis CORS antraštėmis, kad parengiamoji užklausa būtų sėkminga.
9. Statinių failų pateikimas
Express.js siūlo integruotą tarpinę programinę įrangą statiniams failams (pvz., HTML, CSS, JavaScript, paveikslėliams) pateikti. Tai paprastai naudojama programos priekinės dalies (front-end) pateikimui.
Pavyzdys (naudojant express.static):
app.use(express.static('public')); // Pateikti failus iš 'public' katalogo
Dėkite savo statinius išteklius į public
katalogą (ar bet kurį kitą nurodytą katalogą). Tada Express.js automatiškai pateiks šiuos failus pagal jų failų kelius.
10. Pasirinktinė tarpinė programinė įranga specifinėms užduotims
Be aptartų modelių, galite kurti pasirinktinę tarpinę programinę įrangą, pritaikytą specifiniams jūsų programos poreikiams. Tai leidžia jums apgaubti sudėtingą logiką ir skatinti kodo pakartotinį panaudojimą.
Pavyzdys (pasirinktinė tarpinė programinė įranga funkcijų vėliavoms):
// Pasirinktinė tarpinė programinė įranga, skirta įjungti/išjungti funkcijas pagal konfigūracijos failą
const featureFlags = require('./config/feature-flags.json');
function featureFlagMiddleware(featureName) {
return (req, res, next) => {
if (featureFlags[featureName] === true) {
next(); // Funkcija įjungta, tęsti
} else {
res.status(404).send('Funkcija nepasiekiama'); // Funkcija išjungta
}
};
}
// Naudojimo pavyzdys
app.get('/new-feature', featureFlagMiddleware('newFeatureEnabled'), (req, res) => {
res.send('Tai yra nauja funkcija!');
});
Šis pavyzdys demonstruoja, kaip naudoti pasirinktinę tarpinę programinę įrangą, norint kontroliuoti prieigą prie konkrečių maršrutų, remiantis funkcijų vėliavomis. Tai leidžia kūrėjams kontroliuoti funkcijų išleidimą nekeičiant ir nediegiant kodo, kuris dar nėra visiškai patikrintas – tai įprasta praktika programinės įrangos kūrime.
Geriausios praktikos ir aspektai pasaulinėms programoms
- Našumas: Optimizuokite savo tarpinę programinę įrangą našumui, ypač didelio srauto programose. Sumažinkite CPU reikalaujančių operacijų naudojimą. Apsvarstykite galimybę naudoti spartinimo strategijas.
- Mastelio keitimas: Projektuokite savo tarpinę programinę įrangą taip, kad ją būtų galima keisti horizontaliai. Venkite saugoti sesijos duomenis atmintyje; naudokite paskirstytąją talpyklą, pvz., Redis ar Memcached.
- Saugumas: Įgyvendinkite geriausias saugumo praktikas, įskaitant įvesties tikrinimą, autentifikavimą, autorizavimą ir apsaugą nuo įprastų žiniatinklio pažeidžiamumų. Tai ypač svarbu, atsižvelgiant į jūsų auditorijos tarptautiškumą.
- Prižiūrimumas: Rašykite švarų, gerai dokumentuotą ir modulinį kodą. Naudokite aiškius pavadinimų susitarimus ir laikykitės nuoseklaus kodavimo stiliaus. Modulizuokite savo tarpinę programinę įrangą, kad palengvintumėte priežiūrą ir atnaujinimus.
- Testuojamumas: Rašykite vienetų ir integracijos testus savo tarpinei programinei įrangai, kad užtikrintumėte, jog ji veikia teisingai ir anksti aptiktumėte galimas klaidas. Testuokite savo tarpinę programinę įrangą įvairiose aplinkose.
- Internacionalizavimas (i18n) ir lokalizavimas (l10n): Apsvarstykite internacionalizavimą ir lokalizavimą, jei jūsų programa palaiko kelias kalbas ar regionus. Pateikite lokalizuotus klaidų pranešimus, turinį ir formatavimą, kad pagerintumėte vartotojo patirtį. Sistemos, tokios kaip i18next, gali palengvinti i18n pastangas.
- Laiko juostos ir datos/laiko tvarkymas: Atkreipkite dėmesį į laiko juostas ir atsargiai tvarkykite datos/laiko duomenis, ypač dirbant su pasauline auditorija. Naudokite bibliotekas, tokias kaip Moment.js ar Luxon, datos/laiko manipuliavimui arba, pageidautina, naujesnį Javascript integruotą Date objekto tvarkymą su laiko juostų palaikymu. Saugokite datas/laikus UTC formatu savo duomenų bazėje ir konvertuokite juos į vartotojo vietinę laiko juostą, kai juos rodote.
- Valiutų tvarkymas: Jei jūsų programa susijusi su finansinėmis operacijomis, teisingai tvarkykite valiutas. Naudokite tinkamą valiutos formatavimą ir apsvarstykite galimybę palaikyti kelias valiutas. Užtikrinkite, kad jūsų duomenys būtų nuosekliai ir tiksliai tvarkomi.
- Teisinis ir reguliavimo atitikimas: Būkite informuoti apie teisinius ir reguliavimo reikalavimus skirtingose šalyse ar regionuose (pvz., BDAR, CCPA). Įgyvendinkite būtinas priemones, kad atitiktumėte šiuos reglamentus.
- Prieinamumas: Užtikrinkite, kad jūsų programa būtų prieinama vartotojams su negalia. Laikykitės prieinamumo gairių, tokių kaip WCAG (Web Content Accessibility Guidelines).
- Stebėjimas ir perspėjimas: Įgyvendinkite išsamų stebėjimą ir perspėjimą, kad greitai aptiktumėte ir reaguotumėte į problemas. Stebėkite serverio našumą, programos klaidas ir saugumo grėsmes.
Išvada
Pažangių tarpinės programinės įrangos modelių įsisavinimas yra labai svarbus kuriant tvirtas, saugias ir mastelio keitimui pritaikytas Express.js programas. Efektyviai naudodami šiuos modelius, galite kurti programas, kurios yra ne tik funkcionalios, bet ir prižiūrimos bei tinkamos pasaulinei auditorijai. Nepamirškite teikti pirmenybės saugumui, našumui ir prižiūrimumui visame kūrimo procese. Kruopščiai planuodami ir įgyvendindami, galite išnaudoti Express.js tarpinės programinės įrangos galią kurdami sėkmingas žiniatinklio programas, atitinkančias vartotojų poreikius visame pasaulyje.
Papildoma literatūra: