URLPattern مسیریابی را به پلتفرم وب می آورد

منتشر شده: ۲۲ ژوئیه ۲۰۲۱

مسیریابی بخش کلیدی هر برنامه وب است. در قلب آن، مسیریابی یک URL را دریافت می‌کند، تطبیق الگو یا منطق خاص برنامه دیگری را روی آن اعمال می‌کند و سپس، معمولاً، محتوای وب را بر اساس نتیجه نمایش می‌دهد. مسیریابی ممکن است به روش‌های مختلفی پیاده‌سازی شود:

  • کد سرور که مسیرها را به فایل‌های روی دیسک نگاشت می‌کند
  • منطق در یک برنامه تک صفحه‌ای که منتظر تغییرات در مکان فعلی می‌ماند، سپس یک قطعه DOM مربوطه را ایجاد و نمایش می‌دهد.

اگرچه هیچ استاندارد قطعی وجود ندارد، توسعه‌دهندگان وب به سمت یک سینتکس مشترک برای بیان الگوهای مسیریابی URL گرایش پیدا کرده‌اند که اشتراکات زیادی با regular expressions دارد، اما برخی اضافات مختص دامنه مانند توکن‌ها برای تطبیق بخش‌های مسیر را نیز به همراه دارد. چارچوب‌های محبوب سمت سرور مانند Express و Ruby on Rails از این سینتکس (یا چیزی بسیار نزدیک به آن) استفاده می‌کنند و توسعه‌دهندگان جاوا اسکریپت می‌توانند از ماژول‌هایی مانند path-to-regexp یا regexpparam برای اضافه کردن این منطق به کد خود استفاده کنند.

URLPattern افزونه‌ای به پلتفرم وب است که بر پایه‌ی ایجاد شده توسط این چارچوب‌ها ساخته شده است. هدف آن استانداردسازی سینتکس الگوی مسیریابی، از جمله پشتیبانی از wildcardها، گروه‌های توکن نامگذاری شده، گروه‌های عبارت منظم و اصلاح‌کننده‌های گروه است. نمونه‌های URLPattern ایجاد شده با این سینتکس می‌توانند وظایف مسیریابی رایج، مانند تطبیق با URLهای کامل یا pathname URL و بازگرداندن اطلاعات مربوط به تطابق توکن و گروه را انجام دهند.

یکی دیگر از مزایای ارائه تطبیق URL به طور مستقیم در پلتفرم وب این است که یک سینتکس مشترک می‌تواند با سایر APIهایی که نیاز به تطبیق با URLها دارند، به اشتراک گذاشته شود.

پشتیبانی مرورگر و پلی‌فیل‌ها

URLPattern به طور پیش‌فرض در Chrome و Edge نسخه ۹۵ و بالاتر فعال است.

کتابخانه urlpattern-polyfill راهی برای استفاده از رابط URLPattern در مرورگرها یا محیط‌هایی مانند Node که فاقد پشتیبانی داخلی هستند، فراهم می‌کند. اگر از polyfill استفاده می‌کنید، مطمئن شوید که از تشخیص ویژگی استفاده می‌کنید تا مطمئن شوید که فقط در صورتی که محیط فعلی فاقد پشتیبانی باشد، آن را بارگذاری می‌کنید. در غیر این صورت، یکی از مزایای کلیدی URLPattern را از دست خواهید داد: این واقعیت که محیط‌های پشتیبانی برای استفاده از آن نیازی به دانلود و تجزیه کد اضافی ندارند.

if (!(globalThis && 'URLPattern' in globalThis)) {
  // URLPattern is not available, so the polyfill is needed.
}

سازگاری نحوی

فلسفه‌ی اصلی URLPattern اجتناب از نوآوری مجدد است. اگر از قبل با سینتکس مسیریابی مورد استفاده در Express یا Ruby on Rails آشنا هستید، نیازی به یادگیری چیز جدیدی ندارید. اما با توجه به تفاوت‌های جزئی بین سینتکس‌ها در کتابخانه‌های مسیریابی محبوب، باید چیزی به عنوان سینتکس پایه انتخاب می‌شد و طراحان URLPattern تصمیم گرفتند از سینتکس الگو از path-to-regexp (هرچند نه سطح API آن) به عنوان نقطه شروع استفاده کنند.

این تصمیم پس از مشورت دقیق با نگهدارنده فعلی path-to-regexp گرفته شد.

بهترین راه برای آشنایی با هسته‌ی سینتکس پشتیبانی‌شده، مراجعه به مستندات مربوط به path-to-regexp است. می‌توانید مستنداتی را که برای انتشار در MDN در نظر گرفته شده است، در خانه‌ی فعلی آن در گیت‌هاب مطالعه کنید.

ویژگی‌های اضافی

سینتکس URLPattern مجموعه‌ای فراتر از چیزی است که path-to-regexp پشتیبانی می‌کند، زیرا URLPattern از یک ویژگی غیرمعمول در بین کتابخانه‌های مسیریابی پشتیبانی می‌کند: تطبیق originها ، از جمله wildcardها در نام میزبان‌ها. اکثر کتابخانه‌های مسیریابی دیگر فقط با pathname و گاهی اوقات با بخش جستجو یا hash یک URL سر و کار دارند. آنها هرگز مجبور نیستند بخش origin یک URL را بررسی کنند، زیرا آنها فقط برای مسیریابی same-origin در یک برنامه وب مستقل استفاده می‌شوند.

در نظر گرفتن origins، دری را برای موارد استفاده اضافی، مانند مسیریابی درخواست‌های cross-origin درون کنترل‌کننده رویداد fetch در یک service worker ، باز می‌کند. اگر فقط URLهای same-origin را مسیریابی می‌کنید، می‌توانید این ویژگی اضافی را نادیده بگیرید و مانند سایر کتابخانه‌ها URLPattern استفاده کنید.

مثال‌ها

ساخت الگو

برای ایجاد یک URLPattern ، به سازنده‌ی آن یا رشته‌ها یا یک شیء که ویژگی‌های آن حاوی اطلاعاتی در مورد الگویی است که باید با آن مطابقت داده شود، ارسال کنید.

ارسال یک شیء، صریح‌ترین کنترل را بر روی الگویی که برای تطبیق هر جزء URL استفاده می‌شود، ارائه می‌دهد. در طولانی‌ترین حالت، این می‌تواند به شکل زیر باشد:

const p = new URLPattern({
  protocol: 'https',
  username: '',
  password: '',
  hostname: 'example.com',
  port: '',
  pathname: '/foo/:image.jpg',
  search: '*',
  hash: '*',
});

ارائه یک رشته خالی برای یک ویژگی، تنها در صورتی مطابقت خواهد داشت که بخش مربوطه در URL تنظیم نشده باشد. علامت * هر مقداری را برای بخش مشخصی از URL مطابقت می‌دهد.

سازنده چندین میانبر برای استفاده ساده‌تر ارائه می‌دهد. حذف کامل search و hash یا هر ویژگی دیگر، معادل تنظیم آنها با wildcard '*' است. مثال را می‌توان به صورت زیر ساده کرد:

const p = new URLPattern({
  protocol: 'https',
  username: '',
  password: '',
  hostname: 'example.com',
  port: '',
  pathname: '/foo/:image.jpg',
});

به عنوان یک میانبر اضافی، تمام اطلاعات مربوط به مبدا را می‌توان در یک ویژگی واحد، baseURL ، ارائه داد که منجر به

const p = new URLPattern({
  pathname: '/foo/:image.jpg',
  baseURL: 'https://example.com',
});

همه این مثال‌ها فرض می‌کنند که مورد استفاده شما شامل تطبیق مبداها می‌شود. اگر فقط به تطبیق در بخش‌های دیگر URL، به جز مبدا علاقه‌مند هستید (همانطور که در بسیاری از سناریوهای مسیریابی تک مبدایی اتفاق می‌افتد)، می‌توانید اطلاعات مبدا را به طور کامل حذف کنید و فقط ترکیبی از ویژگی‌های pathname ، search و hash را ارائه دهید. مانند قبل، با ویژگی‌های حذف شده طوری رفتار می‌شود که گویی با الگوی wildcard * تنظیم شده‌اند.

const p = new URLPattern({pathname: '/foo/:image.jpg'});

به عنوان جایگزینی برای ارسال یک شیء به سازنده، می‌توانید یک یا دو رشته ارائه دهید. اگر یک رشته ارائه شود، باید یک الگوی کامل URL، از جمله اطلاعات الگوی مورد استفاده برای مطابقت با مبدا را نشان دهد. اگر دو رشته ارائه دهید، رشته دوم به عنوان یک baseURL استفاده می‌شود و رشته اول نسبت به آن پایه در نظر گرفته می‌شود.

چه یک رشته ارائه شود و چه دو رشته، سازنده‌ی URLPattern الگوی کامل URL را تجزیه می‌کند، آن را به اجزای URL تقسیم می‌کند و هر بخش از الگوی بزرگتر را به جزء مربوطه نگاشت می‌کند. این بدان معناست که در باطن، هر URLPattern ایجاد شده با رشته‌ها در نهایت مانند یک URLPattern معادل ایجاد شده با یک شیء نمایش داده می‌شود. سازنده‌ی رشته‌ها فقط یک میانبر است، برای کسانی که رابط کاربری ساده‌تری را ترجیح می‌دهند.

const p = new URLPattern('https://example.com/foo/:image.jpg?*#*');

هنگام استفاده از رشته‌ها برای ایجاد یک URLPattern ، چند نکته وجود دارد که باید در نظر داشته باشید.

حذف یک ویژگی هنگام استفاده از یک شیء برای ساخت URLPattern معادل ارائه یک کاراکتر جایگزین * برای آن ویژگی است. هنگامی که الگوی رشته URL کامل تجزیه می‌شود، اگر یکی از اجزای URL مقداری را از دست داده باشد، طوری رفتار می‌شود که گویی ویژگی آن مؤلفه روی '' تنظیم شده است، که فقط زمانی مطابقت دارد که آن مؤلفه خالی باشد.

هنگام استفاده از رشته‌ها، اگر می‌خواهید از wildcardها در URLPattern ساخته شده استفاده شود، باید آنها را صریحاً وارد کنید.

// p1 and p2 are equivalent.
const p1 = new URLPattern('/foo', location.origin);
const p2 = new URLPattern({
  protocol: location.protocol,
  hostname: location.hostname,
  pathname: '/foo',
  search: '',
  hash: '',
});

// p3 and p4 are equivalent.
const p3 = new URLPattern('/foo?*#*', location.origin);
const p4 = new URLPattern({
  protocol: location.protocol,
  hostname: location.hostname,
  pathname: '/foo',
});

همچنین باید توجه داشته باشید که تجزیه یک الگوی رشته‌ای به اجزای آن می‌تواند مبهم باشد. کاراکترهایی مانند : وجود دارند که در URLها یافت می‌شوند، اما در سینتکس تطبیق الگو نیز معنای خاصی دارند. برای جلوگیری از این ابهام، سازنده URLPattern فرض می‌کند که هر یک از این کاراکترهای خاص بخشی از یک الگو هستند، نه بخشی از URL. اگر می‌خواهید یک کاراکتر مبهم به عنوان بخشی از URL تفسیر شود، حتماً آن را با \` character. For example, the literal URL about:blank وقتی به عنوان یک رشته ارائه می‌شود، should be escaped as .

از الگو استفاده کنید

پس از ساخت یک URLPattern ، دو گزینه برای استفاده از آن دارید. متدهای test() و exec() هر دو ورودی یکسانی را دریافت می‌کنند و از الگوریتم یکسانی برای بررسی تطابق استفاده می‌کنند و فقط در مقدار بازگشتی خود متفاوت هستند. test() در صورت وجود تطابق برای ورودی داده شده، مقدار true و در غیر این صورت false را برمی‌گرداند. exec() اطلاعات دقیقی در مورد تطابق به همراه گروه‌های ضبط را برمی‌گرداند، یا در صورت عدم تطابق null برمی‌گرداند. مثال‌های زیر نحوه استفاده از exec() را نشان می‌دهند، اما اگر فقط مقدار بازگشتی بولی می‌خواهید، می‌توانید برای هر یک از آنها از test() استفاده کنید.

یک راه برای استفاده از متدهای test() و exec() ارسال رشته‌ها است. مشابه آنچه سازنده پشتیبانی می‌کند، اگر یک رشته ارائه شود، باید یک URL کامل، شامل مبدا، باشد. اگر دو رشته ارائه شود، رشته دوم به عنوان یک مقدار baseURL در نظر گرفته می‌شود و رشته اول نسبت به آن پایه ارزیابی می‌شود.

const p = new URLPattern({
  pathname: '/foo/:image.jpg',
  baseURL: 'https://example.com',
});

const result = p.exec('https://example.com/foo/cat.jpg');
// result will contain info about the successful match.
// const result = p.exec('/foo/cat.jpg', 'https://example.com')
// is equivalent, using the baseURL syntax.

const noMatchResult = p.exec('https://example.com/bar');
// noMatchResult will be null.

به عنوان یک روش جایگزین، می‌توانید همان نوع شیء را که سازنده پشتیبانی می‌کند، با ویژگی‌هایی که فقط روی بخش‌هایی از URL که تطبیق آنها برایتان مهم است تنظیم شده‌اند، ارسال کنید.

const p = new URLPattern({pathname: '/foo/:image.jpg'});

const result = p.exec({pathname: '/foo/:image.jpg'});
// result will contain info about the successful match.

هنگام استفاده از exec() روی یک URLPattern که حاوی wildcards یا tokens است، مقدار برگشتی اطلاعاتی در مورد مقادیر متناظر در URL ورودی به شما می‌دهد. این می‌تواند دردسر تجزیه و تحلیل آن مقادیر را برای شما از بین ببرد.

const p = new URLPattern({
  hostname: ':subdomain.example.com',
  pathname: '/*/:image.jpg'
});

const result = p.exec('https://imagecdn1.example.com/foo/cat.jpg');
// result.hostname.groups.subdomain will be 'imagecdn1'
// result.pathname.groups[0] will be 'foo', corresponding to *
// result.pathname.groups.image will be 'cat'

گروه‌های ناشناس و دارای نام

وقتی یک رشته URL را به exec() ارسال می‌کنید، مقداری را برمی‌گردانید که به شما می‌گوید کدام بخش‌ها با تمام گروه‌های الگو مطابقت دارند.

مقدار برگشتی دارای ویژگی‌هایی است که با اجزای URLPattern مطابقت دارند، مانند pathname . بنابراین اگر گروهی به عنوان بخشی از بخش pathname در URLPattern تعریف شده باشد، می‌توان تطابق‌ها را در pathname.groups مقدار برگشتی یافت. تطابق‌ها بسته به اینکه الگوی مربوطه یک گروه ناشناس یا با نام بوده باشد، به طور متفاوتی نمایش داده می‌شوند.

شما می‌توانید از اندیس‌های آرایه برای دسترسی به مقادیر مربوط به یک الگوی ناشناس استفاده کنید. اگر چندین الگوی ناشناس وجود داشته باشد، اندیس 0 نشان‌دهنده مقدار تطبیق برای الگوی سمت چپ است و اندیس‌های 1 و بالاتر برای الگوهای بعدی استفاده می‌شوند.

هنگام استفاده از گروه‌های نامگذاری شده در یک الگو، موارد منطبق به عنوان ویژگی‌هایی نمایش داده می‌شوند که نام آنها با نام هر گروه مطابقت دارد.

پشتیبانی از یونیکد و نرمال‌سازی

URLPattern از کاراکترهای یونیکد به چند روش مختلف پشتیبانی می‌کند.

  • گروه‌های نامگذاری شده، مانند :café ، می‌توانند شامل کاراکترهای یونیکد باشند. قوانینی که برای شناسه‌های معتبر جاوا اسکریپت استفاده می‌شوند، برای گروه‌های نامگذاری شده نیز اعمال می‌شوند.

  • متن درون یک الگو به طور خودکار طبق همان قوانینی که برای کدگذاری URL آن جزء خاص استفاده می‌شود، کدگذاری می‌شود. کاراکترهای یونیکد درون pathname به صورت درصد-کدگذاری می‌شوند، بنابراین یک الگوی pathname مانند /café به طور خودکار به /caf%C3%A9 نرمال‌سازی می‌شود. کاراکترهای یونیکد در hostname به طور خودکار با استفاده از Punycode به جای درصد-کدگذاری کدگذاری می‌شوند.

  • گروه‌های عبارت منظم باید فقط شامل کاراکترهای ASCII باشند. سینتکس عبارت منظم، کدگذاری خودکار کاراکترهای یونیکد در این گروه‌ها را دشوار و ناامن می‌کند. اگر می‌خواهید یک کاراکتر یونیکد را در یک گروه عبارت منظم مطابقت دهید، باید آن را به صورت دستی کدگذاری درصدی کنید، مانند (caf%C3%A9) برای مطابقت با café .

URLPattern علاوه بر رمزگذاری کاراکترهای یونیکد، نرمال‌سازی URL را نیز انجام می‌دهد. برای مثال، /foo/./bar در کامپوننت pathname به معادل /foo/bar تبدیل می‌شود.

وقتی در مورد نحوه نرمال‌سازی یک الگوی ورودی مشخص شک دارید، نمونه URLPattern ساخته شده را با استفاده از DevTools مرورگر خود بررسی کنید.

همه را کنار هم بگذارید

دموی Glitch یک مورد استفاده اصلی از URLPattern را در داخل fetch event handler یک سرویس‌دهنده نشان می‌دهد و الگوهای خاصی را به توابع ناهمزمان نگاشت می‌کند که می‌توانند پاسخی به درخواست‌های شبکه ایجاد کنند. مفاهیم موجود در این مثال را می‌توان در سایر سناریوهای مسیریابی، چه در سمت سرور و چه در سمت کلاینت، نیز به کار برد.

بازخورد و برنامه‌های آینده

اگرچه قابلیت‌های اولیه‌ی URLPattern به کروم و اج راه پیدا کرده است، اما قرار است قابلیت‌های بیشتری به آن اضافه شود. برخی از جنبه‌های URLPattern هنوز در حال توسعه هستند و تعدادی سوال بی‌پاسخ در مورد رفتارهای خاص وجود دارد که ممکن است هنوز نیاز به اصلاح داشته باشند. ما شما را تشویق می‌کنیم که URLPattern امتحان کنید و هرگونه بازخوردی را از طریق GitHub issue ارائه دهید.

پشتیبانی از قالب‌بندی

کتابخانه‌ی path-to-regexp یک compile() function ارائه می‌دهد که به طور مؤثر رفتار مسیریابی را معکوس می‌کند. compile() یک الگو و مقادیری برای متغیرهای توکن می‌گیرد و رشته‌ای برای یک مسیر URL با آن مقادیر جایگزین شده برمی‌گرداند.

ما امیدواریم که در آینده این مورد را به URLPattern اضافه کنیم ، اما در محدوده انتشار اولیه نیست.

ویژگی‌های پلتفرم وب آینده را فعال کنید

با فرض اینکه URLPattern به بخش تثبیت‌شده‌ای از پلتفرم وب تبدیل شود، سایر ویژگی‌هایی که می‌توانند از مسیریابی یا تطبیق الگو بهره‌مند شوند، می‌توانند به عنوان یک عنصر اولیه بر روی آن ساخته شوند.

بحث‌های مداومی در مورد استفاده از URLPattern برای ویژگی‌های پیشنهادی مانند تطبیق الگو در محدوده‌ی سرویس‌دهنده ، PWAها به عنوان کنترل‌کننده‌های فایل و پیش‌واکشی احتمالی وجود دارد.

برای مشاهده فهرست کامل تقدیرنامه‌ها، به سند توضیحی اصلی مراجعه کنید.