Ištirkite pažangias užklausų modifikavimo technikas naudojant Next.js tarpinę programinę įrangą. Išmokite valdyti sudėtingą maršrutizavimą, autentifikavimą, A/B testavimą ir lokalizacijos strategijas, skirtas patikimoms žiniatinklio programoms.
Next.js tarpinės programinės įrangos kraštutiniai atvejai: užklausų modifikavimo šablonų įvaldymas
Next.js tarpinė programinė įranga (angl. middleware) suteikia galingą mechanizmą, leidžiantį perimti ir modifikuoti užklausas prieš joms pasiekiant jūsų programos maršrutus. Ši galimybė atveria platų spektrą galimybių, nuo paprastų autentifikavimo patikrų iki sudėtingų A/B testavimo scenarijų ir internacionalizacijos strategijų. Tačiau, norint efektyviai išnaudoti tarpinę programinę įrangą, reikia gerai suprasti jos kraštutinius atvejus ir galimus spąstus. Šis išsamus vadovas nagrinėja pažangius užklausų modifikavimo šablonus, pateikdamas praktinių pavyzdžių ir veiksmingų įžvalgų, kurios padės jums kurti patikimas ir našias Next.js programas.
Next.js tarpinės programinės įrangos pagrindų supratimas
Prieš gilinantis į pažangius šablonus, apžvelkime Next.js tarpinės programinės įrangos pagrindus. Tarpinės programinės įrangos funkcijos vykdomos prieš užbaigiant užklausą, leidžiančios jums:
- URL perrašymas: Nukreipkite vartotojus į skirtingus puslapius pagal konkrečius kriterijus.
- Vartotojų peradresavimas: Nusiųskite vartotojus į visiškai skirtingus URL, dažnai autentifikavimo ar autorizacijos tikslais.
- Antraščių modifikavimas: Pridėkite, pašalinkite arba atnaujinkite HTTP antraštes.
- Tiesioginis atsakymas: Grąžinkite atsakymą tiesiai iš tarpinės programinės įrangos, aplenkiant Next.js maršrutus.
Tarpinės programinės įrangos funkcijos yra middleware.js
arba middleware.ts
faile, esančiame jūsų /pages
arba /app
kataloge (priklausomai nuo jūsų Next.js versijos ir sąrankos). Jos gauna NextRequest
objektą, atstovaujantį gaunamai užklausai, ir gali grąžinti NextResponse
objektą, kad valdytų tolimesnį elgesį.
Pavyzdys: pagrindinė autentifikavimo tarpinė programinė įranga
Šis pavyzdys demonstruoja paprastą autentifikavimo patikrinimą. Jei vartotojas nėra autentifikuotas (pvz., slapuke nėra galiojančio prieigos rakto), jis peradresuojamas į prisijungimo puslapį.
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
export function middleware(request: NextRequest) {
const authToken = request.cookies.get('authToken')
if (!authToken) {
return NextResponse.redirect(new URL('/login', request.url))
}
return NextResponse.next()
}
export const config = {
matcher: ['/protected/:path*'],
}
Ši tarpinė programinė įranga veiks tik maršrutams, kurie atitinka /protected/:path*
. Ji patikrina, ar yra authToken
slapukas. Jei slapuko trūksta, vartotojas peradresuojamas į /login
puslapį. Kitu atveju, užklausa leidžiama tęsti normaliai naudojant NextResponse.next()
.
Pažangūs užklausų modifikavimo šablonai
Dabar panagrinėkime keletą pažangių užklausų modifikavimo šablonų, kurie demonstruoja tikrąją Next.js tarpinės programinės įrangos galią.
1. A/B testavimas su slapukais
A/B testavimas yra esminė technika, skirta optimizuoti vartotojų patirtis. Tarpinė programinė įranga gali būti naudojama atsitiktinai priskirti vartotojus skirtingoms jūsų programos versijoms ir stebėti jų elgesį. Šis šablonas remiasi slapukais, kad išsaugotų vartotojui priskirtą variantą.
Pavyzdys: A/B testavimas nukreipimo puslapiui
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
const VARIANT_A = 'variantA'
const VARIANT_B = 'variantB'
export function middleware(request: NextRequest) {
let variant = request.cookies.get('variant')?.value
if (!variant) {
// Randomly assign a variant
variant = Math.random() < 0.5 ? VARIANT_A : VARIANT_B
const response = NextResponse.next()
response.cookies.set('variant', variant)
return response
}
if (variant === VARIANT_A) {
return NextResponse.rewrite(new URL('/variant-a', request.url))
} else if (variant === VARIANT_B) {
return NextResponse.rewrite(new URL('/variant-b', request.url))
}
return NextResponse.next()
}
export const config = {
matcher: ['/'],
}
Šiame pavyzdyje, kai vartotojas pirmą kartą apsilanko pagrindiniame kelyje (/
), tarpinė programinė įranga atsitiktinai priskiria jį arba variantA
, arba variantB
. Šis variantas yra išsaugomas slapuke. Vėlesnės to paties vartotojo užklausos bus perrašytos į /variant-a
arba /variant-b
, priklausomai nuo jiems priskirto varianto. Tai leidžia jums pateikti skirtingus nukreipimo puslapius ir stebėti, kuris iš jų veikia geriau. Įsitikinkite, kad jūsų Next.js programoje yra apibrėžti maršrutai /variant-a
ir /variant-b
.
Globalūs aspektai: Atliekant A/B testavimą, atsižvelkite į regioninius skirtumus. Dizainas, kuris rezonuoja Šiaurės Amerikoje, gali būti ne toks efektyvus Azijoje. Galite naudoti geolokacijos duomenis (gautus per IP adreso paiešką ar vartotojo nuostatas), kad pritaikytumėte A/B testą konkretiems regionams.
2. Lokalizacija (i18n) su URL perrašymu
Internacionalizacija (i18n) yra būtina norint pasiekti pasaulinę auditoriją. Tarpinė programinė įranga gali būti naudojama automatiškai nustatyti vartotojo pageidaujamą kalbą ir peradresuoti jį į atitinkamą lokalizuotą jūsų svetainės versiją.
Pavyzdys: Peradresavimas pagal `Accept-Language` antraštę
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
const SUPPORTED_LANGUAGES = ['en', 'fr', 'es', 'de']
const DEFAULT_LANGUAGE = 'en'
function getPreferredLanguage(request: NextRequest): string {
const acceptLanguage = request.headers.get('accept-language')
if (!acceptLanguage) {
return DEFAULT_LANGUAGE
}
const languages = acceptLanguage.split(',').map((lang) => lang.split(';')[0].trim())
for (const lang of languages) {
if (SUPPORTED_LANGUAGES.includes(lang)) {
return lang
}
}
return DEFAULT_LANGUAGE
}
export function middleware(request: NextRequest) {
const pathname = request.nextUrl.pathname
// Check if there's an existing locale in the pathname
if (
SUPPORTED_LANGUAGES.some(
(locale) => pathname.startsWith(`/${locale}/`) || pathname === `/${locale}`
)
) {
return NextResponse.next()
}
const preferredLanguage = getPreferredLanguage(request)
return NextResponse.redirect(
new URL(`/${preferredLanguage}${pathname}`, request.url)
)
}
export const config = {
matcher: [
'/((?!api|_next/static|_next/image|favicon.ico).*)'
],
}
Ši tarpinė programinė įranga išgauna Accept-Language
antraštę iš užklausos ir nustato vartotojo pageidaujamą kalbą. Jei URL adrese dar nėra kalbos priešdėlio (pvz., /en/about
), tarpinė programinė įranga peradresuoja vartotoją į atitinkamą lokalizuotą URL (pvz., /fr/about
prancūzų kalbai). Įsitikinkite, kad jūsų /pages
arba /app
kataloge yra tinkama aplankų struktūra skirtingoms lokalėms. Pavyzdžiui, jums reikės /pages/en/about.js
ir /pages/fr/about.js
failų.
Globalūs aspektai: Įsitikinkite, kad jūsų i18n įgyvendinimas teisingai tvarko kalbas, rašomas iš dešinės į kairę (pvz., arabų, hebrajų). Taip pat apsvarstykite galimybę naudoti turinio pristatymo tinklą (CDN), kad lokalizuotus išteklius pateiktumėte iš arčiau jūsų vartotojų esančių serverių, taip pagerinant našumą.
3. Funkcijų vėliavėlės
Funkcijų vėliavėlės leidžia įjungti arba išjungti funkcijas jūsų programoje nediegiant naujo kodo. Tai ypač naudinga palaipsniui diegiant naujas funkcijas arba testuojant funkcijas gamybinėje aplinkoje. Tarpinė programinė įranga gali būti naudojama patikrinti funkcijos vėliavėlės būseną ir atitinkamai modifikuoti užklausą.
Pavyzdys: Beta funkcijos įjungimas
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
const BETA_FEATURE_ENABLED = process.env.BETA_FEATURE_ENABLED === 'true'
export function middleware(request: NextRequest) {
if (BETA_FEATURE_ENABLED && request.nextUrl.pathname.startsWith('/new-feature')) {
return NextResponse.next()
}
// Optionally redirect to a "feature unavailable" page
return NextResponse.rewrite(new URL('/feature-unavailable', request.url))
}
export const config = {
matcher: ['/new-feature/:path*'],
}
Ši tarpinė programinė įranga patikrina BETA_FEATURE_ENABLED
aplinkos kintamojo vertę. Jei ji nustatyta kaip true
ir vartotojas bando pasiekti maršrutą po /new-feature
, užklausa leidžiama tęsti. Kitu atveju, vartotojas peradresuojamas į /feature-unavailable
puslapį. Nepamirškite tinkamai sukonfigūruoti aplinkos kintamųjų skirtingoms aplinkoms (kūrimo, testavimo, gamybos).
Globalūs aspektai: Naudodami funkcijų vėliavėles, atsižvelkite į teisines pasekmes, įjungiant funkcijas, kurios gali neatitikti visų regionų reglamentų. Pavyzdžiui, su duomenų privatumu susijusias funkcijas tam tikrose šalyse gali tekti išjungti.
4. Įrenginių aptikimas ir adaptyvus maršrutizavimas
Šiuolaikinės žiniatinklio programos turi būti adaptyvios ir prisitaikyti prie skirtingų ekrano dydžių bei įrenginių galimybių. Tarpinė programinė įranga gali būti naudojama nustatyti vartotojo įrenginio tipą ir peradresuoti jį į optimizuotas jūsų svetainės versijas.
Pavyzdys: Mobiliųjų vartotojų peradresavimas į mobiliesiems pritaikytą subdomeną
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
import { device } from 'detection'
export function middleware(request: NextRequest) {
const userAgent = request.headers.get('user-agent')
if (userAgent) {
const deviceType = device(userAgent)
if (deviceType.type === 'phone') {
const mobileUrl = new URL(request.url)
mobileUrl.hostname = 'm.example.com'
return NextResponse.redirect(mobileUrl)
}
}
return NextResponse.next()
}
export const config = {
matcher: ['/'],
}
Šis pavyzdys naudoja `detection` biblioteką, kad nustatytų vartotojo įrenginio tipą pagal User-Agent
antraštę. Jei vartotojas naudoja mobilųjį telefoną, jis peradresuojamas į m.example.com
subdomeną (darant prielaidą, kad ten talpinate mobiliesiems pritaikytą svetainės versiją). Nepamirškite įdiegti `detection` paketą: `npm install detection`.
Globalūs aspektai: Įsitikinkite, kad jūsų įrenginių aptikimo logika atsižvelgia į regioninius įrenginių naudojimo skirtumus. Pavyzdžiui, paprastesni telefonai (angl. feature phones) vis dar paplitę kai kuriose besivystančiose šalyse. Apsvarstykite galimybę naudoti User-Agent aptikimo ir adaptyvaus dizaino technikų derinį, kad sprendimas būtų patikimesnis.
5. Užklausos antraščių praturtinimas
Tarpinė programinė įranga gali pridėti informacijos į užklausos antraštes prieš ją apdorojant jūsų programos maršrutams. Tai naudinga pridedant pasirinktinius metaduomenis, tokius kaip vartotojų rolės, autentifikavimo būsena ar užklausos ID, kuriuos gali naudoti jūsų programos logika.
Pavyzdys: Užklausos ID pridėjimas
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
import { v4 as uuidv4 } from 'uuid'
export function middleware(request: NextRequest) {
const requestId = uuidv4()
const response = NextResponse.next()
response.headers.set('x-request-id', requestId)
return response
}
export const config = {
matcher: ['/api/:path*'], // Only apply to API routes
}
Ši tarpinė programinė įranga sugeneruoja unikalų užklausos ID naudojant uuid
biblioteką ir prideda jį prie x-request-id
antraštės. Šis ID gali būti naudojamas registravimo, sekimo ir derinimo tikslais. Nepamirškite įdiegti uuid
paketą: `npm install uuid`.
Globalūs aspektai: Pridėdami pasirinktines antraštes, atkreipkite dėmesį į antraščių dydžio apribojimus. Viršijus šiuos apribojimus, gali kilti netikėtų klaidų. Taip pat įsitikinkite, kad bet kokia jautri informacija, pridėta prie antraščių, yra tinkamai apsaugota, ypač jei jūsų programa veikia už atvirkštinio tarpinio serverio (angl. reverse proxy) ar CDN.
6. Saugumo patobulinimai: užklausų dažnio ribojimas
Tarpinė programinė įranga gali veikti kaip pirmoji gynybos linija nuo kenkėjiškų atakų, įgyvendinant užklausų dažnio ribojimą. Tai apsaugo nuo piktnaudžiavimo, apribojant užklausų, kurias klientas gali pateikti per tam tikrą laikotarpį, skaičių.
Pavyzdys: Pagrindinis užklausų dažnio ribojimas naudojant paprastą saugyklą
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
const requestCounts: { [ip: string]: number } = {}
const WINDOW_SIZE_MS = 60000; // 1 minute
const MAX_REQUESTS_PER_WINDOW = 100;
export function middleware(request: NextRequest) {
const clientIP = request.ip || '127.0.0.1' // Get client IP, default to localhost for local testing
if (!requestCounts[clientIP]) {
requestCounts[clientIP] = 0;
}
requestCounts[clientIP]++;
if (requestCounts[clientIP] > MAX_REQUESTS_PER_WINDOW) {
return new NextResponse(
JSON.stringify({ message: 'Too many requests' }),
{ status: 429, headers: { 'Content-Type': 'application/json' } }
);
}
// Reset count after window
setTimeout(() => {
requestCounts[clientIP]--;
if (requestCounts[clientIP] <= 0) {
delete requestCounts[clientIP];
}
}, WINDOW_SIZE_MS);
return NextResponse.next();
}
export const config = {
matcher: ['/api/:path*'], // Apply to all API routes
}
Šis pavyzdys palaiko paprastą atmintyje esančią saugyklą (requestCounts
), kad sektų užklausų skaičių iš kiekvieno IP adreso. Jei klientas viršija MAX_REQUESTS_PER_WINDOW
per WINDOW_SIZE_MS
, tarpinė programinė įranga grąžina 429 Too Many Requests
klaidą. Svarbu: Tai yra supaprastintas pavyzdys ir netinka gamybinėms aplinkoms, nes jis nėra mastelio keičiamas ir yra pažeidžiamas paslaugos trikdymo atakoms (angl. denial-of-service). Gamybiniam naudojimui apsvarstykite galimybę naudoti patikimesnį užklausų dažnio ribojimo sprendimą, pavyzdžiui, Redis ar specializuotą ribojimo paslaugą.
Globalūs aspektai: Užklausų dažnio ribojimo strategijos turėtų būti pritaikytos prie konkrečių jūsų programos savybių ir geografinio vartotojų pasiskirstymo. Apsvarstykite galimybę naudoti skirtingus ribojimus skirtingiems regionams ar vartotojų segmentams.
Kraštutiniai atvejai ir galimi spąstai
Nors tarpinė programinė įranga yra galingas įrankis, svarbu žinoti jos apribojimus ir galimus spąstus:
- Poveikis našumui: Tarpinė programinė įranga prideda papildomos apkrovos kiekvienai užklausai. Venkite atlikti skaičiavimams imlias operacijas tarpinėje programinėje įrangoje, nes tai gali ženkliai paveikti našumą. Profiluokite savo tarpinę programinę įrangą, kad nustatytumėte ir optimizuotumėte bet kokius našumo trūkumus.
- Sudėtingumas: Pernelyg gausus tarpinės programinės įrangos naudojimas gali apsunkinti jūsų programos supratimą ir priežiūrą. Naudokite tarpinę programinę įrangą apgalvotai ir užtikrinkite, kad kiekviena funkcija turėtų aiškų ir gerai apibrėžtą tikslą.
- Testavimas: Tarpinės programinės įrangos testavimas gali būti sudėtingas, nes reikia simuliuoti HTTP užklausas ir tikrinti gautus atsakymus. Naudokite įrankius, tokius kaip Jest ir Supertest, kad parašytumėte išsamius vieneto ir integracijos testus savo tarpinės programinės įrangos funkcijoms.
- Slapukų valdymas: Būkite atsargūs nustatydami slapukus tarpinėje programinėje įrangoje, nes tai gali paveikti podėliavimo (angl. caching) elgseną. Įsitikinkite, kad suprantate slapukais pagrįsto podėliavimo pasekmes ir atitinkamai sukonfigūruokite savo podėlio antraštes.
- Aplinkos kintamieji: Užtikrinkite, kad visi aplinkos kintamieji, naudojami jūsų tarpinėje programinėje įrangoje, yra tinkamai sukonfigūruoti skirtingoms aplinkoms (kūrimo, testavimo, gamybos). Naudokite įrankį, pavyzdžiui, Dotenv, aplinkos kintamiesiems valdyti.
- Edge funkcijų apribojimai: Nepamirškite, kad tarpinė programinė įranga veikia kaip Edge funkcijos, kurios turi vykdymo laiko, atminties naudojimo ir supakuoto kodo dydžio apribojimus. Laikykite savo tarpinės programinės įrangos funkcijas lengvasvorėmis ir efektyviomis.
Geriausios Next.js tarpinės programinės įrangos naudojimo praktikos
Norėdami maksimaliai išnaudoti Next.js tarpinės programinės įrangos privalumus ir išvengti galimų problemų, laikykitės šių geriausių praktikų:
- Paprastumas: Kiekviena tarpinės programinės įrangos funkcija turėtų turėti vieną, gerai apibrėžtą atsakomybę. Venkite kurti pernelyg sudėtingas tarpinės programinės įrangos funkcijas, kurios atlieka kelias užduotis.
- Optimizuokite našumą: Sumažinkite apdorojimo kiekį tarpinėje programinėje įrangoje, kad išvengtumėte našumo trūkumų. Naudokite podėliavimo strategijas, kad sumažintumėte pasikartojančių skaičiavimų poreikį.
- Testuokite kruopščiai: Rašykite išsamius vieneto ir integracijos testus savo tarpinės programinės įrangos funkcijoms, kad užtikrintumėte, jog jos veikia kaip tikėtasi.
- Dokumentuokite savo kodą: Aiškiai dokumentuokite kiekvienos tarpinės programinės įrangos funkcijos paskirtį ir funkcionalumą, kad pagerintumėte palaikomumą.
- Stebėkite savo programą: Naudokite stebėjimo įrankius, kad sektumėte savo tarpinės programinės įrangos funkcijų našumą ir klaidų dažnį.
- Supraskite vykdymo tvarką: Žinokite, kokia tvarka vykdomos tarpinės programinės įrangos funkcijos, nes tai gali paveikti jų elgesį.
- Naudokite aplinkos kintamuosius protingai: Naudokite aplinkos kintamuosius, kad sukonfigūruotumėte savo tarpinės programinės įrangos funkcijas skirtingoms aplinkoms.
Išvada
Next.js tarpinė programinė įranga siūlo galingą būdą modifikuoti užklausas ir pritaikyti jūsų programos elgesį „edge“ lygmenyje. Suprasdami šiame vadove aptartus pažangius užklausų modifikavimo šablonus, galite kurti patikimas, našias ir globaliai pritaikytas Next.js programas. Nepamirškite atidžiai apsvarstyti kraštutinių atvejų ir galimų spąstų bei laikytis aukščiau pateiktų geriausių praktikų, kad užtikrintumėte, jog jūsų tarpinės programinės įrangos funkcijos būtų patikimos ir lengvai palaikomos. Pasinaudokite tarpinės programinės įrangos galia, kad sukurtumėte išskirtines vartotojų patirtis ir atvertumėte naujas galimybes savo žiniatinklio programoms.