کارگران خدمات متقاطع - آزمایش با واکشی خارجی

پس زمینه

کارگران خدمات به توسعه دهندگان وب این توانایی را می دهند که به درخواست های شبکه ای که توسط برنامه های کاربردی وب آنها ارائه می شود پاسخ دهند، به آنها اجازه می دهد حتی در حالت آفلاین به کار خود ادامه دهند، با lie-fi مبارزه کنند و تعاملات حافظه پنهان پیچیده مانند stale-while-revalidate را پیاده سازی کنند. اما کارگران خدمات از لحاظ تاریخی به یک منشاء خاص گره خورده اند - به عنوان صاحب یک برنامه وب، این مسئولیت شماست که یک سرویس دهنده را بنویسید و مستقر کنید تا تمام درخواست های شبکه را که برنامه وب شما می کند را رهگیری کند. در آن مدل، هر سرویس‌کار مسئول رسیدگی به درخواست‌های متقاطع است، برای مثال به یک API شخص ثالث یا فونت‌های وب.

اگر یک ارائه‌دهنده شخص ثالث یک API، یا فونت‌های وب، یا سایر سرویس‌های معمولی این قدرت را داشته باشد که سرویس‌کار خود را که فرصت رسیدگی به درخواست‌های ارسال‌شده توسط منابع دیگر به مبدأ خود را داشته باشد، داشته باشد؟ ارائه‌دهندگان می‌توانند منطق شبکه سفارشی خود را پیاده‌سازی کنند و از یک نمونه کش معتبر برای ذخیره پاسخ‌های خود استفاده کنند. اکنون، به لطف واکشی خارجی ، این نوع استقرار کارگر خدمات شخص ثالث یک واقعیت است.

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

  • ارائه دهندگان API با رابط های RESTful
  • ارائه دهندگان فونت وب
  • ارائه دهندگان تجزیه و تحلیل
  • ارائه دهندگان میزبانی تصویر
  • شبکه های تحویل محتوای عمومی

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

پیش نیازها

نشانه آزمایشی مبدا

واکشی خارجی هنوز آزمایشی در نظر گرفته می شود. برای اینکه این طرح قبل از اینکه به طور کامل مشخص شود و توسط فروشندگان مرورگر مورد توافق قرار گیرد، پیش از موعد پخته نشود، در Chrome 54 به‌عنوان نسخه آزمایشی اصلی پیاده‌سازی شده است. تا زمانی که واکشی خارجی آزمایشی باقی بماند، برای استفاده از این ویژگی جدید با سرویسی که میزبانی می‌کنید، باید توکنی را درخواست کنید که با مبدأ خاص سرویس شما مطابقت داشته باشد. این توکن باید به عنوان یک سرصفحه پاسخ HTTP در تمام درخواست‌های متقاطع برای منابعی که می‌خواهید از طریق واکشی خارجی مدیریت کنید، و همچنین در پاسخ منبع جاوا اسکریپت کارگر سرویس شما گنجانده شود:

Origin-Trial: token_obtained_from_signup

آزمایشی در مارس 2017 به پایان می رسد. در آن مرحله، ما انتظار داریم که تغییرات لازم برای تثبیت ویژگی را مشخص کرده و (امیدواریم) آن را به طور پیش فرض فعال کنیم. اگر تا آن زمان واکشی خارجی به‌طور پیش‌فرض فعال نشده باشد، عملکرد مرتبط با توکن‌های آزمایشی مبدا دیگر کار نخواهد کرد.

برای تسهیل آزمایش واکشی خارجی قبل از ثبت نام برای یک نشانه رسمی آزمایشی اولیه، می‌توانید با رفتن به chrome://flags/#enable-experimental-web-platform-features و فعال کردن " از الزامات Chrome برای رایانه محلی خود عبور کنید. ویژگی‌های پلتفرم وب آزمایشی" پرچم. لطفاً توجه داشته باشید که این کار باید در هر نمونه از Chrome که می‌خواهید در آزمایش‌های محلی خود استفاده کنید انجام شود، در حالی که با یک نشانه آزمایشی مبدا، این ویژگی برای همه کاربران Chrome شما در دسترس خواهد بود.

HTTPS

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

استفاده از واکشی خارجی

با وجود پیش‌نیازها، بیایید جزئیات فنی مورد نیاز برای راه‌اندازی و راه‌اندازی یک کارگر خدمات واکشی خارجی را بررسی کنیم.

ثبت نام کارگر خدماتی

اولین چالشی که احتمالاً با آن برخورد خواهید کرد این است که چگونه کارمند خدمات خود را ثبت نام کنید. اگر قبلاً با کارگران خدماتی کار کرده اید، احتمالاً با موارد زیر آشنا هستید:

// You can't do this!
if ('serviceWorker' in navigator) {
    navigator.serviceWorker.register('service-worker.js');
}

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

راه حل به شکل یک هدر HTTP است که سرور شما می تواند در هر پاسخی شامل شود:

Link: </service-worker.js>; rel="serviceworker"; scope="/"

بیایید آن هدر مثال را به اجزای آن تقسیم کنیم، که هر کدام با یک ; شخصیت

  • </service-worker.js> مورد نیاز است و برای تعیین مسیر فایل Service Worker شما استفاده می شود (به جای /service-worker.js مسیر مناسب اسکریپت خود را جایگزین کنید). این به طور مستقیم با رشته scriptURL مطابقت دارد که در غیر این صورت به عنوان اولین پارامتر به navigator.serviceWorker.register() ارسال می شود. مقدار باید در نویسه‌های <> محصور شود (همانطور که توسط مشخصات سرصفحه Link مورد نیاز است)، و اگر URL نسبی به جای مطلق ارائه شود، به عنوان نسبی به محل پاسخ تفسیر می‌شود.
  • rel="serviceworker" نیز مورد نیاز است، و باید بدون نیاز به سفارشی سازی گنجانده شود.
  • scope=/ یک اعلان دامنه اختیاری است، معادل رشته options.scope که می توانید به عنوان پارامتر دوم به navigator.serviceWorker.register() ارسال کنید. برای بسیاری از موارد استفاده، شما با استفاده از محدوده پیش‌فرض مشکلی ندارید ، بنابراین به راحتی آن را کنار بگذارید، مگر اینکه بدانید به آن نیاز دارید. همان محدودیت‌ها در مورد حداکثر محدوده مجاز، همراه با توانایی کاهش آن محدودیت‌ها از طریق هدر Service-Worker-Allowed ، برای ثبت‌های هدر Link اعمال می‌شود.

درست مانند ثبت نام کارگر سرویس "سنتی"، با استفاده از هدر Link یک سرویس کار نصب می شود که برای درخواست بعدی که در مقابل محدوده ثبت شده ارائه می شود، استفاده می شود. بدنه پاسخ که شامل هدر ویژه می‌شود همانطور که هست استفاده می‌شود و فوراً در دسترس صفحه قرار می‌گیرد، بدون اینکه منتظر بماند تا کارمند خدمات خارجی نصب را تمام کند.

به یاد داشته باشید که واکشی خارجی در حال حاضر به‌عنوان آزمایشی مبدأ اجرا می‌شود، بنابراین در کنار سرصفحه پاسخ پیوند خود، باید یک سرصفحه Origin-Trial معتبر نیز قرار دهید. حداقل مجموعه ای از هدرهای پاسخ برای اضافه کردن به منظور ثبت نام کارگر خدمات واکشی خارجی شما است

Link: </service-worker.js>; rel="serviceworker"
Origin-Trial: token_obtained_from_signup

اشکال زدایی ثبت نام

در طول توسعه، احتمالاً می خواهید تأیید کنید که کارگر خدمات واکشی خارجی شما به درستی نصب شده و درخواست ها را پردازش می کند. چند چیز وجود دارد که می‌توانید در ابزارهای برنامه‌نویس Chrome بررسی کنید تا تأیید کنید که کارها همانطور که انتظار می‌رود کار می‌کنند.

آیا سرصفحه های پاسخ مناسب ارسال می شوند؟

برای ثبت نام کارگر خدمات واکشی خارجی، باید یک هدر پیوند را روی پاسخ به منبعی که در دامنه شما میزبانی شده است، تنظیم کنید، همانطور که قبلا در این پست توضیح داده شد. در طول دوره Origin Trial، و با فرض اینکه chrome://flags/#enable-experimental-web-platform-features مجموعه ای ندارید، همچنین باید یک سرصفحه پاسخ Origin-Trial تنظیم کنید. می‌توانید تأیید کنید که سرور وب شما این هدرها را با نگاه کردن به ورودی در پانل شبکه DevTools تنظیم می‌کند:

سرصفحه ها در پنل شبکه نمایش داده می شوند.

آیا کارگر خدمات واکشی خارجی به درستی ثبت نام کرده است؟

همچنین می‌توانید با مشاهده فهرست کامل سرویس‌کاران در پنل برنامه DevTools، ثبت‌نام سرویس‌کار اساسی، از جمله دامنه آن را تأیید کنید. مطمئن شوید که گزینه "نمایش همه" را انتخاب کنید، زیرا به طور پیش فرض، شما فقط کارگران خدمات را برای مبدا فعلی می بینید.

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

کنترل کننده رویداد نصب

اکنون که سرویس‌کار شخص ثالث خود را ثبت کرده‌اید، مانند هر سرویس‌کار دیگری، فرصتی برای پاسخ به رویدادهای install و activate خواهد داشت. می‌تواند از این رویدادها برای پر کردن حافظه‌های پنهان با منابع مورد نیاز در طول رویداد install یا حذف کش‌های قدیمی در رویداد activate استفاده کند.

فراتر از فعالیت‌های ذخیره رویداد install معمولی، یک مرحله اضافی وجود دارد که در کنترل کننده رویداد install توسط کارگر خدمات شخص ثالث شما لازم است. کد شما باید registerForeignFetch() فراخوانی کند، مانند مثال زیر:

self.addEventListener('install', event => {
    event.registerForeignFetch({
    scopes: [self.registration.scope], // or some sub-scope
    origins: ['*'] // or ['https://example.com']
    });
});

دو گزینه پیکربندی وجود دارد که هر دو مورد نیاز است:

  • scopes آرایه‌ای از یک یا چند رشته را می‌گیرد، که هر کدام نشان‌دهنده محدوده‌ای برای درخواست‌هایی هستند که یک رویداد foreignfetch را راه‌اندازی می‌کنند. اما صبر کنید ، ممکن است فکر کنید، من قبلاً در هنگام ثبت نام کارگر خدمات یک محدوده تعریف کرده ام! این درست است، و دامنه کلی هنوز مرتبط است - هر محدوده ای که در اینجا مشخص می کنید باید یا برابر یا زیر دامنه دامنه کلی کارمند خدمات باشد. محدودیت‌های دامنه اضافی در اینجا به شما امکان می‌دهد یک سرویس‌کار همه‌منظوره را مستقر کنید که می‌تواند هم رویدادهای fetch شخص اول (برای درخواست‌های انجام‌شده از سایت شما) و هم رویدادهای foreignfetch شخص ثالث (برای درخواست‌های انجام‌شده از دامنه‌های دیگر) را مدیریت کند و واضح است که فقط زیر مجموعه ای از دامنه بزرگتر شما باید foreignfetch فعال کند. در عمل، اگر یک سرویس‌کار اختصاص داده شده برای رسیدگی به رویدادهای شخص ثالث، foreignfetch ، مستقر می‌کنید، فقط می‌خواهید از یک محدوده صریح و منفرد استفاده کنید که با محدوده کلی کارمند خدمات شما برابر است. این همان کاری است که مثال بالا با استفاده از مقدار self.registration.scope انجام می دهد.
  • origins همچنین آرایه‌ای از یک یا چند رشته را می‌گیرد و به شما اجازه می‌دهد تا کنترلر foreignfetch خود را محدود کنید تا فقط به درخواست‌های دامنه‌های خاص پاسخ دهد. برای مثال، اگر به صراحت به «https://example.com» اجازه دهید، پس درخواستی از یک صفحه میزبانی شده در https://example.com/path/to/page.html برای منبعی که از محدوده واکشی خارجی شما ارائه شده است، ارائه شده است. کنترل کننده واکشی خارجی شما را فعال می کند، اما درخواست های ارسال شده از https://random-domain.com/path/to/page.html کنترل کننده شما را فعال نمی کند. مگر اینکه دلیل خاصی برای راه‌اندازی منطق واکشی خارجی خود برای زیرمجموعه‌ای از مبداهای راه دور داشته باشید، فقط می‌توانید '*' را به عنوان تنها مقدار در آرایه مشخص کنید و همه مبدا مجاز خواهند بود.

کنترل کننده رویداد خارجی

اکنون که سرویس‌کار شخص ثالث خود را نصب کرده‌اید و از طریق registerForeignFetch() پیکربندی شده است، فرصتی برای رهگیری درخواست‌های منبع فرعی متقاطع به سرور شما که در محدوده واکشی خارجی قرار دارند، خواهد داشت.

در یک سرویس‌کار سنتی و شخص اول، هر درخواست یک رویداد fetch را ایجاد می‌کند که کارمند خدمات شما فرصتی برای پاسخگویی به آن دارد. به کارمند خدمات شخص ثالث ما فرصتی داده می شود تا یک رویداد کمی متفاوت به نام foreignfetch را مدیریت کند. از نظر مفهومی، این دو رویداد کاملاً شبیه هم هستند و به شما این فرصت را می‌دهند که درخواست ورودی را بررسی کنید و به صورت اختیاری از طریق respondWith() به آن پاسخ دهید:

self.addEventListener('foreignfetch', event => {
    // Assume that requestLogic() is a custom function that takes
    // a Request and returns a Promise which resolves with a Response.
    event.respondWith(
    requestLogic(event.request).then(response => {
        return {
        response: response,
        // Omit to origin to return an opaque response.
        // With this set, the client will receive a CORS response.
        origin: event.origin,
        // Omit headers unless you need additional header filtering.
        // With this set, only Content-Type will be exposed.
        headers: ['Content-Type']
        };
    })
    );
});

علیرغم شباهت های مفهومی، در عمل هنگام فراخوانی respondWith() در ForeignFetchEvent چند تفاوت وجود دارد. به جای ارائه یک Response (یا Promise که با یک Response حل می شود) به respondWith() ، مانند کاری که با FetchEvent انجام می دهید ، باید یک Promise که با یک Object با ویژگی های خاص حل می شود به respondWith() ForeignFetchEvent ارسال کنید:

  • response مورد نیاز است، و باید روی شی Response تنظیم شود که به مشتری درخواست کننده بازگردانده می شود. اگر چیزی غیر از یک Response معتبر ارائه دهید، درخواست مشتری با یک خطای شبکه خاتمه می یابد. برخلاف هنگام فراخوانی respondWith() در کنترل کننده رویداد fetch ، باید در اینجا یک Response ارائه دهید، نه یک Promise که با یک Response حل می شود! شما می توانید پاسخ خود را از طریق یک زنجیره وعده بسازید و آن زنجیره را به عنوان پارامتر به respondWith() foreignfetch ارسال کنید، اما زنجیره باید با یک Object حل شود که حاوی ویژگی response است که روی یک شی Response تنظیم شده است. شما می توانید نمایشی از این را در نمونه کد بالا مشاهده کنید.
  • origin اختیاری است، و برای تعیین اینکه آیا پاسخی که برگردانده شده است مبهم است یا خیر استفاده می شود. اگر این را کنار بگذارید، پاسخ غیرشفاف خواهد بود و مشتری دسترسی محدودی به بدنه و سرصفحه پاسخ خواهد داشت. اگر درخواست با mode: 'cors' انجام شده باشد، بازگرداندن یک پاسخ غیر شفاف به عنوان یک خطا تلقی می شود. با این حال، اگر مقدار رشته ای برابر با مبدأ کلاینت راه دور (که می تواند از طریق event.origin به دست آید) مشخص کنید، به صراحت انتخاب می کنید که پاسخی با CORS به مشتری ارائه دهد.
  • headers نیز اختیاری است و تنها در صورتی مفید است که origin نیز مشخص کرده باشید و پاسخ CORS را برگردانید. به طور پیش‌فرض، فقط سرصفحه‌های موجود در فهرست سرصفحه پاسخ ایمن‌شده توسط CORS در پاسخ شما گنجانده می‌شود. اگر نیاز دارید آنچه را که برگردانده می‌شود فیلتر کنید، هدرها فهرستی از یک یا چند نام سرصفحه را می‌گیرند و از آن به‌عنوان یک لیست مجاز از سرصفحه‌ها برای نمایش در پاسخ استفاده می‌کند. این به شما امکان می‌دهد CORS را انتخاب کنید و در عین حال از قرار گرفتن مستقیم سرصفحه‌های پاسخ حساس با مشتری از راه دور جلوگیری کنید.

توجه به این نکته مهم است که هنگامی که کنترل کننده foreignfetch اجرا می شود، به تمام اعتبارنامه ها و اختیارات محیطی مبدأ میزبان خدمات کارگر دسترسی دارد . به‌عنوان توسعه‌دهنده‌ای که یک کارمند خدمات خارجی با قابلیت واکشی را مستقر می‌کند، این مسئولیت شماست که اطمینان حاصل کنید که داده‌های پاسخ ممتازی را که در غیر این صورت به موجب آن اعتبارنامه‌ها در دسترس نبود، افشا نکنید. نیاز به انتخاب برای پاسخ‌های CORS یک مرحله برای محدود کردن قرار گرفتن در معرض ناخواسته است، اما به‌عنوان یک توسعه‌دهنده می‌توانید صراحتاً درخواست‌های fetch() را در handler foreignfetch خود انجام دهید که از اعتبارنامه‌های ضمنی استفاده نمی‌کنند از طریق:

self.addEventListener('foreignfetch', event => {
    // The new Request will have credentials omitted by default.
    const noCredentialsRequest = new Request(event.request.url);
    event.respondWith(
    // Replace with your own request logic as appropriate.
    fetch(noCredentialsRequest)
        .catch(() => caches.match(noCredentialsRequest))
        .then(response => ({response}))
    );
});

ملاحظات مشتری

برخی ملاحظات اضافی وجود دارد که بر نحوه رسیدگی کارگر خدمات واکشی خارجی شما به درخواست های مشتریان خدمات شما تأثیر می گذارد.

مشتریانی که کارمند خدمات شخص اول خود را دارند

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

کنترل کننده(های) fetch در یک کارمند خدمات شخص اول، اولین فرصت را برای پاسخ به تمام درخواست های ارائه شده توسط برنامه وب، حتی اگر یک کارگر خدمات شخص ثالث با foreignfetch با محدوده ای که درخواست را پوشش می دهد، وجود داشته باشد، دریافت می کند. اما مشتریان با کارگران خدمات شخص اول هنوز هم می توانند از مزایای کارگر خدمات واکشی خارجی شما استفاده کنند!

در داخل یک سرویس‌کار شخص اول، استفاده از fetch() برای بازیابی منابع متقاطع، کارگر خدمات واکشی خارجی مناسب را راه‌اندازی می‌کند. این بدان معناست که کدهایی مانند زیر می توانند از کنترل کننده foreignfetch شما استفاده کنند:

// Inside a client's first-party service-worker.js:
self.addEventListener('fetch', event => {
    // If event.request is under your foreign fetch service worker's
    // scope, this will trigger your foreignfetch handler.
    event.respondWith(fetch(event.request));
});

به طور مشابه، اگر کنترل‌کننده‌های واکشی شخص اول وجود داشته باشد، اما هنگام رسیدگی به درخواست‌های منبع متقاطع شما، event.respondWith() را فراخوانی نکنند، درخواست به‌طور خودکار به کنترل‌کننده foreignfetch شما می‌رسد:

// Inside a client's first-party service-worker.js:
self.addEventListener('fetch', event => {
    if (event.request.mode === 'same-origin') {
    event.respondWith(localRequestLogic(event.request));
    }

    // Since event.respondWith() isn't called for cross-origin requests,
    // any foreignfetch handlers scoped to the request will get a chance
    // to provide a response.
});

اگر یک کنترل کننده fetch شخص اول event.respondWith() را فراخوانی کند اما fetch() برای درخواست منبعی تحت محدوده واکشی خارجی شما استفاده نکند ، در این صورت کارمند خدمات واکشی خارجی شما فرصتی برای رسیدگی به درخواست نخواهد داشت.

مشتریانی که کارگر خدماتی خود را ندارند

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

کنار هم قرار دادن همه: جایی که مشتریان به دنبال پاسخ هستند

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

  1. fetch کارمند خدمات شخص اول (در صورت وجود)
  2. کنترل کننده foreignfetch یک کارگر خدمات شخص ثالث (در صورت وجود، و فقط برای درخواست های متقابل)
  3. حافظه پنهان HTTP مرورگر (در صورت وجود پاسخ جدید)
  4. شبکه

مرورگر از بالا شروع می‌شود و بسته به اجرای سرویس‌دهنده، تا زمانی که منبعی برای پاسخ پیدا کند به پایین لیست ادامه می‌دهد.

بیشتر بدانید

به روز باشید

با توجه به بازخورد برنامه‌نویسان، اجرای Chrome از واکشی خارجی آزمایشی مبدأ ممکن است تغییر کند. ما این پست را از طریق تغییرات درون خطی به روز نگه می داریم و تغییرات خاص زیر را در صورت وقوع یادداشت می کنیم. همچنین اطلاعات مربوط به تغییرات عمده را از طریق حساب توییتر chromiumdev@ به اشتراک خواهیم گذاشت.