Išnagrinėkite Next.js tarpinę programinę įrangą – galingą funkciją, skirtą perimti ir modifikuoti gaunamas užklausas. Sužinokite, kaip įdiegti autentifikavimą, autorizavimą, peradresavimą ir A/B testavimą, pasitelkiant praktinius pavyzdžius.
Next.js tarpinė programinė įranga (Middleware): užklausų perėmimo įvaldymas dinamiškoms programoms
Next.js tarpinė programinė įranga (middleware) suteikia lankstų ir galingą būdą perimti ir modifikuoti gaunamas užklausas, prieš joms pasiekiant maršrutus. Ši galimybė leidžia įgyvendinti platų funkcijų spektrą – nuo autentifikavimo ir autorizavimo iki peradresavimo ir A/B testavimo, visa tai optimizuojant našumą. Šis išsamus vadovas supažindins jus su pagrindinėmis Next.js tarpinės programinės įrangos koncepcijomis ir parodys, kaip ją efektyviai panaudoti.
Kas yra Next.js tarpinė programinė įranga (Middleware)?
Tarpinė programinė įranga (middleware) Next.js aplinkoje yra funkcija, kuri vykdoma prieš užklausos užbaigimą. Ji leidžia jums:
- Perimti užklausas: Išnagrinėti gaunamos užklausos antraštes, slapukus ir URL.
- Modifikuoti užklausas: Perrašyti URL, nustatyti antraštes ar peradresuoti vartotojus pagal konkrečius kriterijus.
- Vykdyti kodą: Vykdyti serverio pusės logiką prieš atvaizduojant puslapį.
Tarpinės programinės įrangos funkcijos apibrėžiamos middleware.ts
(arba middleware.js
) faile, esančiame jūsų projekto šakninėje direktorijoje. Jos vykdomos kiekvienam maršrutui jūsų programoje arba konkretiems maršrutams, remiantis konfigūruojamais atitikmenimis (matchers).
Pagrindinės sąvokos ir privalumai
Užklausos objektas (Request Object)
request
objektas suteikia prieigą prie informacijos apie gaunamą užklausą, įskaitant:
request.url
: Pilnas užklausos URL.request.method
: HTTP metodas (pvz., GET, POST).request.headers
: Objektas, kuriame yra užklausos antraštės.request.cookies
: Objektas, atspindintis užklausos slapukus.request.geo
: Pateikia su užklausa susijusius geografinės vietos duomenis, jei jie yra prieinami.
Atsakymo objektas (Response Object)
Tarpinės programinės įrangos funkcijos grąžina Response
objektą, kad valdytų užklausos rezultatą. Galite naudoti šiuos atsakymus:
NextResponse.next()
: Tęsia užklausos apdorojimą įprastai, leisdamas jai pasiekti numatytą maršrutą.NextResponse.redirect(url)
: Peradresuoja vartotoją į kitą URL.NextResponse.rewrite(url)
: Perrašo užklausos URL, efektyviai pateikdamas kitą puslapį be peradresavimo. URL naršyklėje lieka tas pats.- Grąžinant pasirinktinį
Response
objektą: Leidžia pateikti pasirinktinį turinį, pavyzdžiui, klaidos puslapį arba konkretų JSON atsakymą.
Atitikmenys (Matchers)
Atitikmenys (matchers) leidžia nurodyti, kuriems maršrutams turėtų būti taikoma jūsų tarpinė programinė įranga. Galite apibrėžti atitikmenis naudodami reguliarias išraiškas arba kelio šablonus. Tai užtikrina, kad jūsų tarpinė programinė įranga veiks tik tada, kai to reikia, pagerindama našumą ir sumažindama pridėtines išlaidas.
Edge Runtime
Next.js tarpinė programinė įranga veikia Edge Runtime aplinkoje, kuri yra lengvasvorė JavaScript vykdymo aplinka, galinti būti įdiegta arti jūsų vartotojų. Šis artumas sumažina delsą ir pagerina bendrą jūsų programos našumą, ypač globaliai paskirstytiems vartotojams. Edge Runtime yra prieinama Vercel Edge tinkle ir kitose suderinamose platformose. Edge Runtime turi tam tikrų apribojimų, ypač susijusių su Node.js API naudojimu.
Praktiniai pavyzdžiai: tarpinės programinės įrangos funkcijų įgyvendinimas
1. Autentifikavimas
Autentifikavimo tarpinė programinė įranga gali būti naudojama apsaugoti maršrutus, kuriems reikalingas prisijungęs vartotojas. Štai pavyzdys, kaip įgyvendinti autentifikavimą naudojant slapukus:
// middleware.ts
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
export function middleware(request: NextRequest) {
const token = request.cookies.get('auth_token');
if (!token) {
return NextResponse.redirect(new URL('/login', request.url))
}
return NextResponse.next()
}
export const config = {
matcher: ['/dashboard/:path*'],
}
Ši tarpinė programinė įranga tikrina, ar yra auth_token
slapukas. Jei slapukas nerandamas, vartotojas peradresuojamas į /login
puslapį. config.matcher
nurodo, kad ši tarpinė programinė įranga turėtų veikti tik maršrutams, esantiems po /dashboard
.
Globali perspektyva: Pritaikykite autentifikavimo logiką, kad palaikytumėte įvairius autentifikavimo metodus (pvz., OAuth, JWT) ir integruotumėte su skirtingais tapatybės teikėjais (pvz., Google, Facebook, Azure AD), kad atitiktumėte vartotojų iš įvairių regionų poreikius.
2. Autorizavimas
Autorizavimo tarpinė programinė įranga gali būti naudojama kontroliuoti prieigą prie išteklių, atsižvelgiant į vartotojo vaidmenis ar leidimus. Pavyzdžiui, galite turėti administratoriaus skydelį, prie kurio gali prisijungti tik tam tikri vartotojai.
// middleware.ts
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
export async function middleware(request: NextRequest) {
const token = request.cookies.get('auth_token');
if (!token) {
return NextResponse.redirect(new URL('/login', request.url))
}
// Pavyzdys: gaunami vartotojo vaidmenys iš API (pakeiskite savo realia logika)
const userResponse = await fetch('https://api.example.com/userinfo', {
headers: {
Authorization: `Bearer ${token}`,
},
});
const userData = await userResponse.json();
if (userData.role !== 'admin') {
return NextResponse.redirect(new URL('/unauthorized', request.url))
}
return NextResponse.next()
}
export const config = {
matcher: ['/admin/:path*'],
}
Ši tarpinė programinė įranga gauna vartotojo vaidmenį ir tikrina, ar jis turi admin
vaidmenį. Jei ne, jis peradresuojamas į /unauthorized
puslapį. Šiame pavyzdyje naudojamas pakaitalo API galinis taškas. Pakeiskite `https://api.example.com/userinfo` savo tikruoju autentifikavimo serverio galiniu tašku.
Globali perspektyva: Tvarkydami vartotojo duomenis, atsižvelkite į duomenų privatumo reglamentus (pvz., GDPR, CCPA). Įgyvendinkite tinkamas saugumo priemones, kad apsaugotumėte jautrią informaciją ir užtikrintumėte atitiktį vietiniams įstatymams.
3. Peradresavimas
Peradresavimo tarpinė programinė įranga gali būti naudojama peradresuoti vartotojus pagal jų vietą, kalbą ar kitus kriterijus. Pavyzdžiui, galite peradresuoti vartotojus į lokalizuotą svetainės versiją pagal jų IP adresą.
// middleware.ts
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
export function middleware(request: NextRequest) {
const country = request.geo?.country || 'US'; // Jei geografinės vietos nustatymas nepavyksta, numatytoji reikšmė yra JAV
if (country === 'DE') {
return NextResponse.redirect(new URL('/de', request.url))
}
if (country === 'FR') {
return NextResponse.redirect(new URL('/fr', request.url))
}
return NextResponse.next()
}
export const config = {
matcher: ['/'],
}
Ši tarpinė programinė įranga tikrina vartotojo šalį pagal jo IP adresą ir peradresuoja jį į atitinkamą lokalizuotą svetainės versiją (/de
Vokietijai, /fr
Prancūzijai). Jei geografinės vietos nustatymas nepavyksta, ji grįžta prie JAV versijos. Atkreipkite dėmesį, kad tai priklauso nuo to, ar yra prieinama geo savybė (pvz., kai įdiegta Vercel platformoje).
Globali perspektyva: Užtikrinkite, kad jūsų svetainė palaiko kelias kalbas ir valiutas. Suteikite vartotojams galimybę rankiniu būdu pasirinkti pageidaujamą kalbą ar regioną. Naudokite atitinkamus datos ir laiko formatus kiekvienai lokalizacijai.
4. A/B testavimas
Tarpinė programinė įranga gali būti naudojama įgyvendinti A/B testavimą, atsitiktinai priskiriant vartotojus skirtingiems puslapio variantams ir stebint jų elgseną. Štai supaprastintas pavyzdys:
// middleware.ts
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
function getRandomVariant() {
return Math.random() < 0.5 ? 'A' : 'B';
}
export function middleware(request: NextRequest) {
let variant = request.cookies.get('variant')?.value;
if (!variant) {
variant = getRandomVariant();
const response = NextResponse.next();
response.cookies.set('variant', variant);
return response;
}
if (variant === 'B') {
return NextResponse.rewrite(new URL('/variant-b', request.url));
}
return NextResponse.next();
}
export const config = {
matcher: ['/'],
}
Ši tarpinė programinė įranga priskiria vartotojus variantui 'A' arba 'B'. Jei vartotojas dar neturi variant
slapuko, vienas yra atsitiktinai priskiriamas ir nustatomas. Vartotojai, priskirti 'B' variantui, yra perrašomi į /variant-b
puslapį. Tada stebėtumėte kiekvieno varianto našumą, kad nustatytumėte, kuris yra efektyvesnis.
Globali perspektyva: Kurdami A/B testus, atsižvelkite į kultūrinius skirtumus. Tai, kas gerai veikia viename regione, gali neatitikti vartotojų lūkesčių kitame. Užtikrinkite, kad jūsų A/B testavimo platforma atitinka privatumo reglamentus skirtinguose regionuose.
5. Funkcijų vėliavėlės
Funkcijų vėliavėlės leidžia įjungti arba išjungti funkcijas jūsų programoje, nediegiant naujo kodo. Tarpinė programinė įranga gali būti naudojama nustatyti, ar vartotojas turėtų turėti prieigą prie konkrečios funkcijos, atsižvelgiant į jo vartotojo ID, vietą ar kitus kriterijus.
// middleware.ts
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
export async function middleware(request: NextRequest) {
// Pavyzdys: gaunamos funkcijų vėliavėlės iš API
const featureFlagsResponse = await fetch('https://api.example.com/featureflags', {
headers: {
'X-User-Id': 'user123',
},
});
const featureFlags = await featureFlagsResponse.json();
if (featureFlags.new_feature_enabled) {
// Įjungti naują funkciją
return NextResponse.next();
} else {
// Išjungti naują funkciją (pvz., peradresuoti į alternatyvų puslapį)
return NextResponse.redirect(new URL('/alternative-page', request.url));
}
}
export const config = {
matcher: ['/new-feature'],
}
Ši tarpinė programinė įranga gauna funkcijų vėliavėles iš API ir tikrina, ar nustatyta new_feature_enabled
vėliavėlė. Jei taip, vartotojas gali pasiekti /new-feature
puslapį. Kitu atveju, jis peradresuojamas į /alternative-page
.
Globali perspektyva: Naudokite funkcijų vėliavėles, kad palaipsniui diegtumėte naujas funkcijas vartotojams skirtinguose regionuose. Tai leidžia stebėti našumą ir spręsti bet kokias problemas prieš išleidžiant funkciją platesnei auditorijai. Taip pat užtikrinkite, kad jūsų funkcijų vėliavėlių sistema veiktų globaliai ir teiktų nuoseklius rezultatus, nepriklausomai nuo vartotojo vietos. Apsvarstykite regioninius reguliavimo apribojimus funkcijų diegimui.
Pažangios technikos
Tarpinės programinės įrangos grandinė (Chaining Middleware)
Galite sujungti kelias tarpinės programinės įrangos funkcijas į grandinę, kad atliktumėte eilę operacijų su užklausa. Tai gali būti naudinga, skaidant sudėtingą logiką į mažesnius, lengviau valdomus modulius.
// middleware.ts
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
export function middleware(request: NextRequest) {
const response = NextResponse.next();
// Pirmoji tarpinės programinės įrangos funkcija
const token = request.cookies.get('auth_token');
if (!token) {
return NextResponse.redirect(new URL('/login', request.url))
}
// Antroji tarpinės programinės įrangos funkcija
response.headers.set('x-middleware-custom', 'value');
return response;
}
export const config = {
matcher: ['/dashboard/:path*'],
}
Šis pavyzdys rodo dvi tarpines programines įrangas vienoje. Pirmoji atlieka autentifikavimą, o antroji nustato pasirinktinę antraštę.
Aplinkos kintamųjų naudojimas
Saugokite jautrią informaciją, pvz., API raktus ir duomenų bazės prisijungimo duomenis, aplinkos kintamuosiuose, o ne koduokite juos tiesiogiai savo tarpinės programinės įrangos funkcijose. Tai pagerina saugumą ir palengvina jūsų programos konfigūracijos valdymą.
// middleware.ts
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
const API_KEY = process.env.API_KEY;
export async function middleware(request: NextRequest) {
const response = await fetch('https://api.example.com/data', {
headers: {
'X-API-Key': API_KEY,
},
});
// ...
}
export const config = {
matcher: ['/data'],
}
Šiame pavyzdyje API_KEY
yra gaunamas iš aplinkos kintamojo.
Klaidų apdorojimas
Įgyvendinkite patikimą klaidų apdorojimą savo tarpinės programinės įrangos funkcijose, kad išvengtumėte netikėtų klaidų, kurios galėtų sutrikdyti jūsų programos veikimą. Naudokite try...catch
blokus, kad pagautumėte išimtis ir tinkamai registruotumėte klaidas.
// middleware.ts
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
export async function middleware(request: NextRequest) {
try {
const response = await fetch('https://api.example.com/data');
// ...
} catch (error) {
console.error('Error fetching data:', error);
return NextResponse.error(); // Arba peradresuoti į klaidų puslapį
}
}
export const config = {
matcher: ['/data'],
}
Geroji praktika
- Tarpinės programinės įrangos funkcijos turi būti lengvos: Venkite atlikti skaičiavimais intensyvių operacijų tarpinėje programinėje įrangoje, nes tai gali paveikti našumą. Sudėtingą apdorojimą perkelkite į fonines užduotis arba dedikuotas paslaugas.
- Efektyviai naudokite atitikmenis (matchers): Taikykite tarpinę programinę įrangą tik tiems maršrutams, kuriems jos reikia.
- Kruopščiai testuokite savo tarpinę programinę įrangą: Rašykite vienetinius testus (unit tests), kad užtikrintumėte, jog jūsų tarpinės programinės įrangos funkcijos veikia teisingai.
- Stebėkite tarpinės programinės įrangos našumą: Naudokite stebėjimo įrankius, kad sektumėte savo tarpinės programinės įrangos funkcijų našumą ir nustatytumėte bet kokius kliuvinius.
- Dokumentuokite savo tarpinę programinę įrangą: Aiškiai dokumentuokite kiekvienos tarpinės programinės įrangos funkcijos paskirtį ir funkcionalumą.
- Atsižvelkite į Edge Runtime apribojimus: Žinokite apie Edge Runtime apribojimus, tokius kaip Node.js API nebuvimas. Atitinkamai koreguokite savo kodą.
Dažniausiai pasitaikančių problemų sprendimas
- Tarpinė programinė įranga neveikia: Dukart patikrinkite savo atitikmenų (matcher) konfigūraciją, kad įsitikintumėte, jog tarpinė programinė įranga taikoma teisingiems maršrutams.
- Našumo problemos: Nustatykite ir optimizuokite lėtai veikiančias tarpinės programinės įrangos funkcijas. Naudokite profiliavimo įrankius, kad nustatytumėte našumo kliuvinius.
- Edge Runtime suderinamumas: Užtikrinkite, kad jūsų kodas yra suderinamas su Edge Runtime. Venkite naudoti nepalaikomų Node.js API.
- Slapukų problemos: Patikrinkite, ar slapukai nustatomi ir gaunami teisingai. Atkreipkite dėmesį į slapukų atributus, tokius kaip
domain
,path
irsecure
. - Antraščių konfliktai: Būkite atidūs galimiems antraščių konfliktams, nustatydami pasirinktines antraštes tarpinėje programinėje įrangoje. Užtikrinkite, kad jūsų antraštės netyčia neperrašytų esamų antraščių.
Išvada
Next.js tarpinė programinė įranga yra galingas įrankis kuriant dinamiškas ir personalizuotas žiniatinklio programas. Įvaldę užklausų perėmimą, galite įgyvendinti platų funkcijų spektrą – nuo autentifikavimo ir autorizavimo iki peradresavimo ir A/B testavimo. Laikydamiesi šiame vadove pateiktų geriausių praktikų, galite panaudoti Next.js tarpinę programinę įrangą, kad sukurtumėte našias, saugias ir keičiamo dydžio programas, atitinkančias jūsų globalios vartotojų bazės poreikius. Pasinaudokite tarpinės programinės įrangos galia, kad atvertumėte naujas galimybes savo Next.js projektuose ir suteiktumėte išskirtinę vartotojo patirtį.