cửa sổ hộp làm việc

Gói workbox-window là tập hợp mô-đun dùng để chạy trong window ngữ cảnh: bên trong trang web của bạn. Chúng là yếu tố bổ sung cho hộp công việc khác các gói chạy trong trình chạy dịch vụ.

Các tính năng/mục tiêu chính của workbox-window là:

Nhập và sử dụng cửa sổ hộp công việc

Điểm truy cập chính của gói workbox-window là lớp Workbox và bạn có thể nhập thông tin này vào mã của mình từ CDN của chúng tôi hoặc sử dụng bất kỳ Công cụ gói JavaScript.

Sử dụng CDN của chúng tôi

Cách dễ nhất để nhập lớp Workbox trên trang web của bạn là từ CDN của chúng tôi:

<script type="module">
  import {Workbox} from 'https://storage.googleapis.com/workbox-cdn/releases/6.4.1/workbox-window.prod.mjs';

  if ('serviceWorker' in navigator) {
    const wb = new Workbox('/sw.js');

    wb.register();
  }
</script>

Lưu ý rằng ví dụ này sử dụng <script type="module"> và câu lệnh import để hãy tải lớp Workbox. Mặc dù bạn có thể nghĩ rằng mình cần chuyển đổi mã này để mã hoạt động trong các trình duyệt cũ hơn thì điều đó thực sự không cần thiết.

Tất cả các trình duyệt chính hỗ trợ trình chạy dịch vụ cũng hỗ trợ các mô-đun JavaScript gốc, vì vậy đây là công cụ hoàn hảo tốt để cung cấp mã này cho bất kỳ trình duyệt nào (các trình duyệt cũ hơn sẽ bỏ qua mã này).

Đang tải Workbox với trình gói JavaScript

Mặc dù bạn hoàn toàn không cần phải có công cụ để sử dụng workbox-window, nhưng nếu cơ sở hạ tầng phát triển đã bao gồm một trình tạo gói như webpack hoặc Bản tổng hợp đang hoạt động với các phần phụ thuộc npm, bạn có thể sử dụng chúng để tải workbox-window.

Bước đầu tiên là cài đặt workbox-window làm phần phụ thuộc của ứng dụng:

npm install workbox-window

Sau đó, trong một trong các tệp JavaScript của ứng dụng, import hộp công việc bằng cách tham chiếu đến tên gói workbox-window:

import {Workbox} from 'workbox-window';

if ('serviceWorker' in navigator) {
  const wb = new Workbox('/sw.js');

  wb.register();
}

Nếu bộ gói của bạn hỗ trợ chức năng chia tách mã thông qua câu lệnh nhập động, bạn cũng có thể tải workbox-window theo điều kiện. Thao tác này sẽ giúp giảm kích thước gói chính trên trang của bạn.

Mặc dù workbox-window khá nhỏ, nhưng không có lý do gì cần được tải bằng logic ứng dụng cốt lõi của trang web, như trình chạy dịch vụ, về bản chất, là một cải tiến tiến bộ.

if ('serviceWorker' in navigator) {
  const {Workbox} = await import('workbox-window');

  const wb = new Workbox('/sw.js');
  wb.register();
}

Khái niệm nâng cao về gói

Không giống như các gói Workbox chạy trong Service worker, tệp bản dựng được tham chiếu bởi workbox-window mainmodule trường trong package.json được chuyển đổi sang ES5. Điều này khiến các quảng cáo này tương thích với bản dựng của mình—một số công cụ trong số này không cho phép nhà phát triển mã hoá bất kỳ nội dung nào các phần phụ thuộc node_module của chúng.

Nếu hệ thống xây dựng cho phép bạn dịch chuyển các phần phụ thuộc (hoặc nếu bạn không cần chuyển mã bất kỳ mã nào), thì tốt hơn là bạn nên nhập thay vì bản thân gói.

Dưới đây là các cách khác nhau mà bạn có thể nhập Workbox, cùng với nội dung giải thích về kết quả sẽ trả về:

// Imports a UMD version with ES5 syntax
// (pkg.main: "build/workbox-window.prod.umd.js")
const {Workbox} = require('workbox-window');

// Imports the module version with ES5 syntax
// (pkg.module: "build/workbox-window.prod.es5.mjs")
import {Workbox} from 'workbox-window';

// Imports the module source file with ES2015+ syntax
import {Workbox} from 'workbox-window/Workbox.mjs';

Ví dụ

Sau khi nhập lớp Workbox, bạn có thể sử dụng lớp này để đăng ký và tương tác với trình chạy dịch vụ của bạn. Sau đây là một số ví dụ về cách bạn có thể sử dụng Workbox trong ứng dụng của bạn:

Đăng ký một trình chạy dịch vụ và thông báo cho người dùng vào lần đầu tiên rằng trình chạy dịch vụ đó hoạt động

Nhiều ứng dụng web sử dụng trình chạy dịch vụ của ứng dụng web để lưu trước nội dung vào bộ nhớ đệm để ứng dụng của họ hoạt động ngoại tuyến trong các lần tải trang tiếp theo. Trong một số trường hợp, có thể cần thông báo cho người dùng biết ứng dụng hiện có thể sử dụng khi không có mạng.

const wb = new Workbox('/sw.js');

wb.addEventListener('activated', event => {
  // `event.isUpdate` will be true if another version of the service
  // worker was controlling the page when this version was registered.
  if (!event.isUpdate) {
    console.log('Service worker activated for the first time!');

    // If your service worker is configured to precache assets, those
    // assets should all be available now.
  }
});

// Register the service worker after event listeners have been added.
wb.register();

Thông báo cho người dùng nếu một worker dịch vụ đã được cài đặt nhưng bị treo khi đang chờ kích hoạt

Khi một trang do một trình chạy dịch vụ hiện có kiểm soát đăng ký một dịch vụ mới worker, theo mặc định, service worker sẽ không kích hoạt cho đến khi tất cả ứng dụng khách do trình chạy dịch vụ ban đầu kiểm soát đã huỷ tải hoàn toàn.

Đây là nguyên nhân phổ biến gây nhầm lẫn cho các nhà phát triển, đặc biệt là trong các trường hợp mà việc tải lại trang hiện tại không khiến trình chạy dịch vụ mới kích hoạt.

Để giúp giảm thiểu nhầm lẫn và làm rõ thời điểm tình huống này xảy ra, lớp Workbox cung cấp một sự kiện waiting mà bạn có thể theo dõi:

const wb = new Workbox('/sw.js');

wb.addEventListener('waiting', event => {
  console.log(
    `A new service worker has installed, but it can't activate` +
      `until all tabs running the current version have fully unloaded.`
  );
});

// Register the service worker after event listeners have been added.
wb.register();

Thông báo cho người dùng về các bản cập nhật bộ nhớ đệm từ gói workbox-broadcast-update

Gói workbox-broadcast-update là một cách tuyệt vời để có thể phân phát nội dung từ bộ nhớ đệm (để phân phối nhanh) trong khi có thể thông báo cho người dùng về các cập nhật đối với nội dung đó (bằng cách sử dụng cũ trong khi xác thực lại).

Để nhận những thông tin cập nhật đó từ cửa sổ, bạn có thể nghe message sự kiện của loại CACHE_UPDATED:

const wb = new Workbox('/sw.js');

wb.addEventListener('message', event => {
  if (event.data.type === 'CACHE_UPDATED') {
    const {updatedURL} = event.data.payload;

    console.log(`A newer version of ${updatedURL} is available!`);
  }
});

// Register the service worker after event listeners have been added.
wb.register();

Gửi cho trình chạy dịch vụ một danh sách URL vào bộ nhớ đệm

Đối với một số ứng dụng, có thể biết tất cả các tài sản cần được lưu trước vào bộ nhớ đệm tại thời điểm tạo, nhưng một số ứng dụng phân phát các trang hoàn toàn khác, dựa trên URL mà người dùng truy cập đầu tiên.

Đối với các ứng dụng thuộc danh mục thứ hai, bạn chỉ nên lưu các thành phần vào bộ nhớ đệm mà người dùng cần cho trang cụ thể mà họ đã truy cập. Khi sử dụng Gói workbox-routing, bạn có thể gửi danh sách URL vào bộ định tuyến và bộ định tuyến sẽ lưu các URL đó vào bộ nhớ đệm theo các quy tắc được xác định trên chính bộ định tuyến.

Ví dụ này sẽ gửi danh sách URL do trang tải đến bộ định tuyến bất kỳ lúc nào trình chạy dịch vụ mới được kích hoạt. Lưu ý rằng bạn có thể gửi tất cả URL vì chỉ các URL khớp với tuyến đã xác định trong trình chạy dịch vụ sẽ được lưu vào bộ nhớ đệm:

const wb = new Workbox('/sw.js');

wb.addEventListener('activated', event => {
  // Get the current page URL + all resources the page loaded.
  const urlsToCache = [
    location.href,
    ...performance.getEntriesByType('resource').map(r => r.name),
  ];
  // Send that list of URLs to your router in the service worker.
  wb.messageSW({
    type: 'CACHE_URLS',
    payload: {urlsToCache},
  });
});

// Register the service worker after event listeners have been added.
wb.register();

Các khoảnh khắc quan trọng trong vòng đời của trình thực thi dịch vụ

Vòng đời của trình chạy dịch vụ phức tạp và có thể là một thách thức để hiểu toàn diện. Một phần lý do là phức tạp đến mức phải xử lý mọi trường hợp phức tạp cho mọi trường hợp sử dụng có thể xảy ra trình chạy dịch vụ (ví dụ: đăng ký nhiều trình chạy dịch vụ, đăng ký nhiều trình chạy dịch vụ trình chạy dịch vụ khác nhau trong các khung khác nhau, đăng ký trình chạy dịch vụ với tên khác, v.v.).

Nhưng hầu hết các nhà phát triển triển khai trình chạy dịch vụ đều không cần lo lắng về tất cả những trường hợp hiếm gặp này vì cách sử dụng khá đơn giản. Nhiều nhà phát triển nhất chỉ đăng ký một trình chạy dịch vụ cho mỗi lần tải trang và họ không thay đổi tên của trình chạy dịch vụ tệp họ triển khai cho máy chủ của mình.

Lớp Workbox sử dụng thành phần hiển thị đơn giản hơn này cho vòng đời của trình thực thi dịch vụ bằng cách chia tất cả đăng ký trình chạy dịch vụ thành hai danh mục: thực thể trình chạy dịch vụ riêng, đã đăng ký và một trình chạy dịch vụ bên ngoài:

  • Trình chạy dịch vụ đã đăng ký: trình chạy dịch vụ bắt đầu cài đặt dưới dạng một trình chạy dịch vụ kết quả của thực thể Workbox gọi register() hoặc thuộc tính đã hoạt động Service worker nếu lệnh gọi register() không kích hoạt sự kiện updatefound khi đăng ký.
  • Trình chạy dịch vụ bên ngoài: một trình chạy dịch vụ đã bắt đầu cài đặt độc lập với thực thể Workbox gọi register(). Thông thường xảy ra khi người dùng mở một phiên bản mới của trang web trong một thẻ khác. Khi một sự kiện bắt nguồn từ một trình chạy dịch vụ bên ngoài, isExternal của sự kiện sẽ được thiết lập thành true.

Liên quan đến hai kiểu nhân viên dịch vụ này, sau đây là bảng chi tiết về tất cả những thời điểm quan trọng trong vòng đời của trình chạy dịch vụ, cùng với các đề xuất của nhà phát triển về cách xử lý:

Lần đầu tiên một trình chạy dịch vụ được cài đặt

Có thể bạn sẽ muốn xử lý lần đầu tiên một trình chạy dịch vụ cài đặt khác với cách bạn xử lý mọi bản cập nhật trong tương lai.

Trong workbox-window, trước tiên bạn có thể phân biệt phiên bản và các bản cập nhật trong tương lai bằng cách kiểm tra thuộc tính isUpdate trên bất kỳ các sự kiện sau. Đối với lần cài đặt đầu tiên, isUpdate sẽ là false

const wb = new Workbox('/sw.js');

wb.addEventListener('installed', event => {
  if (!event.isUpdate) {
    // First-installed code goes here...
  }
});

wb.register();
Sự kiện Sự kiện Hành động được đề xuất
Một trình chạy dịch vụ mới đã cài đặt (lần đầu tiên) installed

Lần đầu tiên một trình chạy dịch vụ cài đặt, chúng ta thường lưu trước bộ nhớ đệm tất cả tài sản cần thiết để trang web hoạt động khi không có mạng. Bạn có thể cân nhắc thông báo cho người dùng rằng trang web của họ hiện có thể hoạt động ngoại tuyến.

Ngoài ra, kể từ lần đầu tiên trình chạy dịch vụ cài đặt, trình chạy dịch vụ sẽ không sự kiện tìm nạp bị chặn cho lần tải trang đó, bạn cũng có thể cân nhắc việc lưu vào bộ nhớ đệm những tài sản đã được tải (mặc dù điều này không cần thiết nếu nội dung đã được lưu trước trong bộ nhớ đệm). Nút gửi Service worker một danh sách các URL để lưu vào bộ nhớ đệm ví dụ ở trên cho thấy cách thực hiện này.

Trình chạy dịch vụ đã bắt đầu kiểm soát trang controlling

Sau khi trình chạy dịch vụ mới được cài đặt và bắt đầu kiểm soát trang, tất cả các sự kiện tìm nạp tiếp theo sẽ đi qua trình chạy dịch vụ đó. Nếu Service worker thêm bất kỳ logic đặc biệt nào để xử lý sự kiện tìm nạp cụ thể, đây là thời điểm bạn biết logic đó sẽ chạy.

Xin lưu ý rằng ngay lần đầu tiên bạn cài đặt trình chạy dịch vụ, trình chạy dịch vụ này sẽ không bắt đầu kiểm soát trang hiện tại trừ khi trình chạy dịch vụ đó cuộc gọi clients.claim() trong sự kiện kích hoạt. Mặc định là đợi cho đến khi tải trang tiếp theo để bắt đầu kiểm soát.

Từ góc độ của workbox-window, điều này có nghĩa là Sự kiện controlling chỉ được gửi đi trong trường hợp trình chạy dịch vụ gọi clients.claim(). Sự kiện này không được gửi đi nếu trang đã được kiểm soát trước khi đăng ký.

Đã kích hoạt xong trình chạy dịch vụ activated

Như đã đề cập ở trên, ngay lần đầu tiên một trình chạy dịch vụ hoàn thành kích hoạt trang đó có thể (hoặc không) đã bắt đầu kiểm soát trang.

Vì lý do này, bạn không nên theo dõi sự kiện kích hoạt biết khi nào trình chạy dịch vụ kiểm soát trang. Tuy nhiên, nếu bạn đang chạy logic trong sự kiện đang hoạt động (trong trình chạy dịch vụ) và bạn cần biết khi nào logic đó hoàn tất, sự kiện được kích hoạt sẽ cho phép bạn biết điều đó.

Khi tìm thấy phiên bản cập nhật của trình chạy dịch vụ

Khi một trình chạy dịch vụ mới bắt đầu cài đặt nhưng phiên bản hiện có đang được cài đặt kiểm soát trang đó, thì thuộc tính isUpdate của tất cả các sự kiện sau sẽ true.

Cách bạn phản ứng trong tình huống này thường khác với lần đầu tiên vì bạn phải quản lý thời điểm và cách thức người dùng nhận được bản cập nhật này.

Sự kiện Sự kiện Hành động được đề xuất
Một trình chạy dịch vụ mới đã cài đặt (cập nhật trình chạy dịch vụ trước đó) installed

Nếu đây không phải là lượt cài đặt trình chạy dịch vụ đầu tiên (event.isUpdate === true), nghĩa là phiên bản mới hơn của Service worker đã được tìm thấy và cài đặt (tức là một phiên bản khác từ tài khoản hiện đang kiểm soát trang).

Điều này thường có nghĩa là phiên bản mới hơn của trang web đã được triển khai cho máy chủ của bạn và các tài sản mới có thể vừa hoàn tất quá trình lưu vào bộ nhớ đệm.

Lưu ý: một số nhà phát triển sử dụng sự kiện installed để thông báo cho người dùng biết rằng trang web của họ có phiên bản mới. Tuy nhiên, tuỳ thuộc vào cho dù bạn gọi skipWaiting() trong trình chạy dịch vụ cài đặt, tức là trình chạy dịch vụ được cài đặt có thể hoạt động hoặc không hoạt động ngay lập tức. Nếu bạn nên gọi skipWaiting(). Sau đó, tốt nhất là bạn nên thông báo cho người dùng của bản cập nhật khi trình chạy dịch vụ mới đã kích hoạt và nếu bạn đừng gọi skipWaiting, bạn nên cho họ biết bản cập nhật đang chờ xử lý trong sự kiện chờ (xem bên dưới để biết thêm thông tin).

Một trình chạy dịch vụ đã cài đặt nhưng bị kẹt trong giai đoạn chờ waiting

Nếu phiên bản cập nhật của trình chạy dịch vụ không gọi skipWaiting() trong khi đang được cài đặt, ứng dụng này sẽ không kích hoạt cho đến khi tất cả các trang do trình chạy dịch vụ hiện đang hoạt động kiểm soát đã huỷ tải. Bạn nên thông báo cho người dùng rằng đã có bản cập nhật và sẽ được áp dụng vào lần tiếp theo họ truy cập.

Cảnh báo! nhà phát triển thường nhắc người dùng tải lại để nhận bản cập nhật, nhưng trong nhiều trường hợp việc làm mới trang sẽ không kích hoạt worker đã cài đặt. Nếu người dùng làm mới trang và trình chạy dịch vụ vẫn đang chờ, sự kiện waiting sẽ kích hoạt lại và Thuộc tính event.wasWaitingBeforeRegister sẽ có giá trị true. Xin lưu ý rằng chúng tôi dự định sẽ cải thiện trải nghiệm này ở bản phát hành sau này. Theo dõi vấn đề #1848 để được cập nhật.

Một lựa chọn khác là nhắc người dùng và hỏi xem họ có muốn xem bản cập nhật hoặc tiếp tục chờ. Nếu chọn nhận bản cập nhật, bạn có thể sử dụng postMessage() để yêu cầu trình chạy dịch vụ chạy skipWaiting() Xem công thức nấu ăn nâng cao ví dụ như cho phép người dùng tải lại một trang.

Trình chạy dịch vụ đã bắt đầu kiểm soát trang controlling

Khi trình chạy dịch vụ được cập nhật bắt đầu kiểm soát trang, điều đó có nghĩa là phiên bản trình chạy dịch vụ của bạn hiện đang kiểm soát khác với phiên bản kiểm soát khi trang được tải. Trong một số trường hợp điều đó có thể ổn, nhưng cũng có thể có nghĩa là một số nội dung được tham chiếu bởi trang hiện tại không còn trong bộ nhớ đệm (và cũng có thể không trên máy chủ). Bạn có thể cân nhắc việc thông báo cho người dùng rằng một số phần của trang có thể không hoạt động chính xác.

Lưu ý: sự kiện controlling sẽ không kích hoạt nếu bạn không gọi skipWaiting() trong trình chạy dịch vụ của mình.

Đã kích hoạt xong trình chạy dịch vụ activated Khi một trình chạy dịch vụ được cập nhật đã kích hoạt xong, có nghĩa là bất kỳ logic mà bạn đang chạy trong activate của trình chạy dịch vụ có đã hoàn tất. Bạn cần trì hoãn điều gì cho đến khi logic đó kết thúc, bây giờ hãy chạy nó.

Khi tìm thấy phiên bản không mong muốn của trình chạy dịch vụ

Đôi khi, người dùng để trang web của bạn luôn mở trong một thẻ nền trong khoảng thời gian rất dài bất cứ lúc nào. Thậm chí, họ có thể mở một thẻ mới và điều hướng đến trang web của bạn mà không biết họ đã mở trang web của bạn trong một thẻ nền. Trong những trường hợp như vậy, có thể chạy hai phiên bản trang web cùng lúc và điều đó có thể trình bày một số vấn đề thú vị cho nhà phát triển như bạn.

Hãy xem xét một trường hợp trong đó bạn có thẻ A chạy phiên bản 1 trên trang web và thẻ B chạy phiên bản 2. Khi thẻ B tải, thẻ B sẽ do phiên bản dịch vụ của bạn kiểm soát worker được chuyển cùng với phiên bản 1, nhưng trang được máy chủ trả về (nếu sử dụng chiến lược lưu vào bộ nhớ đệm ưu tiên mạng cho yêu cầu điều hướng) sẽ chứa tất cả nội dung v2 của bạn.

Tuy nhiên, đây thường không phải là vấn đề đối với thẻ B, vì khi bạn viết phiên bản 2 bạn đã biết mã v1 hoạt động như thế nào. Tuy nhiên, đó có thể là vấn đề với thẻ A,vì mã v1 của bạn không thể dự đoán được điều gì những thay đổi mà mã v2 của bạn có thể tạo ra.

Để giúp xử lý những tình huống này, workbox-window cũng gửi vòng đời các sự kiện khi phát hiện thấy một bản cập nhật từ "bên ngoài" trình chạy dịch vụ, trong đó bên ngoài chỉ có nghĩa là bất kỳ phiên bản nào không phải là phiên bản Workbox hiện tại đã đăng ký thực thể.

Kể từ Workbox phiên bản 6 trở lên, các sự kiện này tương đương với các sự kiện được ghi lại ở trên, với việc thêm thuộc tính isExternal: true được đặt trên mỗi sự kiện . Nếu ứng dụng web của bạn cần triển khai logic cụ thể để xử lý một "bên ngoài" Service worker, bạn có thể kiểm tra thuộc tính đó trong trình xử lý sự kiện của mình.

Tránh những sai lầm phổ biến

Tính năng ghi nhật ký của nhà phát triển là một trong những tính năng hữu ích nhất mà Workbox cung cấp. và điều này đặc biệt đúng đối với workbox-window.

Chúng tôi biết việc phát triển bằng Service worker thường có thể khó hiểu, và khi mọi thứ trái ngược với những gì bạn mong đợi, khó mà biết được lý do tại sao.

Ví dụ: khi bạn thực hiện thay đổi đối với trình chạy dịch vụ và tải lại trang, bạn có thể không thấy thay đổi đó trong trình duyệt của mình. Đó chính là nguyên nhân có khả năng xảy ra, là trình chạy dịch vụ của bạn vẫn đang chờ kích hoạt.

Nhưng khi đăng ký một trình chạy dịch vụ bằng lớp Workbox, bạn sẽ đã thông báo về tất cả các thay đổi về trạng thái vòng đời trong bảng điều khiển dành cho nhà phát triển. trợ giúp gỡ lỗi khiến mọi thứ không như bạn mong đợi.

cảnh báo trên bảng điều khiển cửa sổ hộp công việc cho nhân viên đang chờ

Ngoài ra, một lỗi phổ biến mà các nhà phát triển mắc phải khi lần đầu sử dụng service worker là để đăng ký một trình chạy dịch vụ trong sai phạm vi.

Để giúp ngăn điều này xảy ra, lớp Workbox sẽ cảnh báo bạn nếu trang đăng ký trình chạy dịch vụ không nằm trong phạm vi của trình chạy dịch vụ đó. Sẽ cũng cảnh báo cho bạn trong những trường hợp trình chạy dịch vụ của bạn đang hoạt động nhưng chưa kiểm soát trang:

Cảnh báo trên bảng điều khiển cửa sổ hộp công việc dành cho nhân viên không kiểm soát

Giao tiếp của nhân viên dịch vụ cửa sổ và dịch vụ

Hầu hết các trường hợp sử dụng trình chạy dịch vụ nâng cao liên quan đến rất nhiều thông báo giữa Service worker và cửa sổ. Lớp Workbox cũng giúp bạn làm việc này bằng cách cung cấp một phương thức messageSW(). Phương thức này sẽ postMessage() thực thể đã đăng ký trình chạy dịch vụ và chờ phản hồi.

Mặc dù bạn có thể gửi dữ liệu cho trình chạy dịch vụ ở bất kỳ định dạng nào, nhưng định dạng được chia sẻ bởi tất cả các gói Workbox là một đối tượng có 3 thuộc tính (2 thuộc tính sau là không bắt buộc):

Thuộc tính Bắt buộc? Loại Mô tả
type string

Một chuỗi duy nhất, nhận dạng thông báo này.

Theo quy ước, các loại đều là chữ hoa với dấu gạch dưới phân tách các từ. Nếu một loại biểu thị một hành động cần thực hiện, thì đó phải là một lệnh ở thì hiện tại (ví dụ: CACHE_URLS), nếu kiểu biểu thị thông tin đang được báo cáo, thì thông tin đó phải ở thì quá khứ (ví dụ: URLS_CACHED).

meta không string Trong Workbox, đây luôn là tên của gói Workbox gửi . Khi tự gửi thư, bạn có thể bỏ qua thuộc tính này hoặc đặt thành bất kỳ thứ gì bạn muốn.
payload không * Dữ liệu đang được gửi. Thường thì đây là một đối tượng, nhưng không nhất thiết phải là một đối tượng.

Tin nhắn gửi qua phương thức messageSW() sẽ sử dụng MessageChannel để trình nhận có thể phản hồi các bình luận đó. Để trả lời một tin nhắn, bạn có thể gọi event.ports[0].postMessage(response) trong trình nghe sự kiện thông báo. Chiến lược phát hành đĩa đơn Phương thức messageSW() trả về một hứa hẹn sẽ phân giải thành bất kỳ response nào bạn trả lời.

Dưới đây là ví dụ về việc gửi thông báo từ cửa sổ đến trình chạy dịch vụ và chúng tôi nhận được phản hồi. Khối mã đầu tiên là trình nghe thông báo trong Service worker và khối thứ hai sử dụng lớp Workbox để gửi và chờ phản hồi:

Mã trong sw.js:

const SW_VERSION = '1.0.0';

addEventListener('message', event => {
  if (event.data.type === 'GET_VERSION') {
    event.ports[0].postMessage(SW_VERSION);
  }
});

Mã trong main.js (chạy trong cửa sổ):

const wb = new Workbox('/sw.js');
wb.register();

const swVersion = await wb.messageSW({type: 'GET_VERSION'});
console.log('Service Worker version:', swVersion);

Quản lý tính không tương thích của phiên bản

Ví dụ ở trên cho thấy cách bạn có thể triển khai việc kiểm tra trình chạy dịch vụ phiên bản từ cửa sổ. Ví dụ này được sử dụng vì khi bạn gửi thông báo qua lại giữa cửa sổ và trình chạy dịch vụ, điều quan trọng là cần lưu ý rằng trình chạy dịch vụ của bạn có thể không chạy cùng một phiên bản trang web của bạn mà mã trang đang chạy và giải pháp để xử lý vấn đề này vấn đề là khác nhau tuỳ thuộc vào việc bạn phân phát các trang của mình có ưu tiên mạng hay không hoặc ưu tiên bộ nhớ đệm.

Ưu tiên kết nối mạng

Khi phân phối mạng trang của bạn trước tiên, người dùng sẽ luôn nhận được phiên bản mới nhất của HTML từ máy chủ của bạn. Tuy nhiên, lần đầu tiên người dùng truy cập lại vào trang web của bạn (sau khi bạn đã triển khai bản cập nhật), HTML mà họ nhận được sẽ cho phiên bản mới nhất, nhưng trình chạy dịch vụ chạy trong trình duyệt của họ sẽ phiên bản được cài đặt trước đây (có thể có nhiều phiên bản cũ).

Điều quan trọng là bạn phải hiểu khả năng này vì nếu JavaScript tải nên phiên bản hiện tại của trang sẽ gửi thông báo đến phiên bản cũ của trang web Service worker, phiên bản đó có thể không biết cách phản hồi (hoặc có thể phản hồi bằng có định dạng không tương thích).

Do đó, bạn nên luôn tạo phiên bản cho trình chạy dịch vụ và kiểm tra cho các phiên bản tương thích trước khi thực hiện bất kỳ công việc quan trọng nào.

Ví dụ: trong mã trên, nếu phiên bản trình chạy dịch vụ được trả về Lệnh gọi messageSW() cũ hơn phiên bản dự kiến, nên đợi cho đến khi tìm thấy bản cập nhật (việc này sẽ xảy ra khi bạn gọi register()). Tại vào thời điểm đó, bạn có thể thông báo cho người dùng hoặc cập nhật hoặc có thể theo cách thủ công bỏ qua giai đoạn chờ để kích hoạt trình chạy dịch vụ mới ngay lập tức.

Lưu vào bộ nhớ đệm trước tiên

Khác với khi bạn phân phát các trang theo mạng ưu tiên, khi phân phối các trang của bạn vào bộ nhớ đệm- thứ nhất, bạn biết rằng trang của mình ban đầu sẽ luôn có cùng một phiên bản trình chạy dịch vụ của bạn (vì đó là những gì đã phân phối nó). Do đó, đây là giải pháp an toàn để sử dụng messageSW() ngay lập tức.

Tuy nhiên, nếu phiên bản cập nhật của trình chạy dịch vụ được tìm thấy và kích hoạt khi trang của bạn gọi register() (tức là bạn cố ý bỏ qua giai đoạn chờ), thì việc gửi tin nhắn đến máy chủ đó có thể không còn an toàn.

Một chiến lược để quản lý khả năng này là sử dụng lược đồ tạo phiên bản cho phép bạn phân biệt giữa nội dung cập nhật có thể gây lỗi và nội dung cập nhật không gây ra lỗi, và trong trường hợp có một bản cập nhật bị lỗi, bạn nên biết rằng việc nhắn tin cho trình chạy dịch vụ. Thay vào đó, bạn muốn cảnh báo người dùng rằng họ đang chạy phiên bản của trang và đề xuất họ tải lại để cập nhật.

Bỏ qua trình trợ giúp đang chờ

Một quy ước sử dụng phổ biến đối với thông báo từ trình chạy cửa sổ đến dịch vụ là gửi một Thông báo {type: 'SKIP_WAITING'} để hướng dẫn một trình chạy dịch vụ đã được cài đặt vào bỏ qua giai đoạn chờ và kích hoạt.

Kể từ Workbox phiên bản 6, bạn có thể sử dụng phương thức messageSkipWaiting() để gửi {type: 'SKIP_WAITING'} thông báo cho nhân viên dịch vụ chờ liên kết với đăng ký của trình chạy dịch vụ hiện tại. Nó sẽ âm thầm không làm gì nếu không có trình chạy dịch vụ chờ.

Loại

Workbox

Một lớp để hỗ trợ xử lý việc đăng ký, cập nhật và xử lý trình chạy dịch vụ phản ứng với các sự kiện trong vòng đời của trình chạy dịch vụ.

Thuộc tính

  • hàm khởi tạo

    void

    Tạo một thực thể Workbox mới có URL của tập lệnh và trình chạy dịch vụ . URL và các tuỳ chọn của tập lệnh giống như URL và các tuỳ chọn được sử dụng khi gọi navigation.serviceWorker.register(scriptURL, options).

    Hàm constructor có dạng như sau:

    (scriptURL: string | TrustedScriptURL, registerOptions?: object) => {...}

    • scriptURL

      string | TrustedScriptURL

      Tập lệnh trình chạy dịch vụ liên kết với lần xuất hiện này. Sử dụng TrustedScriptURL được hỗ trợ.

    • registerOptions

      đối tượng không bắt buộc

  • hoạt động

    Promise&lt;ServiceWorker&gt;

  • đang điều khiển

    Promise&lt;ServiceWorker&gt;

  • getSW

    void

    Phân giải bằng tham chiếu đến trình chạy dịch vụ khớp với URL của tập lệnh của trường hợp này, ngay khi có.

    Nếu tại thời điểm đăng ký đã có một dịch vụ đang hoạt động hoặc đang chờ có URL của tập lệnh phù hợp, URL này sẽ được sử dụng (với lệnh chờ trình chạy dịch vụ được ưu tiên hơn trình chạy dịch vụ đang hoạt động nếu cả hai vì trình chạy dịch vụ chờ sẽ được đăng ký nhiều hơn gần đây). Nếu không có nhân viên dịch vụ đang hoạt động hoặc đang chờ nào phù hợp khi đăng ký thì lời hứa sẽ không được giải quyết cho đến khi tìm thấy bản cập nhật và bắt đầu đang cài đặt, tại thời điểm đó trình chạy dịch vụ cài đặt sẽ được sử dụng.

    Hàm getSW có dạng như sau:

    () => {...}

    • returns

      Promise&lt;ServiceWorker&gt;

  • messageSW

    void

    Gửi đối tượng dữ liệu đã truyền tới trình chạy dịch vụ do trình chạy này đăng ký thực thể (thông qua workbox-window.Workbox#getSW) và phân giải bằng một câu trả lời (nếu có).

    Bạn có thể thiết lập phản hồi trong một trình xử lý thông báo của trình chạy dịch vụ bằng cách gọi event.ports[0].postMessage(...) để thực hiện lời hứa được trả về bởi messageSW(). Nếu không có phản hồi nào được đặt, lời hứa sẽ không bao giờ giải quyết.

    Hàm messageSW có dạng như sau:

    (data: object) => {...}

    • dữ liệu

      đối tượng

      Đối tượng để gửi cho trình chạy dịch vụ

    • returns

      Cam kết<bất kỳ>

  • messageSkipWaiting

    void

    Gửi thông báo {type: 'SKIP_WAITING'} tới trình chạy dịch vụ hiện ở trạng thái waiting được liên kết với đơn đăng ký hiện tại.

    Nếu không có đăng ký hiện tại hoặc không có trình chạy dịch vụ nào là waiting, việc gọi lệnh này sẽ không có hiệu lực.

    Hàm messageSkipWaiting có dạng như sau:

    () => {...}

  • thanh ghi

    void

    Đăng ký một trình chạy dịch vụ cho URL và dịch vụ của tập lệnh trường hợp này tuỳ chọn trình thực thi. Theo mặc định, phương thức này trì hoãn quá trình đăng ký cho đến cửa sổ đã tải.

    Hàm register có dạng như sau:

    (options?: object) => {...}

    • tùy chọn

      đối tượng không bắt buộc

      • sát cạnh

        boolean không bắt buộc

    • returns

      Promise&lt;ServiceWorkerRegistration&gt;

  • cập nhật

    void

    Kiểm tra các bản cập nhật của trình chạy dịch vụ đã đăng ký.

    Hàm update có dạng như sau:

    () => {...}

    • returns

      Lời hứa<vô hiệu>

WorkboxEventMap

Thuộc tính

WorkboxLifecycleEvent

Thuộc tính

  • isExternal

    boolean không bắt buộc

  • isUpdate

    boolean không bắt buộc

  • originalEvent

    Sự kiện không bắt buộc

  • sw

    ServiceWorker không bắt buộc

  • mục tiêu

    WorkboxEventTarget không bắt buộc

  • loại

    typeOperator

WorkboxLifecycleEventMap

Thuộc tính

WorkboxLifecycleWaitingEvent

Thuộc tính

  • isExternal

    boolean không bắt buộc

  • isUpdate

    boolean không bắt buộc

  • originalEvent

    Sự kiện không bắt buộc

  • sw

    ServiceWorker không bắt buộc

  • mục tiêu

    WorkboxEventTarget không bắt buộc

  • loại

    typeOperator

  • wasWaitingBeforeRegister

    boolean không bắt buộc

WorkboxMessageEvent

Thuộc tính

  • dữ liệu

    bất kỳ

  • isExternal

    boolean không bắt buộc

  • originalEvent

    Sự kiện

  • ports

    typeOperator

  • sw

    ServiceWorker không bắt buộc

  • mục tiêu

    WorkboxEventTarget không bắt buộc

  • loại

    "tin nhắn"

Phương thức

messageSW()

workbox-window.messageSW(
  sw: ServiceWorker,
  data: object,
)

Gửi một đối tượng dữ liệu đến một trình chạy dịch vụ qua postMessage và phân giải bằng nội dung phản hồi (nếu có).

Bạn có thể thiết lập phản hồi trong một trình xử lý thông báo của trình chạy dịch vụ bằng cách gọi event.ports[0].postMessage(...) để thực hiện lời hứa được trả về bởi messageSW(). Nếu bạn không đặt câu trả lời, thì lời hứa sẽ không giải quyết.

Tham số

  • sw

    ServiceWorker

    Trình chạy dịch vụ để gửi thư đến.

  • dữ liệu

    đối tượng

    Đối tượng để gửi cho trình chạy dịch vụ.

Giá trị trả về

  • Cam kết<bất kỳ>