Eesti

Avastage Next.js middleware'i abil täiustatud päringute muutmise tehnikaid. Õppige toime tulema keeruka marsruutimise, autentimise, A/B testimise ja lokaliseerimisstrateegiatega robustsete veebirakenduste jaoks.

Next.js Middleware'i erijuhud: päringute muutmise mustrite valdamine

Next.js middleware pakub võimsat mehhanismi päringute pealtkuulamiseks ja muutmiseks enne, kui need jõuavad teie rakenduse marsruutideni. See võimekus avab laia valiku võimalusi, alates lihtsatest autentimiskontrollidest kuni keerukate A/B testimise stsenaariumite ja rahvusvahelistumise strateegiateni. Kuid middleware'i tõhusaks kasutamiseks on vaja sügavat arusaamist selle erijuhtudest ja potentsiaalsetest lõksudest. See põhjalik juhend uurib täiustatud päringute muutmise mustreid, pakkudes praktilisi näiteid ja teostatavaid teadmisi, mis aitavad teil ehitada robustseid ja jõudsaid Next.js rakendusi.

Next.js Middleware'i põhitõdede mõistmine

Enne täiustatud mustritesse sukeldumist kordame üle Next.js middleware'i põhitõed. Middleware'i funktsioonid käivitatakse enne päringu lõpuleviimist, võimaldades teil:

Middleware'i funktsioonid asuvad failis middleware.js või middleware.ts teie /pages või /app kataloogis (sõltuvalt teie Next.js versioonist ja seadistusest). Nad saavad sissetulevat päringut esindava NextRequest objekti ja võivad tagastada NextResponse objekti, et kontrollida järgnevat käitumist.

Näide: Põhiline autentimise middleware

See näide demonstreerib lihtsat autentimiskontrolli. Kui kasutaja pole autenditud (nt küpsises pole kehtivat tokenit), suunatakse ta sisselogimislehele.


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

See middleware käivitub ainult marsruutidel, mis vastavad mustrile /protected/:path*. See kontrollib authToken küpsise olemasolu. Kui küpsis puudub, suunatakse kasutaja /login lehele. Vastasel juhul lubatakse päringul normaalselt jätkuda, kasutades NextResponse.next().

Täiustatud päringute muutmise mustrid

Nüüd uurime mõningaid täiustatud päringute muutmise mustreid, mis näitavad Next.js middleware'i tõelist jõudu.

1. A/B testimine küpsistega

A/B testimine on oluline tehnika kasutajakogemuse optimeerimiseks. Middleware'i saab kasutada kasutajate juhuslikuks määramiseks teie rakenduse erinevatele variantidele ja nende käitumise jälgimiseks. See muster tugineb küpsistele, et säilitada kasutajale määratud variant.

Näide: Avalehe A/B testimine


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) {
    // Määra variant juhuslikult
    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: ['/'],
}

Selles näites, kui kasutaja külastab juur-URL-i (/) esimest korda, määrab middleware talle juhuslikult kas variantA või variantB. See variant salvestatakse küpsisesse. Sama kasutaja järgnevad päringud kirjutatakse ümber kas aadressile /variant-a või /variant-b, sõltuvalt talle määratud variandist. See võimaldab teil serveerida erinevaid avalehti ja jälgida, kumb neist paremini toimib. Veenduge, et teie Next.js rakenduses on määratletud marsruudid /variant-a ja /variant-b jaoks.

Globaalsed kaalutlused: A/B testimise läbiviimisel arvestage piirkondlike erinevustega. Disain, mis kõnetab Põhja-Ameerikas, ei pruugi Aasias olla sama tõhus. Võiksite kasutada geograafilist asukohaandmeid (saadud IP-aadressi otsingu või kasutajaeelistuste kaudu), et kohandada A/B testi konkreetsetele piirkondadele.

2. Lokaliseerimine (i18n) URL-ide ümberkirjutamisega

Rahvusvahelistumine (i18n) on globaalse publikuni jõudmiseks hädavajalik. Middleware'i saab kasutada kasutaja eelistatud keele automaatseks tuvastamiseks ja tema suunamiseks teie saidi vastavasse lokaliseeritud versiooni.

Näide: Ümbersuunamine Accept-Language päise põhjal


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

  // Kontrolli, kas URL-is on juba lokaat olemas
  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).*)'
  ],
}

See middleware eraldab päringust Accept-Language päise ja määrab kindlaks kasutaja eelistatud keele. Kui URL ei sisalda juba keeleprefiksit (nt /en/about), suunab middleware kasutaja vastavale lokaliseeritud URL-ile (nt /fr/about prantsuse keele puhul). Veenduge, et teil on oma /pages või /app kataloogis sobiv kaustastruktuur erinevate lokaatide jaoks. Näiteks vajate faile /pages/en/about.js ja /pages/fr/about.js.

Globaalsed kaalutlused: Veenduge, et teie i18n-rakendus käsitleks paremalt vasakule kirjutatavaid keeli (nt araabia, heebrea) korrektselt. Samuti kaaluge sisuedastusvõrgu (CDN) kasutamist, et serveerida lokaliseeritud varasid kasutajatele lähematest serveritest, parandades seeläbi jõudlust.

3. Funktsioonilipud (Feature Flags)

Funktsioonilipud võimaldavad teil oma rakenduses funktsioone sisse või välja lülitada ilma uut koodi juurutamata. See on eriti kasulik uute funktsioonide järkjärguliseks kasutuselevõtuks või funktsioonide testimiseks tootmiskeskkonnas. Middleware'i saab kasutada funktsioonilipu staatuse kontrollimiseks ja päringu vastavaks muutmiseks.

Näide: Beetafunktsiooni lubamine


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()
  }

  // Valikuliselt suuna "funktsioon pole saadaval" lehele
  return NextResponse.rewrite(new URL('/feature-unavailable', request.url))
}

export const config = {
  matcher: ['/new-feature/:path*'],
}

See middleware kontrollib keskkonnamuutuja BETA_FEATURE_ENABLED väärtust. Kui see on seatud väärtusele true ja kasutaja proovib pääseda marsruudile /new-feature all, lubatakse päringul jätkuda. Vastasel juhul suunatakse kasutaja lehele /feature-unavailable. Ärge unustage konfigureerida keskkonnamuutujaid sobivalt erinevate keskkondade (arendus, testimine, tootmine) jaoks.

Globaalsed kaalutlused: Funktsioonilippude kasutamisel arvestage juriidiliste tagajärgedega, mis kaasnevad funktsioonide lubamisega, mis ei pruugi olla kõigis piirkondades eeskirjadega kooskõlas. Näiteks andmekaitsega seotud funktsioonid võivad teatud riikides vajada keelamist.

4. Seadmetuvastus ja adaptiivne marsruutimine

Kaasaegsed veebirakendused peavad olema responsiivsed ja kohanema erinevate ekraanisuuruste ja seadmete võimalustega. Middleware'i saab kasutada kasutaja seadmetüübi tuvastamiseks ja nende suunamiseks teie saidi optimeeritud versioonidele.

Näide: Mobiilikasutajate suunamine mobiilile optimeeritud alamdomeenile


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

See näide kasutab teeki `detection`, et määrata kasutaja seadme tüüp User-Agent päise põhjal. Kui kasutaja on mobiiltelefonis, suunatakse ta alamdomeenile m.example.com (eeldusel, et teil on seal hostitud saidi mobiilile optimeeritud versioon). Ärge unustage paigaldada `detection` paketti: `npm install detection`.

Globaalsed kaalutlused: Veenduge, et teie seadmetuvastuse loogika arvestaks piirkondlike erinevustega seadmete kasutamisel. Näiteks on nuputelefonid mõnes arengumaas endiselt levinud. Kaaluge User-Agent'i tuvastamise ja responsiivse disaini tehnikate kombinatsiooni kasutamist robustsema lahenduse saamiseks.

5. Päringupäiste rikastamine

Middleware saab lisada teavet päringu päistesse enne, kui teie rakenduse marsruudid seda töötlevad. See on kasulik kohandatud metaandmete, näiteks kasutajarollide, autentimisstaatuse või päringu ID-de lisamiseks, mida teie rakenduse loogika saab kasutada.

Näide: Päringu ID lisamine


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*'], // Rakenda ainult API marsruutidele
}

See middleware genereerib unikaalse päringu ID, kasutades teeki uuid, ja lisab selle x-request-id päisesse. Seda ID-d saab seejärel kasutada logimiseks, jälgimiseks ja silumiseks. Ärge unustage paigaldada uuid paketti: `npm install uuid`.

Globaalsed kaalutlused: Kohandatud päiste lisamisel pidage silmas päiste suuruse piiranguid. Nende piirangute ületamine võib põhjustada ootamatuid vigu. Samuti veenduge, et päistesse lisatud tundlik teave on korralikult kaitstud, eriti kui teie rakendus on pöördproksi või CDN-i taga.

6. Turvalisuse täiustused: Päringute piiramine (Rate Limiting)

Middleware võib toimida esimese kaitseliinina pahatahtlike rünnakute vastu, rakendades päringute piiramist. See hoiab ära kuritarvitamise, piirates päringute arvu, mida klient saab kindla ajavahemiku jooksul teha.

Näide: Põhiline päringute piiramine lihtsa salvestusruumiga


import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'

const requestCounts: { [ip: string]: number } = {}
const WINDOW_SIZE_MS = 60000; // 1 minut
const MAX_REQUESTS_PER_WINDOW = 100;

export function middleware(request: NextRequest) {
  const clientIP = request.ip || '127.0.0.1' // Hangi kliendi IP, vaikimisi localhost kohalikuks testimiseks

  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' } }
    );
  }

  // Lähtesta loendur pärast akna möödumist
  setTimeout(() => {
    requestCounts[clientIP]--;
    if (requestCounts[clientIP] <= 0) {
        delete requestCounts[clientIP];
    }
  }, WINDOW_SIZE_MS);

  return NextResponse.next();
}

export const config = {
  matcher: ['/api/:path*'], // Rakenda kõigile API marsruutidele
}

See näide haldab lihtsat mälusisest salvestusruumi (requestCounts), et jälgida iga IP-aadressi päringute arvu. Kui klient ületab MAX_REQUESTS_PER_WINDOW piiri WINDOW_SIZE_MS jooksul, tagastab middleware vea 429 Too Many Requests. Tähtis: See on lihtsustatud näide ja ei sobi tootmiskeskkondadesse, kuna see ei skaleeru ja on haavatav teenusetõkestamise rünnakutele. Tootmiskasutuseks kaaluge robustsema päringute piiramise lahenduse, näiteks Redis või spetsiaalse päringute piiramise teenuse kasutamist.

Globaalsed kaalutlused: Päringute piiramise strateegiad tuleks kohandada vastavalt teie rakenduse eripäradele ja kasutajate geograafilisele jaotusele. Kaaluge erinevate piirangute kasutamist erinevate piirkondade või kasutajasegmentide jaoks.

Erijuhud ja potentsiaalsed lõksud

Kuigi middleware on võimas tööriist, on oluline olla teadlik selle piirangutest ja potentsiaalsetest lõksudest:

Next.js Middleware'i kasutamise parimad praktikad

Next.js middleware'i eeliste maksimeerimiseks ja võimalike probleemide vältimiseks järgige neid parimaid praktikaid:

Kokkuvõte

Next.js middleware pakub võimsat viisi päringute muutmiseks ja teie rakenduse käitumise kohandamiseks servas. Mõistes selles juhendis käsitletud täiustatud päringute muutmise mustreid, saate ehitada robustseid, jõudsaid ja globaalselt teadlikke Next.js rakendusi. Pidage meeles hoolikalt kaaluda erijuhte ja potentsiaalseid lõkse ning järgige ülaltoodud parimaid praktikaid, et tagada teie middleware'i funktsioonide usaldusväärsus ja hooldatavus. Võtke omaks middleware'i jõud, et luua erakordseid kasutajakogemusi ja avada uusi võimalusi oma veebirakendustele.