Magyar

Fedezze fel a haladó kérésmódosítási technikákat a Next.js middleware segítségével. Tanulja meg a komplex útválasztás, hitelesítés, A/B tesztelés és lokalizáció kezelését robusztus webalkalmazásokhoz.

A Next.js Middleware Edge Esetei: A Kérésmódosítási Minták Mesteri Szintű Kezelése

A Next.js middleware egy hatékony mechanizmust biztosít a kérések elfogására és módosítására, még mielőtt azok elérnék az alkalmazás útvonalait. Ez a képesség lehetőségek széles skáláját nyitja meg, az egyszerű hitelesítési ellenőrzésektől a komplex A/B tesztelési forgatókönyvekig és nemzetköziesítési stratégiákig. Azonban a middleware hatékony kihasználásához mélyen meg kell érteni annak szélsőséges eseteit és lehetséges buktatóit. Ez az átfogó útmutató a haladó kérésmódosítási mintákat vizsgálja, gyakorlati példákat és hasznosítható ismereteket nyújtva, hogy segítsen robusztus és nagy teljesítményű Next.js alkalmazásokat építeni.

A Next.js Middleware Alapjainak Megértése

Mielőtt belemerülnénk a haladó mintákba, ismételjük át a Next.js middleware alapjait. A middleware függvények egy kérés befejezése előtt futnak le, lehetővé téve a következőket:

A middleware függvények a middleware.js vagy middleware.ts fájlban helyezkednek el a /pages vagy /app könyvtárban (a Next.js verziójától és beállításaitól függően). Kapnak egy NextRequest objektumot, amely a bejövő kérést képviseli, és visszaadhatnak egy NextResponse objektumot a további viselkedés irányítására.

Példa: Alapvető Hitelesítési Middleware

Ez a példa egy egyszerű hitelesítési ellenőrzést mutat be. Ha a felhasználó nincs hitelesítve (pl. nincs érvényes token egy sütiben), átirányításra kerül a bejelentkezési oldalra.


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*'],
}

Ez a middleware csak a /protected/:path* útvonalakra illeszkedő kérések esetén fut le. Ellenőrzi az authToken süti meglétét. Ha a süti hiányzik, a felhasználó átirányításra kerül a /login oldalra. Ellenkező esetben a kérés a NextResponse.next() használatával normálisan folytatódhat.

Haladó Kérésmódosítási Minták

Most pedig nézzünk meg néhány haladó kérésmódosítási mintát, amelyek bemutatják a Next.js middleware valódi erejét.

1. A/B Tesztelés Sütikkel

Az A/B tesztelés kulcsfontosságú technika a felhasználói élmény optimalizálásához. A middleware segítségével véletlenszerűen hozzárendelhetjük a felhasználókat az alkalmazás különböző variációihoz, és nyomon követhetjük viselkedésüket. Ez a minta sütikre támaszkodik a felhasználóhoz rendelt változat megőrzéséhez.

Példa: Nyitóoldal A/B Tesztelése


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: ['/'],
}

Ebben a példában, amikor egy felhasználó először látogatja meg a gyökér útvonalat (/), a middleware véletlenszerűen hozzárendeli őt a variantA vagy a variantB változathoz. Ezt a változatot egy sütiben tárolja a rendszer. Ugyanazon felhasználó későbbi kérései átírásra kerülnek a /variant-a vagy a /variant-b útvonalra, a hozzárendelt változattól függően. Ez lehetővé teszi, hogy különböző nyitóoldalakat szolgáljunk ki, és nyomon kövessük, melyik teljesít jobban. Győződjön meg róla, hogy a Next.js alkalmazásában definiálva vannak a /variant-a és /variant-b útvonalak.

Globális Megfontolások: A/B tesztelés során vegye figyelembe a regionális különbségeket. Egy dizájn, amely Észak-Amerikában népszerű, lehet, hogy Ázsiában nem annyira hatékony. Használhat geolokációs adatokat (IP-cím alapú kereséssel vagy felhasználói preferenciákkal szerezve) az A/B teszt adott régiókra szabásához.

2. Lokalizáció (i18n) URL Átírással

A nemzetköziesítés (i18n) elengedhetetlen a globális közönség eléréséhez. A middleware segítségével automatikusan felismerhető a felhasználó preferált nyelve, és átirányítható a webhely megfelelő, lokalizált verziójára.

Példa: Átirányítás az `Accept-Language` Fejléc Alapján


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).*)'
  ],
}

Ez a middleware kinyeri a kérésből az Accept-Language fejlécet, és meghatározza a felhasználó preferált nyelvét. Ha az URL még nem tartalmaz nyelvi előtagot (pl. /en/about), a middleware átirányítja a felhasználót a megfelelő lokalizált URL-re (pl. franciául a /fr/about-ra). Győződjön meg arról, hogy a /pages vagy /app könyvtárában megfelelő mappastruktúrával rendelkezik a különböző nyelvekhez. Például szüksége lesz egy /pages/en/about.js és egy /pages/fr/about.js fájlra.

Globális Megfontolások: Győződjön meg róla, hogy az i18n implementációja helyesen kezeli a jobbról balra író nyelveket (pl. arab, héber). Fontolja meg egy Tartalomszolgáltató Hálózat (CDN) használatát is, hogy a lokalizált eszközöket a felhasználókhoz közelebbi szerverekről szolgálja ki, ezzel javítva a teljesítményt.

3. Funkciókapcsolók (Feature Flags)

A funkciókapcsolók (feature flags) lehetővé teszik, hogy új kód telepítése nélkül engedélyezzen vagy letiltson funkciókat az alkalmazásában. Ez különösen hasznos új funkciók fokozatos bevezetéséhez vagy éles környezetben történő teszteléséhez. A middleware használható egy funkciókapcsoló állapotának ellenőrzésére és a kérés ennek megfelelő módosítására.

Példa: Egy Béta Funkció Engedélyezése


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*'],
}

Ez a middleware ellenőrzi a BETA_FEATURE_ENABLED környezeti változó értékét. Ha az értéke true, és a felhasználó egy /new-feature alatti útvonalat próbál elérni, a kérés továbbengedésre kerül. Ellenkező esetben a felhasználó átirányításra kerül egy /feature-unavailable oldalra. Ne felejtse el megfelelően beállítani a környezeti változókat a különböző környezetekhez (fejlesztői, teszt-, éles).

Globális Megfontolások: Funkciókapcsolók használatakor vegye figyelembe azon funkciók engedélyezésének jogi következményeit, amelyek esetleg nem felelnek meg minden régió szabályozásának. Például az adatvédelemmel kapcsolatos funkciókat bizonyos országokban le kell tiltani.

4. Eszközfelismerés és Adaptív Útválasztás

A modern webalkalmazásoknak reszponzívnak kell lenniük, és alkalmazkodniuk kell a különböző képernyőméretekhez és eszközképességekhez. A middleware használható a felhasználó eszköztípusának felismerésére és a webhely optimalizált verzióira történő átirányítására.

Példa: Mobil Felhasználók Átirányítása egy Mobilra Optimalizált Aldomainre


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: ['/'],
}

Ez a példa a `detection` könyvtárat használja a felhasználó eszköztípusának meghatározására a User-Agent fejléc alapján. Ha a felhasználó mobiltelefonon van, átirányításra kerül a m.example.com aldomainre (feltételezve, hogy ott egy mobilra optimalizált verziója van a webhelynek). Ne felejtse el telepíteni a `detection` csomagot: `npm install detection`.

Globális Megfontolások: Győződjön meg róla, hogy az eszközfelismerési logikája figyelembe veszi az eszközhasználat regionális különbségeit. Például a hagyományos mobiltelefonok még mindig elterjedtek néhány fejlődő országban. Fontolja meg a User-Agent felismerés és a reszponzív design technikák kombinációjának használatát egy robusztusabb megoldás érdekében.

5. Kérés Fejlécének Bővítése

A middleware információkat adhat hozzá a kérés fejléceihez, mielőtt azokat az alkalmazás útvonalai feldolgoznák. Ez hasznos egyéni metaadatok, például felhasználói szerepkörök, hitelesítési állapot vagy kérésazonosítók hozzáadásához, amelyeket az alkalmazás logikája felhasználhat.

Példa: Kérésazonosító Hozzáadása


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
}

Ez a middleware egyedi kérésazonosítót generál az uuid könyvtár segítségével, és hozzáadja azt az x-request-id fejléchez. Ezt az azonosítót később naplózási, nyomkövetési és hibakeresési célokra lehet használni. Ne felejtse el telepíteni az uuid csomagot: `npm install uuid`.

Globális Megfontolások: Egyéni fejlécek hozzáadásakor ügyeljen a fejlécméret-korlátokra. Ezek túllépése váratlan hibákhoz vezethet. Továbbá gondoskodjon arról, hogy a fejlécekhez hozzáadott érzékeny információk megfelelően védve legyenek, különösen, ha az alkalmazás egy fordított proxy vagy CDN mögött található.

6. Biztonsági Fejlesztések: Kérések Korlátozása (Rate Limiting)

A middleware az első védelmi vonalként működhet a rosszindulatú támadások ellen a kérések korlátozásának (rate limiting) bevezetésével. Ez megakadályozza a visszaéléseket azáltal, hogy korlátozza a kliens által egy adott időablakban tehető kérések számát.

Példa: Alapvető Kéréskorlátozás egy Egyszerű Tárolóval


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
}

Ez a példa egy egyszerű, memóriában tárolt (requestCounts) adatstruktúrát tart fenn az egyes IP-címekről érkező kérések számának nyomon követésére. Ha egy kliens túllépi a MAX_REQUESTS_PER_WINDOW értéket a WINDOW_SIZE_MS időablakon belül, a middleware egy 429 Too Many Requests hibát ad vissza. Fontos: Ez egy egyszerűsített példa, és nem alkalmas éles környezetben való használatra, mivel nem skálázódik és sebezhető a szolgáltatásmegtagadási támadásokkal szemben. Éles használatra fontolja meg egy robusztusabb kéréskorlátozási megoldás, például a Redis vagy egy dedikált szolgáltatás használatát.

Globális Megfontolások: A kéréskorlátozási stratégiákat az alkalmazás specifikus jellemzőihez és a felhasználók földrajzi eloszlásához kell igazítani. Fontolja meg különböző korlátok alkalmazását különböző régiókra vagy felhasználói szegmensekre.

Szélsőséges Esetek és Lehetséges Buktatók

Bár a middleware egy hatékony eszköz, fontos tisztában lenni a korlátaival és lehetséges buktatóival:

A Next.js Middleware Használatának Legjobb Gyakorlatai

A Next.js middleware előnyeinek maximalizálása és a lehetséges problémák elkerülése érdekében kövesse az alábbi legjobb gyakorlatokat:

Összegzés

A Next.js middleware hatékony módot kínál a kérések módosítására és az alkalmazás viselkedésének testreszabására az edge-en. Az ebben az útmutatóban tárgyalt haladó kérésmódosítási minták megértésével robusztus, nagy teljesítményű és globálisan tudatos Next.js alkalmazásokat építhet. Ne felejtse el gondosan mérlegelni a szélsőséges eseteket és a lehetséges buktatókat, és kövesse a fent vázolt legjobb gyakorlatokat annak érdekében, hogy middleware függvényei megbízhatóak és karbantarthatóak legyenek. Használja ki a middleware erejét, hogy kivételes felhasználói élményeket hozzon létre, és új lehetőségeket nyisson meg webalkalmazásai számára.

A Next.js Middleware Edge Esetei: A Kérésmódosítási Minták Mesteri Szintű Kezelése | MLOG