در پست وبلاگ «وباپلیکیشنهای پیشرونده در سایتهای چندمنبعی» ، دمیان در مورد چالشهایی که سایتهای ساختهشده بر روی چندین منبع هنگام تلاش برای ساخت یک وباپلیکیشن پیشرونده واحد که شامل همه آنها باشد، با آن مواجه میشوند، بحث کرد.
نمونهای از این نوع معماری سایت، یک سایت تجارت الکترونیک است که در آن:
- صفحه اصلی در
https://www.example.comاست. - صفحات دستهبندی در
https://category.example.comمیزبانی میشوند. - صفحات جزئیات محصول در
https://product.example.com.
همانطور که در مقاله بحث شد، سیاست same-origin محدودیتهای متعددی را اعمال میکند و از به اشتراک گذاشتن service workerها، cacheها و مجوزها بین originها جلوگیری میکند. به همین دلیل، اکیداً توصیه میکنیم از این نوع پیکربندی اجتناب کنید و برای کسانی که از قبل سایتهایی به این روش ساختهاند، در صورت امکان، مهاجرت به معماری سایت single origin را در نظر بگیرید.

در این پست، نگاهی به حالت مخالف میاندازیم: به جای یک PWA واحد در مبداهای مختلف، حالت شرکتهایی را بررسی خواهیم کرد که میخواهند چندین PWA ارائه دهند و از نام دامنه یکسان بهره ببرند و به کاربر اطلاع دهند که آن PWAها متعلق به یک سازمان یا سرویس هستند.
همانطور که ممکن است متوجه شده باشید، ما از اصطلاحات متفاوت اما مرتبط با هم، مانند دامنهها و مبداها، استفاده میکنیم. قبل از ادامه، این مفاهیم را مرور کنید.
اصطلاحات فنی
- دامنه: هر دنباله از برچسبها که در سامانه نام دامنه (DNS) تعریف شده است. برای مثال:
comوexample.comدامنه هستند. - نام میزبان: یک ورودی DNS که حداقل به یک آدرس IP تبدیل میشود. برای مثال:
www.example.comیک نام میزبان خواهد بود،example.comمیتواند یک نام میزبان باشد اگر آدرس IP داشته باشد، وcomهرگز به یک آدرس IP تبدیل نمیشود و بنابراین هرگز نمیتواند یک نام میزبان باشد. - مبدا: ترکیبی از یک طرح، نام میزبان و (اختیاری) پورت. برای مثال،
https://www.example.com:443یک مبدا است.
همانطور که از نامش پیداست، سیاست same-origin محدودیتهایی را بر روی originها اعمال میکند، بنابراین ما در طول مقاله بیشتر به این اصطلاح اشاره خواهیم کرد. با این وجود، ما هر از گاهی از «دامنهها» یا «زیردامنهها» برای توصیف تکنیک مورد استفاده برای ایجاد «originهای» مختلف استفاده خواهیم کرد.
موردی برای PWA های چندگانه و مرتبط
در برخی موارد، ممکن است بخواهید برنامههای مستقلی بسازید، اما همچنان آنها را متعلق به یک سازمان یا "برند" معرفی کنید. استفاده مجدد از نام دامنه یکسان، راه خوبی برای ایجاد این رابطه است. به عنوان مثال:
- یک سایت تجارت الکترونیک میخواهد یک تجربه مستقل ایجاد کند تا فروشندگان بتوانند موجودی خود را مدیریت کنند، در عین حال مطمئن شوند که این موجودی متعلق به وبسایت اصلی است که کاربران از آنجا محصولات را خریداری میکنند.
- یک سایت خبری ورزشی میخواهد یک اپلیکیشن خاص برای یک رویداد ورزشی مهم بسازد، به کاربران اجازه دهد آمار مربوط به مسابقات مورد علاقه خود را با استفاده از اعلانها دریافت کنند و آن را به عنوان یک اپلیکیشن وب پیشرونده نصب کنند، در حالی که مطمئن میشود کاربران آن را به عنوان اپلیکیشنی که توسط شرکت خبری ساخته شده است، تشخیص میدهند.
- یک شرکت میخواهد برنامههای چت، ایمیل و تقویم جداگانهای بسازد و میخواهد که آنها به عنوان برنامههای مستقل، مرتبط با نام شرکت، کار کنند.

از ریشههای جداگانه استفاده کنید
رویکرد توصیهشده در مواردی از این دست، اجرای زندهی هر برنامهی مفهومی متمایز در مبدأ خودش است.
اگر میخواهید از یک نام دامنه یکسان در همه آنها استفاده کنید، میتوانید با استفاده از زیردامنهها این کار را انجام دهید. به عنوان مثال، شرکتی که چندین برنامه یا سرویس اینترنتی ارائه میدهد، میتواند یک برنامه ایمیل را در https://mail.example.com و یک برنامه تقویم را در آدرس https://calendar.example.com میزبانی کند، در حالی که سرویس اصلی کسب و کار خود را در https://www.example.com ارائه میدهد. مثال دیگر، یک سایت ورزشی است که میخواهد یک برنامه مستقل کاملاً اختصاصی برای یک رویداد ورزشی مهم، مانند مسابقات قهرمانی فوتبال، در آدرس https://footballcup.example.com ایجاد کند که کاربران بتوانند آن را مستقل از سایت ورزشی اصلی که در https://www.example.com میزبانی میشود، نصب و استفاده کنند. این رویکرد همچنین ممکن است برای پلتفرمهایی که به مشتریان اجازه میدهند برنامههای مستقل خود را تحت نام تجاری شرکت ایجاد کنند، مفید باشد. به عنوان مثال، برنامهای که به بازرگانان اجازه میدهد PWA های خود را در https://merchant1.example.com ، https://merchant2.example.com و غیره ایجاد کنند.
استفاده از ریشههای مختلف، جداسازی بین برنامهها را تضمین میکند، به این معنی که هر یک از آنها میتوانند ویژگیهای مختلف مرورگر را به طور مستقل مدیریت کنند، از جمله:
- قابلیت نصب: هر برنامه Manifest مخصوص به خود را دارد و تجربه نصب مخصوص به خود را ارائه میدهد.
- فضای ذخیرهسازی: هر برنامه حافظه پنهان، فضای ذخیرهسازی محلی و اساساً تمام اشکال فضای ذخیرهسازی محلی دستگاه خود را دارد، بدون اینکه آنها را با دیگران به اشتراک بگذارد.
- سرویس ورکرها: هر برنامه سرویس ورکرهای مخصوص به خود را برای محدودههای ثبتشده دارد.
- مجوزها: مجوزها همچنین بر اساس مبدا محدود میشوند. به لطف این، کاربران دقیقاً میدانند که برای کدام سرویس مجوز میدهند و ویژگیهایی مانند اعلانها به درستی به هر برنامه نسبت داده میشوند.
ایجاد چنین درجهای از ایزولهسازی در مورد استفاده از چندین PWA مستقل، مطلوبترین حالت است، بنابراین ما اکیداً این رویکرد را توصیه میکنیم .
اگر برنامههای روی زیردامنهها بخواهند دادههای محلی را با یکدیگر به اشتراک بگذارند، همچنان میتوانند این کار را با کوکیها انجام دهند. برای سناریوهای پیشرفتهتر، میتوانند ذخیرهسازی را از طریق یک سرور همگامسازی کنند.

از همان مبدا استفاده کنید
رویکرد دوم، ساخت PWA های مختلف در یک مبدا است. این شامل سناریوهای زیر میشود:
مسیرهای غیر همپوشانی
چندین PWA یا «برنامههای وب» مفهومی، که در یک مبدا میزبانی میشوند و مسیرهای غیر همپوشانی دارند. برای مثال:
-
https://example.com/app1/ -
https://example.com/app2/
مسیرهای همپوشانی یا تو در تو
چندین PWA در یک مبدا، که یکی از آنها scope درون دیگری قرار دارد:
-
https://example.com/("برنامه بیرونی") -
https://example.com/app/("برنامه داخلی")
API سرویس ورکر و فرمت مانیفست به شما این امکان را میدهند که با استفاده از محدودهبندی سطح مسیر، هر دو کار را انجام دهید. با این حال، در هر دو مورد، استفاده از یک مبدا یکسان مشکلات و محدودیتهای زیادی را ایجاد میکند که ریشه آن از این واقعیت ناشی میشود که مرورگر اینها را به طور کامل به عنوان «برنامههای» مجزا در نظر نمیگیرد، بنابراین این رویکرد توصیه نمیشود .

در بخش بعدی، این چالشها را با جزئیات بیشتری تجزیه و تحلیل میکنیم و بررسی میکنیم که اگر استفاده از مبدأهای جداگانه امکانپذیر نباشد، چه کاری میتوان انجام داد.
چالشهای پیش روی PWA های چندگانه با منشأ یکسان
در اینجا به برخی از مسائل عملی مشترک در هر دو رویکرد با منشأ یکسان اشاره میکنیم:
- فضای ذخیرهسازی: کوکیها، فضای ذخیرهسازی محلی و تمام اشکال فضای ذخیرهسازی محلی دستگاه بین برنامهها به اشتراک گذاشته میشوند. به همین دلیل، اگر کاربر تصمیم به پاک کردن دادههای محلی یک برنامه بگیرد، تمام دادهها از مبدا پاک میشوند؛ هیچ راهی برای انجام این کار برای یک برنامه واحد وجود ندارد. توجه داشته باشید که کروم و برخی مرورگرهای دیگر هنگام حذف یکی از برنامهها، به طور فعال از کاربران میخواهند که دادههای محلی را پاک کنند و این امر بر دادههای سایر برنامههای موجود در مبدا نیز تأثیر میگذارد. مسئله دیگر این است که برنامهها همچنین باید سهمیه فضای ذخیرهسازی خود را به اشتراک بگذارند، به این معنی که اگر هر یک از آنها فضای زیادی را اشغال کند، دیگری تحت تأثیر منفی قرار خواهد گرفت.
- مجوزها: مجوزهای مرورگر به مبدأ وابسته هستند. این بدان معناست که اگر کاربر به یک برنامه مجوزی اعطا کند، این مجوز به طور همزمان برای همه برنامههای موجود در آن مبدأ اعمال میشود. این ممکن است چیز خوبی به نظر برسد (نیازی به درخواست چندین بار مجوز نیست)، اما به یاد داشته باشید: اگر کاربر مجوز یک برنامه را مسدود کند، مانع از درخواست آن مجوز یا استفاده از آن ویژگی توسط دیگران میشود. توجه داشته باشید که حتی اگر مجوزهای مرورگر فقط یک بار برای هر مبدأ لازم باشد اعطا شوند، از سوی دیگر، مجوزهای سطح سیستم باید یک بار برای هر برنامه اعطا شوند، صرف نظر از اینکه چندین برنامه به یک مبدأ اشاره میکنند یا خیر.
- تنظیمات کاربر: تنظیمات برای هر مبدا نیز تنظیم میشوند. برای مثال، اگر دو برنامه اندازه فونت متفاوتی داشته باشند و کاربر بخواهد بزرگنمایی را فقط در یکی از آنها تنظیم کند تا این تفاوت جبران شود، بدون اعمال این تنظیمات در سایر برنامهها قادر به انجام این کار نخواهد بود.
این چالشها، تشویق به استفاده از این رویکرد را دشوار میکند. با این وجود، اگر نمیتوانید از یک مبدأ جداگانه (مثلاً یک زیردامنه) استفاده کنید، همانطور که در بخش «استفاده از مبدأهای جداگانه» بحث شد، از بین دو گزینه مبدأ یکسان که ارائه دادیم، استفاده از مسیرهای غیرهمپوشان اکیداً توصیه میشود، نه مسیرهای همپوشانی و تودرتو.
همانطور که گفته شد، چالشهای مورد بحث در این بخش در هر دو رویکرد با مبدا یکسان مشترک است. در بخش بعدی، عمیقتر به جزئیات این موضوع خواهیم پرداخت که چرا استفاده از مسیرهای همپوشانی و تو در تو، کمترین توصیه را در بین استراتژیها دارد.
چالشهای اضافی برای مسیرهای همپوشانی و تو در تو
مشکل دیگر رویکرد مسیرهای همپوشانی و تو در تو (که در آن https://example.com/ برنامه بیرونی و https://example.com/app/ برنامه درونی است)، این است که تمام URLهای موجود در برنامه درونی در واقع بخشی از هر دو برنامه بیرونی و درونی در نظر گرفته میشوند.
در عمل، این امر مسائل زیر را به همراه دارد:
- تبلیغات نصب: اگر کاربر از برنامه داخلی (مثلاً در یک مرورگر وب) بازدید کند، در حالی که برنامه خارجی از قبل در دستگاه کاربر نصب شده است، مرورگر بنرهای تبلیغاتی نصب را نشان نمیدهد و رویداد BeforeInstallPrompt فعال نمیشود. دلیل این امر این است که مرورگر بررسی میکند و میبیند که آیا صفحه فعلی متعلق به برنامهای است که قبلاً نصب شده است یا خیر، و نتیجه میگیرد که چنین است. راه حل این مشکل، نصب دستی برنامه داخلی (از طریق گزینه "ایجاد میانبر" در منوی مرورگر) یا نصب اولیه برنامه داخلی، قبل از برنامه خارجی است.
- اعلانها و API نشانگذاری : اگر برنامهی بیرونی نصب شده باشد اما برنامهی درونی نصب نشده باشد، اعلانها و نشانهایی که از برنامهی درونی میآیند، به اشتباه به برنامهی بیرونی (که نزدیکترین محدودهی محصورکنندهی یک برنامهی نصب شده است) نسبت داده میشوند. این ویژگی در صورتی که هر دو برنامه روی دستگاه کاربر نصب شده باشند، به درستی کار میکند.
- ضبط لینک : برنامهی بیرونی ممکن است URLهایی را که متعلق به برنامهی درونی هستند، ضبط کند. این امر به ویژه در صورتی محتمل است که برنامهی بیرونی نصب شده باشد اما برنامهی درونی نصب نشده باشد. به طور مشابه، لینکهایی که در برنامهی بیرونی به برنامهی درونی لینک میشوند، ضبط لینک را در برنامهی درونی انجام نمیدهند، زیرا در محدودهی برنامهی بیرونی در نظر گرفته میشوند. علاوه بر این، در ChromeOS و اندروید، اگر این برنامهها به فروشگاه Play اضافه شوند (به عنوان فعالیتهای وب مورد اعتماد )، برنامهی بیرونی تمام لینکها را ضبط میکند. حتی اگر برنامهی درونی نصب شده باشد، سیستم عامل همچنان به کاربر این امکان را میدهد که آنها را در برنامهی بیرونی باز کند.
نتیجهگیری
ما روشهای مختلفی را بررسی کردیم که توسعهدهندگان میتوانند چندین برنامه وب پیشرونده مرتبط با یکدیگر را در یک دامنه بسازند.
به طور خلاصه، ما اکیداً توصیه میکنیم برای میزبانی PWA های مستقل از یک منبع متفاوت (مثلاً با استفاده از زیر دامنهها) استفاده کنید. میزبانی آنها در یک منبع یکسان چالشهای زیادی را به همراه دارد، عمدتاً به این دلیل که مرورگر آنها را به طور کامل به عنوان برنامههای مجزا در نظر نمیگیرد.
- خاستگاههای جداگانه: توصیه میشود
- مبدا یکسان، مسیرهای غیر همپوشانی: توصیه نمیشود
- مسیرهای با مبدا یکسان، همپوشانی و تو در تو: اکیداً توصیه نمیشود
اگر استفاده از مبداهای مختلف امکانپذیر نیست، استفاده از مسیرهای غیرهمپوشانی (مثلاً https://example.com/app1/ و https://example.com/app2/ اکیداً توصیه میشود که از مسیرهای همپوشانی یا تو در تو مانند https://example.com/ (برای برنامه بیرونی) و https://example.com/app/ (برای برنامه درونی) استفاده نکنید.
منابع اضافی
با تشکر فراوان از بررسیها و پیشنهادات فنی آنها: جو مدلی، دومینیک نگ، آلن کاتر، دنیل مورفی، پنی مکلاکلن، توماس اشتاینر و داروین هوانگ