رؤوس HTTP
تسمح لك الرؤوس (Headers) بتعيين رؤوس HTTP مخصصة على الاستجابة لطلب وارد على مسار معين.
لتعيين رؤوس HTTP مخصصة، يمكنك استخدام مفتاح headers
في ملف 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
.
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
(بدون مسارات متداخلة):
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
:
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
:
module.exports = {
async headers() {
return [
{
source: '/blog/:post(\\d{1,})',
headers: [
{
key: 'x-post',
value: ':post',
},
],
},
]
},
}
الأحرف التالية (
, )
, {
, }
, :
, *
, +
, ?
تُستخدم لمطابقة مسار regex، لذا عند استخدامها في source
كقيم غير خاصة يجب الهروب منها بإضافة \\
قبلها:
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
.
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',
// لن تكون قيمة الصفحة متاحة في
// مفاتيح/قيم الرأس حيث يتم توفير القيمة و
// لا تستخدم مجموعة capture مسماة مثل (?<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
إلى الرأس:
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
بلغة ليتم مطابقتها بشكل صحيح.
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` هي defaultLocale
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
للصفحات أو الأصول، حيث سيتم تجاوز هذه الرؤوس في الإنتاج لضمان تخزين الاستجابات والأصول الثابتة بشكل فعال.
تعلم المزيد عن التخزين المؤقت مع موجه التطبيق.
الخيارات
X-DNS-Prefetch-Control
هذا الرأس يتحكم في prefetching لـ DNS، مما يسمح للمتصفحات بإجراء تحليل اسم النطاق بشكل استباقي للروابط الخارجية والصور وCSS وJavaScript وغير ذلك. يتم تنفيذ هذا prefetching في الخلفية، بحيث يكون 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
هذا الرأس يتحكم في مقدار المعلومات التي يدرجها المتصفح عند الانتقال من الموقع الحالي (origin) إلى موقع آخر.
{
key: 'Referrer-Policy',
value: 'origin-when-cross-origin'
}
Content-Security-Policy
تعلم المزيد عن إضافة سياسة أمان المحتوى إلى تطبيقك.
سجل الإصدارات
الإصدار | التغييرات |
---|---|
v13.3.0 | تمت إضافة missing . |
v10.2.0 | تمت إضافة has . |
v9.5.0 | تمت إضافة الرؤوس. |