Lớp học lập trình này hướng dẫn bạn từng bước cách tạo một ứng dụng thông báo đẩy. Khi kết thúc lớp học lập trình này, bạn sẽ có một ứng dụng khách:
- Đăng ký cho người dùng nhận thông báo đẩy.
- Nhận thông báo đẩy và hiển thị dưới dạng thông báo.
- Huỷ đăng ký nhận thông báo đẩy cho người dùng.
Lớp học lập trình này tập trung vào việc giúp bạn học bằng cách thực hành và không đề cập nhiều đến các khái niệm. Hãy xem bài viết Thông báo đẩy hoạt động như thế nào? để tìm hiểu về các khái niệm liên quan đến thông báo đẩy.
Mã máy chủ của lớp học lập trình này đã hoàn tất. Trong lớp học lập trình này, bạn sẽ chỉ triển khai ứng dụng. Để tìm hiểu cách triển khai một máy chủ thông báo đẩy, hãy xem Lớp học lập trình: Xây dựng máy chủ thông báo đẩy.
Khả năng tương thích với trình duyệt
Lớp học lập trình này hoạt động với các tổ hợp hệ điều hành và trình duyệt sau:
- Windows: Chrome, Edge
- macOS: Chrome, Firefox
- Android: Chrome, Firefox
Lớp học lập trình này không hoạt động với các hệ điều hành sau (hoặc tổ hợp hệ điều hành và trình duyệt):
- macOS: Brave, Edge, Safari
- iOS
Thiết lập
Nhận bản sao có thể chỉnh sửa của mã
- Nhấp vào Trộn để chỉnh sửa để có thể chỉnh sửa dự án.
Thiết lập chế độ xác thực
Để có thể nhận thông báo đẩy, bạn cần thiết lập máy chủ và ứng dụng bằng các khoá xác thực.
Hãy xem phần Ký các yêu cầu giao thức thông báo đẩy trên web để tìm hiểu lý do. Thông thường, bạn sẽ lưu trữ các khoá bí mật trong một tệp .env
, tương tự như tệp này.
VAPID_PUBLIC_KEY="BKiwTvD9HA…"
VAPID_PRIVATE_KEY="4mXG9jBUaU…"
VAPID_SUBJECT="mailto:test@test.test"
- Mở
public/index.js
. - Thay thế
VAPID_PUBLIC_KEY_VALUE_HERE
bằng giá trị khoá công khai của bạn.
Đăng ký trình chạy dịch vụ
Khách hàng của bạn sẽ cần một worker dịch vụ để nhận và hiển thị thông báo. Tốt nhất là bạn nên đăng ký trình chạy dịch vụ càng sớm càng tốt. Hãy xem phần Nhận và hiển thị các thông báo được đẩy dưới dạng thông báo để biết thêm thông tin.
- Thay thế chú thích
// TODO add startup logic here
bằng đoạn mã sau:
// TODO add startup logic here
if ('serviceWorker' in navigator && 'PushManager' in window) {
navigator.serviceWorker.register('./service-worker.js').then(serviceWorkerRegistration => {
console.info('Service worker was registered.');
console.info({serviceWorkerRegistration});
}).catch(error => {
console.error('An error occurred while registering the service worker.');
console.error(error);
});
subscribeButton.disabled = false;
} else {
console.error('Browser does not support service workers or push messages.');
}
subscribeButton.addEventListener('click', subscribeButtonHandler);
unsubscribeButton.addEventListener('click', unsubscribeButtonHandler);
- Nhấn tổ hợp phím `Control+Shift+J` (hoặc `Command+Option+J` trên máy Mac) để mở Công cụ cho nhà phát triển.
- Nhấp vào thẻ Bảng điều khiển. Bạn sẽ thấy thông báo
Service worker was registered.
được ghi vào Bảng điều khiển.
Yêu cầu cấp quyền gửi thông báo đẩy
Bạn không bao giờ được yêu cầu quyền gửi thông báo đẩy khi tải trang. Thay vào đó, giao diện người dùng của bạn nên hỏi người dùng xem họ có muốn nhận thông báo đẩy hay không. Sau khi người dùng xác nhận rõ ràng (ví dụ: bằng cách nhấp vào một nút), bạn có thể bắt đầu quy trình chính thức để nhận được quyền gửi thông báo đẩy từ trình duyệt.
- Trong
public/index.js
, hãy thay thế chú thích// TODO
trongsubscribeButtonHandler()
bằng đoạn mã sau:
// TODO
// Prevent the user from clicking the subscribe button multiple times.
subscribeButton.disabled = true;
const result = await Notification.requestPermission();
if (result === 'denied') {
console.error('The user explicitly denied the permission request.');
return;
}
if (result === 'granted') {
console.info('The user accepted the permission request.');
}
- Quay lại thẻ ứng dụng rồi nhấp vào Subscribe to push (Đăng ký nhận thông báo đẩy). Trình duyệt hoặc hệ điều hành của bạn có thể sẽ hỏi bạn có muốn cho phép trang web gửi thông báo đẩy cho bạn hay không. Nhấp vào Cho phép (hoặc cụm từ tương đương mà trình duyệt/hệ điều hành của bạn sử dụng). Trong Bảng điều khiển, bạn sẽ thấy một thông báo cho biết yêu cầu đã được chấp nhận hay bị từ chối.
Đăng ký nhận thông báo đẩy
Quy trình đăng ký bao gồm việc tương tác với một dịch vụ web do nhà cung cấp trình duyệt kiểm soát, được gọi là dịch vụ truyền dữ liệu đẩy. Sau khi nhận được thông tin đăng ký thông báo đẩy, bạn cần gửi thông tin đó đến một máy chủ và yêu cầu máy chủ lưu trữ thông tin đó trong cơ sở dữ liệu dài hạn. Hãy xem phần Đăng ký cho ứng dụng nhận thông báo đẩy để biết thêm thông tin về quy trình đăng ký.
- Thêm mã được đánh dấu sau vào
subscribeButtonHandler()
:
subscribeButton.disabled = true;
const result = await Notification.requestPermission();
if (result === 'denied') {
console.error('The user explicitly denied the permission request.');
return;
}
if (result === 'granted') {
console.info('The user accepted the permission request.');
}
const registration = await navigator.serviceWorker.getRegistration();
const subscribed = await registration.pushManager.getSubscription();
if (subscribed) {
console.info('User is already subscribed.');
notifyMeButton.disabled = false;
unsubscribeButton.disabled = false;
return;
}
const subscription = await registration.pushManager.subscribe({
userVisibleOnly: true,
applicationServerKey: urlB64ToUint8Array(VAPID_PUBLIC_KEY)
});
notifyMeButton.disabled = false;
fetch('/add-subscription', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(subscription)
});
Bạn phải chọn true
cho tuỳ chọn userVisibleOnly
. Có thể một ngày nào đó, bạn sẽ có thể gửi thông báo mà không hiển thị thông báo cho người dùng (thông báo đẩy thầm lặng), nhưng hiện tại, các trình duyệt không cho phép tính năng đó vì lo ngại về quyền riêng tư.
Giá trị applicationServerKey
dựa vào một hàm tiện ích chuyển đổi chuỗi base64 thành Uint8Array. Giá trị này được dùng để xác thực giữa máy chủ của bạn và dịch vụ truyền dữ liệu qua push.
Huỷ đăng ký nhận thông báo đẩy
Sau khi người dùng đăng ký nhận thông báo đẩy, giao diện người dùng của bạn cần cung cấp cách huỷ đăng ký trong trường hợp người dùng thay đổi ý định và không muốn nhận thông báo đẩy nữa.
- Thay thế chú thích
// TODO
trongunsubscribeButtonHandler()
bằng đoạn mã sau:
// TODO
const registration = await navigator.serviceWorker.getRegistration();
const subscription = await registration.pushManager.getSubscription();
fetch('/remove-subscription', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({endpoint: subscription.endpoint})
});
const unsubscribed = await subscription.unsubscribe();
if (unsubscribed) {
console.info('Successfully unsubscribed from push notifications.');
unsubscribeButton.disabled = true;
subscribeButton.disabled = false;
notifyMeButton.disabled = true;
}
Nhận thông báo đẩy và hiển thị thông báo đó
Như đã đề cập trước đó, bạn cần một worker dịch vụ để xử lý việc nhận và hiển thị các thông báo được đẩy đến máy khách từ máy chủ của bạn. Hãy xem phần Nhận và hiển thị các thông báo được đẩy dưới dạng thông báo để biết thêm thông tin chi tiết.
- Mở
public/service-worker.js
rồi thay thế chú thích// TODO
trong trình xử lý sự kiệnpush
của worker dịch vụ bằng mã sau:
// TODO
let data = event.data.json();
const image = 'logo.png';
const options = {
body: data.options.body,
icon: image
}
self.registration.showNotification(
data.title,
options
);
- Quay lại thẻ ứng dụng.
- Nhấp vào Thông báo cho tôi. Bạn sẽ nhận được một thông báo đẩy.
- Hãy thử mở URL của thẻ ứng dụng trên các trình duyệt khác (hoặc thậm chí là các thiết bị khác), thực hiện quy trình đăng ký rồi nhấp vào Thông báo cho tất cả. Bạn sẽ nhận được cùng một thông báo đẩy trên tất cả các trình duyệt mà bạn đã đăng ký. Tham khảo lại phần Khả năng tương thích của trình duyệt để xem danh sách các tổ hợp trình duyệt/hệ điều hành đã biết là hoạt động hay không hoạt động.
Bạn có thể tuỳ chỉnh thông báo theo nhiều cách. Hãy xem các thông số của ServiceWorkerRegistration.showNotification()
để tìm hiểu thêm.
Mở một URL khi người dùng nhấp vào một thông báo
Trong thực tế, có lẽ bạn sẽ sử dụng thông báo này để thu hút lại người dùng và nhắc họ truy cập vào trang web của bạn. Để làm được điều đó, bạn cần định cấu hình worker dịch vụ của mình thêm một chút.
- Thay thế chú thích
// TODO
trong trình xử lý sự kiệnnotificationclick
của trình chạy dịch vụ bằng đoạn mã sau:
// TODO
event.notification.close();
event.waitUntil(self.clients.openWindow('https://web.dev'));
- Quay lại thẻ ứng dụng, gửi cho chính bạn một thông báo khác, rồi nhấp vào thông báo đó. Trình duyệt của bạn sẽ mở một thẻ mới và tải
https://web.dev
.
Các bước tiếp theo
- Hãy xem phần
ServiceWorkerRegistration.showNotification()
để khám phá tất cả các cách tuỳ chỉnh thông báo. - Đọc bài viết Tổng quan về thông báo đẩy để hiểu rõ hơn về khái niệm cách hoạt động của thông báo đẩy.
- Hãy xem Lớp học lập trình: Xây dựng một máy chủ thông báo đẩy để tìm hiểu cách xây dựng một máy chủ quản lý các lượt đăng ký và gửi yêu cầu giao thức thông báo đẩy trên web.
- Hãy dùng thử Notification Generator (Trình tạo thông báo) để thử tất cả các cách bạn có thể tuỳ chỉnh thông báo.