ไทย

สำรวจเทคนิคการปรับเปลี่ยนคำขอขั้นสูงโดยใช้ Next.js middleware เรียนรู้วิธีจัดการการกำหนดเส้นทางที่ซับซ้อน การตรวจสอบสิทธิ์ การทดสอบ A/B และกลยุทธ์การแปลภาษาสำหรับเว็บแอปพลิเคชันที่มีประสิทธิภาพ

กรณีพิเศษของ Next.js Middleware: การควบคุมรูปแบบการปรับเปลี่ยนคำขอ

Next.js middleware เป็นกลไกที่มีประสิทธิภาพสำหรับการสกัดกั้นและแก้ไขคำขอก่อนที่จะเข้าถึงเส้นทางของแอปพลิเคชันของคุณ ความสามารถนี้เปิดโอกาสที่หลากหลาย ตั้งแต่การตรวจสอบสิทธิ์อย่างง่ายไปจนถึงสถานการณ์การทดสอบ A/B ที่ซับซ้อนและกลยุทธ์การทำให้เป็นสากล อย่างไรก็ตาม การใช้ middleware อย่างมีประสิทธิภาพต้องอาศัยความเข้าใจอย่างลึกซึ้งเกี่ยวกับกรณีพิเศษและข้อผิดพลาดที่อาจเกิดขึ้น คู่มือที่ครอบคลุมนี้จะสำรวจรูปแบบการปรับเปลี่ยนคำขอขั้นสูง โดยให้ตัวอย่างที่เป็นประโยชน์และข้อมูลเชิงลึกที่นำไปปฏิบัติได้จริง เพื่อช่วยคุณสร้างแอปพลิเคชัน Next.js ที่แข็งแกร่งและมีประสิทธิภาพ

ทำความเข้าใจพื้นฐานของ Next.js Middleware

ก่อนที่จะเจาะลึกลงไปในรูปแบบขั้นสูง มาทบทวนพื้นฐานของ Next.js middleware ฟังก์ชัน Middleware จะถูกดำเนินการก่อนที่คำขอจะเสร็จสมบูรณ์ ทำให้คุณสามารถ:

ฟังก์ชัน Middleware อยู่ในไฟล์ middleware.js หรือ middleware.ts ในไดเรกทอรี /pages หรือ /app ของคุณ (ขึ้นอยู่กับเวอร์ชันและการตั้งค่า Next.js ของคุณ) โดยจะได้รับออบเจ็กต์ NextRequest ที่แสดงถึงคำขอขาเข้า และสามารถส่งคืนออบเจ็กต์ NextResponse เพื่อควบคุมลักษณะการทำงานที่ตามมา

ตัวอย่าง: Middleware การตรวจสอบสิทธิ์ขั้นพื้นฐาน

ตัวอย่างนี้สาธิตการตรวจสอบสิทธิ์อย่างง่าย หากผู้ใช้ไม่ได้รับการตรวจสอบสิทธิ์ (เช่น ไม่มีโทเค็นที่ถูกต้องในคุกกี้) พวกเขาจะถูกเปลี่ยนเส้นทางไปยังหน้าเข้าสู่ระบบ


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

Middleware นี้จะทำงานเฉพาะสำหรับเส้นทางที่ตรงกับ /protected/:path* โดยจะตรวจสอบการมีอยู่ของคุกกี้ authToken หากไม่มีคุกกี้ ผู้ใช้จะถูกเปลี่ยนเส้นทางไปยังหน้า /login มิฉะนั้น คำขอจะได้รับอนุญาตให้ดำเนินการตามปกติโดยใช้ NextResponse.next()

รูปแบบการปรับเปลี่ยนคำขอขั้นสูง

ตอนนี้ มาสำรวจรูปแบบการปรับเปลี่ยนคำขอขั้นสูงบางส่วนที่แสดงให้เห็นถึงพลังที่แท้จริงของ Next.js middleware

1. การทดสอบ A/B ด้วยคุกกี้

การทดสอบ A/B เป็นเทคนิคที่สำคัญสำหรับการเพิ่มประสิทธิภาพประสบการณ์ผู้ใช้ Middleware สามารถใช้เพื่อกำหนดผู้ใช้ให้กับรูปแบบต่างๆ ของแอปพลิเคชันของคุณแบบสุ่ม และติดตามพฤติกรรมของพวกเขา รูปแบบนี้อาศัยคุกกี้เพื่อคงอยู่กับตัวแปรที่กำหนดของผู้ใช้

ตัวอย่าง: การทดสอบ A/B ของหน้า Landing Page


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

ในตัวอย่างนี้ เมื่อผู้ใช้เข้าชมเส้นทาง root (/) เป็นครั้งแรก middleware จะกำหนดให้พวกเขาเป็น variantA หรือ variantB แบบสุ่ม ตัวแปรนี้จะถูกเก็บไว้ในคุกกี้ คำขอที่ตามมาจากผู้ใช้รายเดียวกันจะถูกเขียนใหม่เป็น /variant-a หรือ /variant-b ขึ้นอยู่กับตัวแปรที่กำหนด นี่ช่วยให้คุณสามารถแสดงหน้า Landing Page ที่แตกต่างกัน และติดตามว่าหน้าใดมีประสิทธิภาพดีกว่า ตรวจสอบให้แน่ใจว่าคุณมีเส้นทางที่กำหนดไว้สำหรับ /variant-a และ /variant-b ในแอปพลิเคชัน Next.js ของคุณ

ข้อควรพิจารณาโดยรวม: เมื่อทำการทดสอบ A/B ให้พิจารณาความแตกต่างในระดับภูมิภาค การออกแบบที่โดนใจในอเมริกาเหนืออาจไม่ได้ผลในเอเชีย คุณสามารถใช้ข้อมูลตำแหน่งทางภูมิศาสตร์ (ที่ได้รับจากการค้นหาที่อยู่ IP หรือการตั้งค่าของผู้ใช้) เพื่อปรับแต่งการทดสอบ A/B ให้เข้ากับภูมิภาคที่เฉพาะเจาะจง

2. การแปลภาษา (i18n) ด้วยการเขียน URL ใหม่

Internationalization (i18n) เป็นสิ่งจำเป็นสำหรับการเข้าถึงผู้ชมทั่วโลก Middleware สามารถใช้เพื่อตรวจจับภาษาที่ผู้ใช้ต้องการโดยอัตโนมัติ และเปลี่ยนเส้นทางพวกเขาไปยังไซต์เวอร์ชันที่แปลเป็นภาษาท้องถิ่นที่เหมาะสม

ตัวอย่าง: การเปลี่ยนเส้นทางตามส่วนหัว `Accept-Language`


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

Middleware นี้จะแยกส่วนหัว Accept-Language ออกจากคำขอ และกำหนดภาษาที่ผู้ใช้ต้องการ หาก URL ยังไม่มีคำนำหน้าภาษา (เช่น /en/about) middleware จะเปลี่ยนเส้นทางผู้ใช้ไปยัง URL ที่แปลเป็นภาษาท้องถิ่นที่เหมาะสม (เช่น /fr/about สำหรับภาษาฝรั่งเศส) ตรวจสอบให้แน่ใจว่าคุณมีโครงสร้างโฟลเดอร์ที่เหมาะสมในไดเรกทอรี `/pages` หรือ `/app` ของคุณสำหรับภาษาต่างๆ ตัวอย่างเช่น คุณจะต้องมีไฟล์ `/pages/en/about.js` และ `/pages/fr/about.js`

ข้อควรพิจารณาโดยรวม: ตรวจสอบให้แน่ใจว่าการใช้งาน i18n ของคุณจัดการภาษาที่อ่านจากขวาไปซ้าย (เช่น อาหรับ ฮิบรู) อย่างถูกต้อง นอกจากนี้ ให้พิจารณาใช้ Content Delivery Network (CDN) เพื่อให้บริการเนื้อหาที่แปลเป็นภาษาท้องถิ่นจากเซิร์ฟเวอร์ที่อยู่ใกล้กับผู้ใช้ของคุณมากขึ้น ซึ่งจะช่วยปรับปรุงประสิทธิภาพ

3. Feature Flags

Feature Flags ช่วยให้คุณเปิดหรือปิดใช้งานคุณสมบัติในแอปพลิเคชันของคุณได้โดยไม่ต้องปรับใช้โค้ดใหม่ นี่เป็นประโยชน์อย่างยิ่งสำหรับการเปิดตัวคุณสมบัติใหม่ทีละน้อย หรือสำหรับการทดสอบคุณสมบัติในการใช้งานจริง Middleware สามารถใช้เพื่อตรวจสอบสถานะของ Feature Flag และแก้ไขคำขอตามนั้น

ตัวอย่าง: การเปิดใช้งานคุณสมบัติ Beta


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

Middleware นี้จะตรวจสอบค่าของตัวแปรสภาพแวดล้อม BETA_FEATURE_ENABLED หากตั้งค่าเป็น true และผู้ใช้พยายามเข้าถึงเส้นทางภายใต้ /new-feature คำขอจะได้รับอนุญาตให้ดำเนินการ มิฉะนั้น ผู้ใช้จะถูกเปลี่ยนเส้นทางไปยังหน้า /feature-unavailable อย่าลืมกำหนดค่าตัวแปรสภาพแวดล้อมอย่างเหมาะสมสำหรับสภาพแวดล้อมที่แตกต่างกัน (การพัฒนา สเตจ การใช้งานจริง)

ข้อควรพิจารณาโดยรวม: เมื่อใช้ Feature Flags ให้พิจารณาถึงผลกระทบทางกฎหมายของการเปิดใช้งานคุณสมบัติที่อาจไม่เป็นไปตามข้อกำหนดในทุกภูมิภาค ตัวอย่างเช่น คุณสมบัติที่เกี่ยวข้องกับความเป็นส่วนตัวของข้อมูลอาจต้องถูกปิดใช้งานในบางประเทศ

4. การตรวจจับอุปกรณ์และการกำหนดเส้นทางแบบปรับตัว

เว็บแอปพลิเคชันสมัยใหม่ต้องตอบสนองและปรับให้เข้ากับขนาดหน้าจอและความสามารถของอุปกรณ์ที่แตกต่างกัน Middleware สามารถใช้เพื่อตรวจจับประเภทอุปกรณ์ของผู้ใช้ และเปลี่ยนเส้นทางพวกเขาไปยังไซต์เวอร์ชันที่ปรับให้เหมาะสม

ตัวอย่าง: การเปลี่ยนเส้นทางผู้ใช้มือถือไปยัง Subdomain ที่ปรับให้เหมาะสมสำหรับมือถือ


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

ตัวอย่างนี้ใช้ไลบรารี `detection` เพื่อกำหนดประเภทอุปกรณ์ของผู้ใช้ตามส่วนหัว User-Agent หากผู้ใช้อยู่บนโทรศัพท์มือถือ พวกเขาจะถูกเปลี่ยนเส้นทางไปยัง subdomain m.example.com (โดยสมมติว่าคุณมีไซต์เวอร์ชันที่ปรับให้เหมาะสมสำหรับมือถือโฮสต์อยู่ที่นั่น) อย่าลืมติดตั้งแพ็กเกจ `detection`: `npm install detection`

ข้อควรพิจารณาโดยรวม: ตรวจสอบให้แน่ใจว่าตรรกะการตรวจจับอุปกรณ์ของคุณคำนึงถึงความแตกต่างในระดับภูมิภาคในการใช้อุปกรณ์ ตัวอย่างเช่น ฟีเจอร์โฟนยังคงแพร่หลายในประเทศกำลังพัฒนาบางประเทศ พิจารณาใช้การผสมผสานระหว่างการตรวจจับ User-Agent และเทคนิคการออกแบบที่ตอบสนอง เพื่อโซลูชันที่แข็งแกร่งยิ่งขึ้น

5. การเพิ่มคุณค่าส่วนหัวคำขอ

Middleware สามารถเพิ่มข้อมูลลงในส่วนหัวคำขอก่อนที่เส้นทางของแอปพลิเคชันของคุณจะประมวลผลได้ นี่เป็นประโยชน์สำหรับการเพิ่ม metadata ที่กำหนดเอง เช่น บทบาทผู้ใช้ สถานะการตรวจสอบสิทธิ์ หรือ ID คำขอ ที่ตรรกะแอปพลิเคชันของคุณสามารถใช้ได้

ตัวอย่าง: การเพิ่ม Request ID


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
}

Middleware นี้สร้าง Request ID ที่ไม่ซ้ำกันโดยใช้ไลบรารี uuid และเพิ่มลงในส่วนหัว x-request-id จากนั้น ID นี้สามารถใช้เพื่อวัตถุประสงค์ในการบันทึก การติดตาม และการแก้ไขข้อบกพร่องได้ อย่าลืมติดตั้งแพ็กเกจ `uuid`: `npm install uuid`

ข้อควรพิจารณาโดยรวม: เมื่อเพิ่มส่วนหัวที่กำหนดเอง ให้ระลึกถึงขีดจำกัดขนาดส่วนหัว การเกินขีดจำกัดเหล่านี้อาจนำไปสู่ข้อผิดพลาดที่ไม่คาดคิด นอกจากนี้ ตรวจสอบให้แน่ใจว่าข้อมูลที่ละเอียดอ่อนใดๆ ที่เพิ่มลงในส่วนหัวได้รับการปกป้องอย่างเหมาะสม โดยเฉพาะอย่างยิ่งหากแอปพลิเคชันของคุณอยู่เบื้องหลัง Reverse Proxy หรือ CDN

6. การปรับปรุงความปลอดภัย: การจำกัดอัตรา

Middleware สามารถทำหน้าที่เป็นแนวป้องกันแรกจากการโจมตีที่เป็นอันตรายโดยการใช้การจำกัดอัตรา การทำเช่นนี้จะป้องกันการละเมิดโดยการจำกัดจำนวนคำขอที่ไคลเอนต์สามารถทำได้ภายในช่วงเวลาที่กำหนด

ตัวอย่าง: การจำกัดอัตราขั้นพื้นฐานโดยใช้ Store อย่างง่าย


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
}

ตัวอย่างนี้จะเก็บรักษา Store ในหน่วยความจำอย่างง่าย (requestCounts) เพื่อติดตามจำนวนคำขอจากที่อยู่ IP แต่ละรายการ หากไคลเอนต์เกิน MAX_REQUESTS_PER_WINDOW ภายใน WINDOW_SIZE_MS middleware จะส่งคืนข้อผิดพลาด 429 Too Many Requests สำคัญ: นี่เป็นตัวอย่างที่ง่ายและไม่เหมาะสำหรับสภาพแวดล้อมการใช้งานจริง เนื่องจากไม่สามารถปรับขนาดได้และมีความเสี่ยงต่อการโจมตีแบบปฏิเสธการให้บริการ สำหรับการใช้งานจริง ให้พิจารณาใช้โซลูชันการจำกัดอัตราที่แข็งแกร่งยิ่งขึ้น เช่น Redis หรือบริการจำกัดอัตราโดยเฉพาะ

ข้อควรพิจารณาโดยรวม: กลยุทธ์การจำกัดอัตราควรปรับให้เหมาะกับลักษณะเฉพาะของแอปพลิเคชันของคุณ และการกระจายทางภูมิศาสตร์ของผู้ใช้ของคุณ พิจารณาใช้ขีดจำกัดอัตราที่แตกต่างกันสำหรับภูมิภาคหรือกลุ่มผู้ใช้ที่แตกต่างกัน

กรณีพิเศษและข้อผิดพลาดที่อาจเกิดขึ้น

แม้ว่า middleware จะเป็นเครื่องมือที่มีประสิทธิภาพ แต่สิ่งสำคัญคือต้องตระหนักถึงข้อจำกัดและข้อผิดพลาดที่อาจเกิดขึ้น:

แนวทางปฏิบัติที่ดีที่สุดสำหรับการใช้ Next.js Middleware

เพื่อให้ได้รับประโยชน์สูงสุดจาก Next.js middleware และหลีกเลี่ยงปัญหาที่อาจเกิดขึ้น ให้ปฏิบัติตามแนวทางปฏิบัติที่ดีที่สุดเหล่านี้:

สรุป

Next.js middleware นำเสนอวิธีที่มีประสิทธิภาพในการแก้ไขคำขอและปรับแต่งลักษณะการทำงานของแอปพลิเคชันของคุณที่ Edge การทำความเข้าใจรูปแบบการปรับเปลี่ยนคำขอขั้นสูงที่กล่าวถึงในคู่มือนี้ จะช่วยให้คุณสร้างแอปพลิเคชัน Next.js ที่แข็งแกร่ง มีประสิทธิภาพ และตระหนักถึงทั่วโลก อย่าลืมพิจารณากรณีพิเศษและข้อผิดพลาดที่อาจเกิดขึ้นอย่างรอบคอบ และปฏิบัติตามแนวทางปฏิบัติที่ดีที่สุดที่ระบุไว้ข้างต้นเพื่อให้แน่ใจว่าฟังก์ชัน middleware ของคุณมีความน่าเชื่อถือและบำรุงรักษาได้ง่าย ยอมรับพลังของ middleware เพื่อสร้างประสบการณ์ผู้ใช้ที่ยอดเยี่ยมและปลดล็อกความเป็นไปได้ใหม่ๆ สำหรับเว็บแอปพลิเคชันของคุณ