رؤوس (headers)

تسمح لك الرؤوس بتعيين رؤوس HTTP مخصصة على الاستجابة لطلب وارد على مسار معين.

لتعيين رؤوس HTTP مخصصة، يمكنك استخدام مفتاح headers في ملف next.config.js:

next.config.js
module.exports = {
  async headers() {
    return [
      {
        source: '/about',
        headers: [
          {
            key: 'x-custom-header',
            value: 'قيمة الرأس المخصصة',
          },
          {
            key: 'x-another-custom-header',
            value: 'قيمة الرأس المخصصة الأخرى',
          },
        ],
      },
    ]
  },
}

headers هي دالة غير متزامنة تتوقع إرجاع مصفوفة تحتوي على كائنات ذات خصائص source و headers:

  • source: نمط مسار الطلب الوارد.
  • headers: مصفوفة من كائنات رأس الاستجابة، مع خصائص key و value.
  • basePath: false أو undefined - إذا كانت false فلن يتم تضمين basePath عند المطابقة، يمكن استخدامه لإعادة التوجيه الخارجية فقط.
  • locale: false أو undefined - ما إذا كان يجب عدم تضمين اللغة عند المطابقة.
  • has: مصفوفة من كائنات has مع خصائص type و key و value.
  • missing: مصفوفة من كائنات missing مع خصائص type و key و value.

يتم التحقق من الرؤوس قبل نظام الملفات الذي يتضمن الصفحات وملفات /public.

سلوك تجاوز الرؤوس

إذا تطابق رأسان على نفس المسار وقاما بتعيين نفس مفتاح الرأس، فإن آخر مفتاح رأس سيتجاوز الأول. باستخدام الرؤوس أدناه، سيؤدي المسار /hello إلى أن يكون الرأس x-hello بقيمة world لأن آخر قيمة رأس تم تعيينها هي world.

next.config.js
module.exports = {
  async headers() {
    return [
      {
        source: '/:path*',
        headers: [
          {
            key: 'x-hello',
            value: 'there',
          },
        ],
      },
      {
        source: '/hello',
        headers: [
          {
            key: 'x-hello',
            value: 'world',
          },
        ],
      },
    ]
  },
}

مطابقة المسار

يتم السماح بمطابقة المسارات، على سبيل المثال /blog/:slug ستطابق /blog/hello-world (بدون مسارات متداخلة):

next.config.js
module.exports = {
  async headers() {
    return [
      {
        source: '/blog/:slug',
        headers: [
          {
            key: 'x-slug',
            value: ':slug', // يمكن استخدام المعلمات المتطابقة في القيمة
          },
          {
            key: 'x-slug-:slug', // يمكن استخدام المعلمات المتطابقة في المفتاح
            value: 'قيمة الرأس المخصصة الأخرى',
          },
        ],
      },
    ]
  },
}

مطابقة مسار Wildcard

لمطابقة مسار wildcard، يمكنك استخدام * بعد معلمة، على سبيل المثال /blog/:slug* ستطابق /blog/a/b/c/d/hello-world:

next.config.js
module.exports = {
  async headers() {
    return [
      {
        source: '/blog/:slug*',
        headers: [
          {
            key: 'x-slug',
            value: ':slug*', // يمكن استخدام المعلمات المتطابقة في القيمة
          },
          {
            key: 'x-slug-:slug*', // يمكن استخدام المعلمات المتطابقة في المفتاح
            value: 'قيمة الرأس المخصصة الأخرى',
          },
        ],
      },
    ]
  },
}

مطابقة مسار Regex

لمطابقة مسار regex، يمكنك لف regex بين قوسين بعد معلمة، على سبيل المثال /blog/:slug(\\d{1,}) ستطابق /blog/123 ولكن ليس /blog/abc:

next.config.js
module.exports = {
  async headers() {
    return [
      {
        source: '/blog/:post(\\d{1,})',
        headers: [
          {
            key: 'x-post',
            value: ':post',
          },
        ],
      },
    ]
  },
}

الأحرف التالية (, ), {, }, :, *, +, ? تستخدم لمطابقة مسار regex، لذا عند استخدامها في source كقيم غير خاصة يجب الهروب منها بإضافة \\ قبلها:

next.config.js
module.exports = {
  async headers() {
    return [
      {
        // هذا سيطابق `/english(default)/something` عند الطلب
        source: '/english\\(default\\)/:slug',
        headers: [
          {
            key: 'x-header',
            value: 'value',
          },
        ],
      },
    ]
  },
}

مطابقة الرأس، الكوكي، والاستعلام

لتطبيق رأس فقط عندما تتطابق قيم الرأس أو الكوكي أو الاستعلام مع حقل has أو لا تتطابق مع حقل missing، يمكن استخدام has و missing. يجب أن يتطابق كل من source وجميع عناصر has وألا تتطابق جميع عناصر missing لتطبيق الرأس.

يمكن أن تحتوي عناصر has و missing على الحقول التالية:

  • type: String - يجب أن يكون إما header أو cookie أو host أو query.
  • key: String - المفتاح من النوع المحدد للمطابقة ضده.
  • value: String أو undefined - القيمة للتحقق منها، إذا كانت undefined فإن أي قيمة ستطابق. يمكن استخدام سلسلة تشبه regex لالتقاط جزء معين من القيمة، على سبيل المثال إذا تم استخدام القيمة first-(?<paramName>.*) لـ first-second فإن second ستكون قابلة للاستخدام في الوجهة مع :paramName.
next.config.js
module.exports = {
  async headers() {
    return [
      // إذا كان الرأس `x-add-header` موجودًا،
      // سيتم تطبيق الرأس `x-another-header`
      {
        source: '/:path*',
        has: [
          {
            type: 'header',
            key: 'x-add-header',
          },
        ],
        headers: [
          {
            key: 'x-another-header',
            value: 'hello',
          },
        ],
      },
      // إذا كان الرأس `x-no-header` غير موجود،
      // سيتم تطبيق الرأس `x-another-header`
      {
        source: '/:path*',
        missing: [
          {
            type: 'header',
            key: 'x-no-header',
          },
        ],
        headers: [
          {
            key: 'x-another-header',
            value: 'hello',
          },
        ],
      },
      // إذا تمت مطابقة المصدر والاستعلام والكوكي،
      // سيتم تطبيق الرأس `x-authorized`
      {
        source: '/specific/:path*',
        has: [
          {
            type: 'query',
            key: 'page',
            // لن تكون قيمة الصفحة متاحة في
            // مفاتيح/قيم الرأس حيث يتم توفير القيمة و
            // لا تستخدم مجموعة التقاط مسماة مثل (?<page>home)
            value: 'home',
          },
          {
            type: 'cookie',
            key: 'authorized',
            value: 'true',
          },
        ],
        headers: [
          {
            key: 'x-authorized',
            value: ':authorized',
          },
        ],
      },
      // إذا كان الرأس `x-authorized` موجودًا و
      // يحتوي على قيمة مطابقة، سيتم تطبيق `x-another-header`
      {
        source: '/:path*',
        has: [
          {
            type: 'header',
            key: 'x-authorized',
            value: '(?<authorized>yes|true)',
          },
        ],
        headers: [
          {
            key: 'x-another-header',
            value: ':authorized',
          },
        ],
      },
      // إذا كان المضيف هو `example.com`،
      // سيتم تطبيق هذا الرأس
      {
        source: '/:path*',
        has: [
          {
            type: 'host',
            value: 'example.com',
          },
        ],
        headers: [
          {
            key: 'x-another-header',
            value: ':authorized',
          },
        ],
      },
    ]
  },
}

الرؤوس مع دعم basePath

عند استخدام دعم basePath مع الرؤوس، يتم تلقائيًا إضافة بادئة basePath إلى كل source ما لم تقم بإضافة basePath: false إلى الرأس:

next.config.js
module.exports = {
  basePath: '/docs',

  async headers() {
    return [
      {
        source: '/with-basePath', // تصبح /docs/with-basePath
        headers: [
          {
            key: 'x-hello',
            value: 'world',
          },
        ],
      },
      {
        source: '/without-basePath', // لا يتم تعديلها حيث تم تعيين basePath: false
        headers: [
          {
            key: 'x-hello',
            value: 'world',
          },
        ],
        basePath: false,
      },
    ]
  },
}

الرؤوس مع دعم i18n

عند استخدام دعم i18n مع الرؤوس، يتم تلقائيًا إضافة بادئة إلى كل source للتعامل مع locales المكونة ما لم تقم بإضافة locale: false إلى الرأس. إذا تم استخدام locale: false فيجب إضافة بادئة اللغة إلى source لمطابقتها بشكل صحيح.

next.config.js
module.exports = {
  i18n: {
    locales: ['en', 'fr', 'de'],
    defaultLocale: 'en',
  },

  async headers() {
    return [
      {
        source: '/with-locale', // يتعامل تلقائيًا مع جميع اللغات
        headers: [
          {
            key: 'x-hello',
            value: 'world',
          },
        ],
      },
      {
        // لا يتعامل مع اللغات تلقائيًا حيث تم تعيين locale: false
        source: '/nl/with-locale-manual',
        locale: false,
        headers: [
          {
            key: 'x-hello',
            value: 'world',
          },
        ],
      },
      {
        // هذا يطابق '/' حيث أن `en` هي اللغة الافتراضية
        source: '/en',
        locale: false,
        headers: [
          {
            key: 'x-hello',
            value: 'world',
          },
        ],
      },
      {
        // يتم تحويل هذا إلى /(en|fr|de)/(.*) لذا لن يطابق
        // المسارات الأساسية `/` أو `/fr` مثل /:path*
        source: '/(.*)',
        headers: [
          {
            key: 'x-hello',
            value: 'world',
          },
        ],
      },
    ]
  },
}

التحكم في التخزين المؤقت (Cache-Control)

لا يمكنك تعيين رؤوس Cache-Control في next.config.js للصفحات أو الأصول، حيث سيتم تجاوز هذه الرؤوس في الإنتاج لضمان تخزين الاستجابات والأصول الثابتة بشكل فعال.

إذا كنت بحاجة إلى إعادة التحقق من التخزين المؤقت لصفحة تم إنشاؤها بشكل ثابت، يمكنك القيام بذلك عن طريق تعيين خاصية revalidate في دالة getStaticProps للصفحة.

يمكنك تعيين رأس Cache-Control في مسارات API باستخدام طريقة res.setHeader:

import type { NextApiRequest, NextApiResponse } from 'next'

type ResponseData = {
  message: string
}

export default function handler(
  req: NextApiRequest,
  res: NextApiResponse<ResponseData>
) {
  res.setHeader('Cache-Control', 's-maxage=86400')
  res.status(200).json({ message: 'Hello from Next.js!' })
}
export default function handler(req, res) {
  res.setHeader('Cache-Control', 's-maxage=86400')
  res.status(200).json({ message: 'Hello from Next.js!' })
}

الخيارات

CORS

مشاركة الموارد عبر المصادر (CORS) هي ميزة أمان تسمح لك بالتحكم في المواقع التي يمكنها الوصول إلى مواردك. يمكنك تعيين رأس Access-Control-Allow-Origin للسماح لمصدر معين بالوصول إلى نقاط نهاية API الخاصة بك.

async headers() {
    return [
      {
        source: "/api/:path*",
        headers: [
          {
            key: "Access-Control-Allow-Origin",
            value: "*", // تعيين المصدر الخاص بك
          },
          {
            key: "Access-Control-Allow-Methods",
            value: "GET, POST, PUT, DELETE, OPTIONS",
          },
          {
            key: "Access-Control-Allow-Headers",
            value: "Content-Type, Authorization",
          },
        ],
      },
    ];
  },

X-DNS-Prefetch-Control

هذا الرأس يتحكم في جلب DNS مسبقًا، مما يسمح للمتصفحات بإجراء تحليل اسم النطاق استباقيًا على الروابط الخارجية والصور وCSS وJavaScript وغير ذلك. يتم تنفيذ هذا الجلب المسبق في الخلفية، لذا يكون DNS أكثر احتمالية لحلها بحلول الوقت الذي تكون فيه العناصر المشار إليها مطلوبة. هذا يقلل من زمن الوصول عندما ينقر المستخدم على رابط.

{
  key: 'X-DNS-Prefetch-Control',
  value: 'on'
}

Strict-Transport-Security

هذا الرأس يخبر المتصفحات أنه يجب الوصول إليه فقط باستخدام HTTPS، بدلاً من استخدام HTTP. باستخدام التكوين أدناه، ستستخدم جميع النطاقات الفرعية الحالية والمستقبلية HTTPS لمدة max-age تبلغ سنتين. هذا يمنع الوصول إلى الصفحات أو النطاقات الفرعية التي يمكن تقديمها فقط عبر HTTP.

إذا كنت تقوم بالنشر على Vercel، فإن هذا الرأس ليس ضروريًا حيث يتم إضافته تلقائيًا إلى جميع عمليات النشر ما لم تعلن عن headers في ملف next.config.js الخاص بك.

{
  key: 'Strict-Transport-Security',
  value: 'max-age=63072000; includeSubDomains; preload'
}

X-Frame-Options

هذا الرأس يشير إلى ما إذا كان يجب السماح بعرض الموقع داخل iframe. يمكن أن يمنع هذا من هجمات clickjacking.

تم استبدال هذا الرأس بخيار frame-ancestors في CSP، والذي يتمتع بدعم أفضل في المتصفحات الحديثة (راجع سياسة أمان المحتوى للحصول على تفاصيل التكوين).

{
  key: 'X-Frame-Options',
  value: 'SAMEORIGIN'
}

Permissions-Policy

هذا الرأس يسمح لك بالتحكم في الميزات وواجهات برمجة التطبيقات التي يمكن استخدامها في المتصفح. كان يُعرف سابقًا باسم Feature-Policy.

{
  key: 'Permissions-Policy',
  value: 'camera=(), microphone=(), geolocation=(), browsing-topics=()'
}

X-Content-Type-Options

هذا الرأس يمنع المتصفح من محاولة تخمين نوع المحتوى إذا لم يتم تعيين رأس Content-Type بشكل صريح. يمكن أن يمنع هذا من استغلال XSS للمواقع التي تسمح للمستخدمين بتحميل ومشاركة الملفات.

على سبيل المثال، قد يحاول مستخدم تنزيل صورة، ولكن يتم معاملتها كنوع Content-Type مختلف مثل ملف قابل للتنفيذ، والذي قد يكون ضارًا. ينطبق هذا الرأس أيضًا على تنزيل ملحقات المتصفح. القيمة الوحيدة الصالحة لهذا الرأس هي nosniff.

{
  key: 'X-Content-Type-Options',
  value: 'nosniff'
}

Referrer-Policy

هذا الرأس يتحكم في مقدار المعلومات التي يدرجها المتصفح عند الانتقال من الموقع الحالي (المصدر) إلى موقع آخر.

{
  key: 'Referrer-Policy',
  value: 'origin-when-cross-origin'
}

سياسة أمان المحتوى (Content-Security-Policy)

تعرف على المزيد حول إضافة سياسة أمان المحتوى إلى تطبيقك.

سجل الإصدارات

الإصدارالتغييرات
v13.3.0تمت إضافة missing.
v10.2.0تمت إضافة has.
v9.5.0تمت إضافة الرؤوس.