Lớp học lập trình này nằm trong khóa đào tạo về Phát triển ứng dụng web tiến bộ do nhóm Đào tạo của Google Developers phát triển. Bạn sẽ nhận được nhiều giá trị nhất từ khóa học này nếu làm việc qua các lớp học lập trình theo trình tự.
Để biết đầy đủ thông tin chi tiết về khóa học, hãy xem phần Phát triển ứng dụng web tiến bộ.
Giới thiệu
Phòng thí nghiệm này hướng dẫn bạn cách tạo một trình chạy dịch vụ đơn giản và giải thích vòng đời của trình chạy dịch vụ.
Kiến thức bạn sẽ học được
- Tạo một tập lệnh trình chạy dịch vụ cơ bản, cài đặt tập lệnh và thực hiện gỡ lỗi đơn giản
Những điều bạn cần biết
- JavaScript và HTML cơ bản
- Các khái niệm và cú pháp cơ bản của Lời hứa ES2015
- Cách bật bảng điều khiển dành cho nhà phát triển
Bạn cần chuẩn bị những gì trước khi bắt đầu
- Máy tính có cổng vào/vỏ
- Kết nối Internet
- Trình duyệt hỗ trợ trình chạy dịch vụ
- Trình chỉnh sửa văn bản
Tải xuống hoặc sao chép kho lưu trữ-pwa-training-labs từ github và cài đặt phiên bản LTI của Node.js, nếu cần.
Chuyển đến thư mục service-worker-lab/app/
và khởi động máy chủ phát triển cục bộ:
cd service-worker-lab/app npm install node server.js
Bạn có thể chấm dứt máy chủ bất cứ lúc nào bằng Ctrl-c
.
Mở trình duyệt của bạn và chuyển đến localhost:8081/
.
Lưu ý: Hủy đăng ký bất kỳ trình chạy dịch vụ nào và xóa tất cả bộ nhớ đệm của trình chạy dịch vụ cho máy chủ cục bộ để chúng không can thiệp vào phòng thí nghiệm. Trong Công cụ dành cho nhà phát triển của Chrome, bạn có thể thực hiện việc này bằng cách nhấp vào Xóa dữ liệu trang web từ phần Xóa bộ nhớ của thẻ Ứng dụng.
Mở thư mục service-worker-lab/app/
trong trình chỉnh sửa văn bản ưu tiên của bạn. Thư mục app/
là nơi bạn sẽ tạo phòng thí nghiệm.
Thư mục này chứa:
below/another.html
,js/another.js
,js/other.js
vàother.html
là các tài nguyên mẫu mà chúng tôi sử dụng để thử nghiệm với phạm vi trình chạy dịch vụ- Thư mục
styles/
chứa các biểu định kiểu xếp tầng cho phòng thí nghiệm này - Thư mục
test/
chứa các tệp để kiểm tra tiến trình của bạn index.html
là trang HTML chính cho trang web/ứng dụng mẫu của chúng tôiservice-worker.js
là tệp JavaScript dùng để tạo trình chạy dịch vụ của chúng tôipackage.json
vàpackage-lock.json
theo dõi các gói nút được dùng trong dự án nàyserver.js
là một máy chủ nhanh đơn giản mà chúng tôi dùng để lưu trữ ứng dụng
Mở service-worker.js
trong trình chỉnh sửa văn bản của bạn. Xin lưu ý rằng tệp trống. Chúng tôi chưa thêm bất kỳ mã nào để chạy trong trình chạy dịch vụ.
Mở index.html
trong trình chỉnh sửa văn bản của bạn.
Bên trong các thẻ <script>
, hãy thêm mã sau để đăng ký trình chạy dịch vụ:
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker.register('service-worker.js')
.then(registration => {
console.log('Service Worker is registered', registration);
})
.catch(err => {
console.error('Registration failed:', err);
});
});
}
Lưu tập lệnh và làm mới trang. Bảng điều khiển sẽ trả về thông báo cho biết rằng trình chạy dịch vụ đã được đăng ký. Trong Chrome, bạn có thể kiểm tra xem một trình chạy dịch vụ đã được đăng ký hay chưa bằng cách mở Công cụ cho nhà phát triển (Control + Shift + I trên Windows và Linux hoặc ⌘ + alt + I trên máy Mac), nhấp vào thẻ Ứng dụng, sau đó nhấp vào tùy chọn Trình chạy dịch vụ. Bạn sẽ thấy nội dung tương tự như sau:
Không bắt buộc: Mở trang web trên trình duyệt không được hỗ trợ và xác minh rằng tính năng kiểm tra hỗ trợ có hoạt động.
Giải thích
Mã ở trên sẽ đăng ký tệp service-worker.js
dưới dạng trình chạy dịch vụ. Trước tiên, tiện ích này kiểm tra xem trình duyệt có hỗ trợ các trình chạy dịch vụ hay không. Bạn nên thực hiện việc này mỗi khi bạn đăng ký một trình chạy dịch vụ vì một số trình duyệt có thể không hỗ trợ các trình chạy dịch vụ. Sau đó, mã này đăng ký trình chạy dịch vụ bằng phương thức register
của API ServiceWorkerContainer
. API này nằm trong giao diện Navigator
của cửa sổ.
navigator.serviceWorker.register(...)
trả về một lời hứa sẽ phân giải bằng đối tượng registration
sau khi trình chạy dịch vụ được đăng ký thành công. Nếu không đăng ký được, lời hứa sẽ từ chối.
Những thay đổi trong trạng thái của trình chạy dịch vụ sẽ kích hoạt các sự kiện trong trình chạy dịch vụ.
Thêm trình xử lý sự kiện
Mở service-worker.js
trong trình chỉnh sửa văn bản của bạn.
Thêm trình xử lý sự kiện sau vào trình chạy dịch vụ:
self.addEventListener('install', event => {
console.log('Service worker installing...');
// Add a call to skipWaiting here
});
self.addEventListener('activate', event => {
console.log('Service worker activating...');
});
Lưu tệp.
Hủy đăng ký trình chạy dịch vụ theo cách thủ công và làm mới trang để cài đặt và kích hoạt trình chạy dịch vụ đã cập nhật. Nhật ký bảng điều khiển phải cho biết rằng trình chạy dịch vụ mới đã được đăng ký, đã cài đặt và đã được kích hoạt.
Lưu ý: Nhật ký đăng ký có thể xuất hiện không đúng thứ tự với các nhật ký khác (cài đặt và kích hoạt). Trình chạy dịch vụ chạy đồng thời với trang. Vì vậy, chúng tôi không thể đảm bảo thứ tự của nhật ký (nhật ký đăng ký đến từ trang, trong khi nhật ký cài đặt và kích hoạt đến từ trình chạy dịch vụ). Tuy nhiên, các sự kiện cài đặt, kích hoạt và các trình chạy dịch vụ khác sẽ xuất hiện theo thứ tự xác định bên trong trình chạy dịch vụ và luôn xuất hiện theo thứ tự dự kiến.
Giải thích
Trình chạy dịch vụ này phát ra một sự kiện install
khi kết thúc quá trình đăng ký. Trong đoạn mã ở trên, một thông báo được ghi lại bên trong trình xử lý sự kiện install
, nhưng trong ứng dụng thực tế thì đây sẽ là một vị trí phù hợp để lưu bộ nhớ đệm vào tài sản.
Khi một trình chạy dịch vụ đã được đăng ký, trình duyệt sẽ phát hiện xem có trình chạy dịch vụ mới hay không (vì trình chạy dịch vụ này khác với trình chạy dịch vụ đã cài đặt trước đó hoặc do không có trình chạy dịch vụ nào đã đăng ký cho trang web này). Nếu trình chạy dịch vụ mới (như trong trường hợp này), thì trình duyệt sẽ cài đặt trình chạy này.
Trình chạy dịch vụ này phát ra một sự kiện activate
khi trình điều khiển này kiểm soát trang. Mã ở trên ghi lại thông báo tại đây, nhưng sự kiện này thường dùng để cập nhật bộ nhớ đệm.
Chỉ một trình chạy dịch vụ có thể hoạt động tại một thời điểm cho một phạm vi nhất định (xem Khám phá phạm vi trình chạy dịch vụ), vì vậy, một trình chạy dịch vụ mới được cài đặt sẽ không được kích hoạt cho đến khi trình chạy dịch vụ hiện tại không còn được sử dụng nữa. Đây là lý do tại sao tất cả các trang do một trình chạy dịch vụ kiểm soát phải được đóng trước khi một trình chạy dịch vụ mới có thể tiếp quản. Vì chúng tôi đã hủy đăng ký trình chạy dịch vụ hiện có, trình chạy dịch vụ mới này đã được kích hoạt ngay lập tức.
Lưu ý: Chỉ cần làm mới trang là không đủ để chuyển quyền kiểm soát cho trình chạy dịch vụ mới, vì trang mới sẽ được yêu cầu trước khi trang hiện tại bị hủy tải và sẽ không có thời gian không sử dụng trình chạy dịch vụ cũ.
Lưu ý: Bạn cũng có thể kích hoạt một trình chạy dịch vụ mới theo cách thủ công bằng một số trình duyệt\39; công cụ cho nhà phát triển và theo phương thức lập trình với skipWaiting()
mà chúng ta sẽ thảo luận trong phần 3.4.
Cập nhật trình chạy dịch vụ
Thêm nhận xét sau ở bất kỳ đâu trong service-worker.js
:
// I'm a new service worker
Lưu tệp và làm mới trang. Xem nhật ký trong bảng điều khiển; bạn có thể thấy trình chạy dịch vụ mới cài đặt nhưng không kích hoạt. Trong Chrome, bạn có thể thấy trình chạy dịch vụ đang chờ trong thẻ Ứng dụng trên Công cụ cho nhà phát triển.
Đóng tất cả trang được liên kết với trình chạy dịch vụ. Sau đó, mở lại localhost:8081/
. Nhật ký bảng điều khiển phải cho biết rằng dịch vụ mới hiện đã được kích hoạt.
Lưu ý: Nếu bạn nhận được kết quả không mong muốn, hãy đảm bảo rằng bộ nhớ đệm HTTP của bạn bị vô hiệu hóa trong công cụ cho nhà phát triển.
Giải thích
Trình duyệt phát hiện sự chênh lệch byte giữa tệp trình chạy dịch vụ mới và hiện có (do có thêm nhận xét), vì vậy, trình chạy dịch vụ mới sẽ được cài đặt. Vì chỉ có một trình chạy dịch vụ có thể hoạt động tại một thời điểm (trong một phạm vi nhất định), mặc dù trình chạy dịch vụ mới đã được cài đặt, nhưng trình chạy dịch vụ đó sẽ không được kích hoạt cho đến khi trình chạy dịch vụ hiện tại không còn được sử dụng nữa. Bằng cách đóng tất cả trang dưới trình điều khiển dịch vụ cũ, chúng tôi có thể kích hoạt trình chạy dịch vụ mới này.
Bỏ qua giai đoạn chờ
Trình chạy dịch vụ mới có thể kích hoạt ngay lập tức, ngay cả khi có trình chạy dịch vụ hiện tại, bằng cách bỏ qua giai đoạn chờ.
Trong service-worker.js
, hãy thêm một cuộc gọi vào skipWaiting
trong trình nghe sự kiện install
:
self.skipWaiting();
Lưu tệp và làm mới trang. Xin lưu ý rằng trình chạy dịch vụ mới sẽ cài đặt và kích hoạt ngay lập tức, mặc dù trình chạy dịch vụ trước đó đã nắm quyền kiểm soát.
Giải thích
Phương thức skipWaiting()
cho phép một trình chạy dịch vụ kích hoạt ngay khi quá trình cài đặt hoàn tất. Trình nghe sự kiện cài đặt là nơi phổ biến để thực hiện lệnh gọi skipWaiting()
, nhưng có thể được gọi ở bất cứ đâu trong hoặc trước giai đoạn chờ. Hãy xem tài liệu này để biết thêm thông tin về thời điểm và cách sử dụng skipWaiting()
. Đối với các phòng thí nghiệm còn lại, giờ đây, chúng tôi có thể thử nghiệm mã trình chạy dịch vụ mới mà không cần hủy đăng ký trình chạy dịch vụ theo cách thủ công.
Thông tin khác
Trình chạy dịch vụ có thể hoạt động như một proxy giữa ứng dụng web và mạng.
Hãy thêm một trình xử lý tìm nạp để chặn các yêu cầu từ miền của chúng tôi.
Thêm mã sau vào service-worker.js
:
self.addEventListener('fetch', event => {
console.log('Fetching:', event.request.url);
});
Lưu tập lệnh và làm mới trang để cài đặt và kích hoạt trình chạy dịch vụ đã cập nhật.
Kiểm tra bảng điều khiển và quan sát thấy rằng không có sự kiện tìm nạp nào được ghi lại. Hãy làm mới trang rồi kiểm tra lại bảng điều khiển. Bạn sẽ thấy các sự kiện tìm nạp lần này cho trang và các tài sản của trang (như CSS).
Nhấp vào các đường liên kết đến Trang khác, Trang khác và Quay lại.
Bạn sẽ thấy các sự kiện tìm nạp trong bảng điều khiển cho từng trang và nội dung của trang đó. Tất cả nhật ký có hợp lý không?
Lưu ý: Nếu bạn truy cập vào một trang và chưa tắt bộ nhớ đệm HTTP, thì tài sản CSS và JavaScript có thể được lưu vào bộ nhớ đệm trên máy. Nếu điều này xảy ra, bạn sẽ không thấy các sự kiện tìm nạp cho những tài nguyên này.
Giải thích
Trình chạy dịch vụ sẽ nhận được một sự kiện tìm nạp cho mỗi yêu cầu HTTP do trình duyệt đưa ra trong phạm vi của nó. Đối tượng tìm nạp sự kiện chứa yêu cầu. Xử lý các sự kiện tìm nạp trong trình chạy dịch vụ cũng tương tự như việc theo dõi các sự kiện nhấp chuột trong DOM. Trong mã của mình, khi một sự kiện tìm nạp xảy ra, chúng tôi sẽ ghi lại URL đã yêu cầu vào bảng điều khiển (trong thực tế, chúng tôi cũng có thể tạo và trả về phản hồi tùy chỉnh của riêng mình bằng các tài nguyên tùy ý).
Tại sao không có sự kiện tìm nạp nào ghi lại lần làm mới đầu tiên? Theo mặc định, sự kiện tìm nạp từ một trang sẽ không đi qua trình chạy dịch vụ trừ phi chính yêu cầu đó đi qua một trình chạy dịch vụ. Điều này đảm bảo tính nhất quán trong trang web của bạn; nếu một trang tải mà không có trình chạy dịch vụ, thì tài nguyên phụ của trang đó cũng sẽ được tải.
Thông tin khác
- Sự kiện tìm nạp – MDN
- Sử dụng tính năng tìm nạp – MDN
- Giới thiệu về tính năng Tìm nạp – Nhà phát triển của Google
Mã giải pháp
Để nhận bản sao mã đang hoạt động, hãy chuyển đến thư mục 04-intercepting-network-requests/
.
Trình chạy dịch vụ có phạm vi. Phạm vi của trình chạy dịch vụ sẽ xác định những đường dẫn mà trình chạy dịch vụ chặn các đường dẫn.
Tìm phạm vi
Cập nhật mã đăng ký trong index.html
bằng:
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker.register('service-worker.js')
.then(registration => {
console.log('SW registered with scope:', registration.scope);
})
.catch(err => {
console.error('Registration failed:', err);
});
});
}
Làm mới trình duyệt. Xin lưu ý rằng bảng điều khiển cho biết phạm vi của trình chạy dịch vụ (trong trường hợp này là http://localhost:8081/
).
Giải thích
Lời hứa mà register()
trả về sẽ phân giải thành đối tượng đăng ký có chứa phạm vi của trình chạy dịch vụ.
Phạm vi mặc định là đường dẫn đến tệp trình chạy dịch vụ và mở rộng tới tất cả các thư mục thấp hơn. Vì vậy, một trình chạy dịch vụ trong thư mục gốc của một ứng dụng sẽ kiểm soát các yêu cầu từ tất cả tệp trong ứng dụng.
Di chuyển trình chạy dịch vụ
Di chuyển service-worker.js
vào thư mục below/
và cập nhật URL trình chạy dịch vụ trong mã đăng ký trong index.html
.
Hủy đăng ký trình chạy dịch vụ hiện tại trong trình duyệt và làm mới trang.
Bảng điều khiển cho biết phạm vi của trình chạy dịch vụ hiện là http://localhost:8081/below/
. Trong Chrome, bạn cũng có thể thấy phạm vi trình chạy dịch vụ trong thẻ ứng dụng của Công cụ cho nhà phát triển:
Quay lại trang chính, nhấp vào Trang khác, Trang khác và Quay lại. Những yêu cầu tìm nạp nào đang được ghi lại? Cái nào không?
Giải thích
Phạm vi mặc định của trình chạy dịch vụ là đường dẫn đến tệp trình chạy dịch vụ. Vì tệp trình chạy dịch vụ hiện nằm trong below/
, đó là phạm vi của tệp. Bảng điều khiển hiện chỉ ghi lại các sự kiện tìm nạp cho another.html
, another.css
và another.js
vì đây là các tài nguyên duy nhất trong phạm vi trình chạy dịch vụ.
Đặt một phạm vi bất kỳ
Di chuyển trình chạy dịch vụ trở lại thư mục gốc của dự án (app/
) và cập nhật URL trình chạy dịch vụ trong mã đăng ký trong index.html
.
Dùng tệp tham chiếu trên MDN để đặt phạm vi của trình chạy dịch vụ thành thư mục below/
bằng cách dùng thông số không bắt buộc trong register()
.
Hủy đăng ký trình chạy dịch vụ và làm mới trang. Nhấp vào Trang khác, Trang khác và Quay lại.
Xin nhắc lại, bảng điều khiển cho biết phạm vi của trình chạy dịch vụ hiện là http://localhost:8081/below/
và chỉ ghi lại các sự kiện tìm nạp cho another.html
, another.css
và another.js
.
Giải thích
Bạn có thể đặt một phạm vi tùy ý bằng cách chuyển một thông số bổ sung khi đăng ký, ví dụ:
navigator.serviceWorker.register('/service-worker.js', {
scope: '/kitten/'
});
Trong ví dụ trên, phạm vi của trình chạy dịch vụ được đặt thành /kitten/
. Trình chạy dịch vụ chặn các yêu cầu từ những trang trong /kitten/
và /kitten/lower/
, nhưng không chặn các trang như /kitten
hoặc /
.
Lưu ý: Bạn không thể đặt phạm vi tùy ý cao hơn vị trí thực tế của nhân viên dịch vụ. Tuy nhiên, nếu trình chạy máy chủ của bạn đang hoạt động trên một ứng dụng đang được phân phát bằng tiêu đề Service-Worker-Allowed
, thì bạn có thể chỉ định một phạm vi tối đa cho trình chạy dịch vụ đó ở phía trên vị trí của trình chạy dịch vụ.
Thông tin khác
Mã giải pháp
Để nhận bản sao mã đang hoạt động, hãy chuyển đến thư mục solution/
.
Bây giờ, bạn có một trình chạy dịch vụ đơn giản đang chạy và hiểu được vòng đời của trình chạy dịch vụ.
Thông tin khác
Để xem tất cả các lớp học lập trình trong khóa đào tạo PWA, hãy xem Lớp học lập trình chào mừng của khóa học/