رسیدگی به درخواست های محدوده در یک کارگر خدماتی

مطمئن شوید که کارمند خدمات شما می داند که در صورت درخواست پاسخ جزئی چه کاری انجام دهد.

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

یک سرویس کار کد جاوا اسکریپت است که بین برنامه وب و شبکه شما قرار می گیرد و به طور بالقوه درخواست های شبکه خروجی را رهگیری می کند و برای آنها پاسخ ایجاد می کند.

از لحاظ تاریخی، درخواست‌های محدوده و کارگران خدمات به خوبی با هم بازی نکرده‌اند. لازم است اقدامات ویژه ای برای جلوگیری از نتایج بد در خدمتکار خود انجام دهید. خوشبختانه، این شروع به تغییر کرده است. در مرورگرهایی که رفتار درستی از خود نشان می‌دهند، درخواست‌های محدوده زمانی که از یک سرویس‌دهنده عبور می‌کنند «فقط کار می‌کنند».

موضوع چیست؟

یک سرویس‌کار را با شنونده رویداد fetch زیر در نظر بگیرید، که هر درخواست دریافتی را می‌گیرد و به شبکه ارسال می‌کند:

self.addEventListener('fetch', (event) => {
  // The Range: header will not pass through in
  // browsers that behave incorrectly.
  event.respondWith(fetch(event.request));
});

در مرورگرهایی که رفتار نادرست دارند، اگر event.request شامل یک هدر Range: باشد، آن سرصفحه بی‌صدا حذف می‌شود. درخواستی که توسط سرور راه دور دریافت شده است به هیچ وجه شامل Range: نمی شود. این لزوماً چیزی را "شکست" نمی کند، زیرا یک سرور از نظر فنی مجاز است که بدنه کامل پاسخ را با کد وضعیت 200 برگرداند، حتی زمانی که هدر Range: در درخواست اصلی وجود دارد. اما منجر به انتقال داده‌های بیشتری از آنچه از دیدگاه مرورگر نیاز است، می‌شود.

توسعه‌دهندگانی که از این رفتار آگاه بودند، می‌توانند با بررسی صریح وجود یک Range: header و عدم فراخوانی event.respondWith() در صورت وجود، آن را حل کنند. با انجام این کار، سرویس‌کار به طور موثر خود را از تصویر تولید پاسخ حذف می‌کند و به جای آن از منطق شبکه پیش‌فرض مرورگر، که می‌داند چگونه درخواست‌های محدوده را حفظ کند، استفاده می‌شود.

self.addEventListener('fetch', (event) => {
  // Return without calling event.respondWith()
  // if this is a range request.
  if (event.request.headers.has('range')) {
    return;
  }

  event.respondWith(fetch(event.request));
});

به جرات می توان گفت که اکثر توسعه دهندگان از نیاز به انجام این کار آگاه نبودند. و مشخص نبود که چرا باید مورد نیاز باشد. در نهایت، این محدودیت به دلیل نیاز مرورگرها به تغییرات در مشخصات اساسی بود که پشتیبانی از این عملکرد را اضافه کرد.

چه چیزی رفع شده است؟

مرورگرهایی که به درستی رفتار می کنند، هدر Range: را زمانی که event.request به fetch() ارسال می شود، حفظ می کنند. این بدان معناست که کد سرویس‌کار در مثال اولیه من به سرور راه دور اجازه می‌دهد تا هدر Range: را ببیند، در صورتی که توسط مرورگر تنظیم شده باشد:

self.addEventListener('fetch', (event) => {
  // The Range: header will pass through in browsers
  // that behave correctly.
  event.respondWith(fetch(event.request));
});

سرور اکنون این فرصت را دارد که درخواست محدوده را به درستی مدیریت کند و یک پاسخ جزئی با کد وضعیت 206 ارائه دهد.

کدام مرورگرها درست عمل می کنند؟

نسخه های اخیر سافاری عملکرد صحیحی دارند. کروم و اج که با نسخه 87 شروع می‌شوند نیز به درستی رفتار می‌کنند.

از اکتبر 2020، فایرفاکس هنوز این رفتار را برطرف نکرده است، بنابراین ممکن است همچنان لازم باشد در حین استقرار کد کارمند سرویس خود در تولید، آن را در نظر بگیرید.

بررسی ردیف «شامل سرصفحه محدوده در درخواست شبکه» داشبورد آزمایش‌های پلتفرم وب بهترین راه برای تأیید اینکه آیا مرورگر معینی این رفتار را اصلاح کرده است یا خیر.

در مورد سرویس درخواست‌های محدوده از حافظه پنهان چطور؟

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

همه مرورگرها، از جمله فایرفاکس، از بازرسی درخواست در یک کنترل کننده fetch ، بررسی وجود هدر Range: و سپس انجام درخواست به صورت محلی با یک پاسخ 206 که از حافظه پنهان می آید، پشتیبانی می کنند. با این حال، کد service worker برای تجزیه صحیح هدر Range: و برگرداندن تنها بخش مناسب از پاسخ ذخیره شده کامل، بی اهمیت نیست.

خوشبختانه، توسعه‌دهندگانی که کمک می‌خواهند می‌توانند به Workbox مراجعه کنند، که مجموعه‌ای از کتابخانه‌ها است که موارد استفاده از سرویس‌های رایج را ساده می‌کند. workbox-range-request module تمام منطق لازم برای ارائه پاسخ های جزئی را مستقیماً از حافظه پنهان پیاده سازی می کند. یک دستور کامل برای این مورد استفاده را می توان در اسناد Workbox پیدا کرد.

تصویر قهرمان در این پست توسط Natalie Rhea Riggs در Unsplash است.