Thông báo đẩy trên web mở

Nếu bạn hỏi các nhà phát triển, tính năng nào của thiết bị di động bị thiếu trong thì thông báo đẩy luôn ở vị trí cao trong danh sách.

Thông báo đẩy cho phép người dùng của bạn chọn nhận nội dung cập nhật kịp thời từ các trang web mà họ và cho phép bạn tương tác lại một cách hiệu quả với họ bằng nội dung tuỳ chỉnh, hấp dẫn.

Kể từ Chrome phiên bản 42, API đẩyAPI Thông báo được cung cấp cho nhà phát triển.

API đẩy trong Chrome dựa trên một số công nghệ, bao gồm Tệp kê khai ứng dụng webService Workers. Trong bài đăng này, chúng tôi sẽ xem xét từng công nghệ này, nhưng chỉ những công nghệ tối thiểu để thiết lập và chạy thông báo đẩy. Để hiểu rõ hơn về một số các tính năng khác của tệp kê khai cũng như khả năng ngoại tuyến của trình chạy dịch vụ, vui lòng xem các đường liên kết ở trên.

Chúng ta cũng sẽ xem xét những gì sẽ được thêm vào API trong các phiên bản Chrome sau này, và cuối cùng là tôi sẽ cung cấp Câu hỏi thường gặp.

Triển khai Thông báo đẩy cho Chrome

Phần này mô tả từng bước mà bạn cần hoàn thành để hỗ trợ quá trình đẩy nhắn tin trong ứng dụng web.

Đăng ký một Trình chạy dịch vụ

Có một phần phụ thuộc của việc có một trình chạy dịch vụ để triển khai thông báo đẩy cho trên web. Lý do là vì khi nhận được một thông báo đẩy, trình duyệt có thể khởi động trình chạy dịch vụ, trình chạy này chạy ở chế độ nền mà không cần trang đang mở và gửi một sự kiện để bạn có thể quyết định cách xử lý thông báo đẩy.

Dưới đây là ví dụ về cách bạn đăng ký trình chạy dịch vụ trong ứng dụng web của mình. Thời gian quá trình đăng ký đã hoàn tất thành công, chúng ta sẽ gọi initialiseState() mà chúng tôi sẽ đề cập đến ngay sau đây.

var isPushEnabled = false;



window.addEventListener('load', function() {
    var pushButton = document.querySelector('.js-push-button');
    pushButton.addEventListener('click', function() {
    if (isPushEnabled) {
        unsubscribe();
    } else {
        subscribe();
    }
    });

    // Check that service workers are supported, if so, progressively
    // enhance and add push messaging support, otherwise continue without it.
    if ('serviceWorker' in navigator) {
    navigator.serviceWorker.register('/service-worker.js')
    .then(initialiseState);
    } else {
    console.warn('Service workers aren\'t supported in this browser.');
    }
});

Trình xử lý lượt nhấp vào nút đăng ký hoặc huỷ đăng ký cho người dùng gửi thông báo. isPushEnabled là một biến toàn cục chỉ theo dõi liệu hoạt động đẩy Tính năng nhắn tin hiện đã được đăng ký hay chưa. Các tài sản này sẽ được tham khảo xuyên suốt các đoạn mã.

Sau đó, chúng ta sẽ kiểm tra xem trình chạy dịch vụ có được hỗ trợ hay không trước khi đăng ký service-worker.js có logic để xử lý thông báo đẩy. Ở đây, chúng ta chỉ cho trình duyệt biết rằng tệp JavaScript này là trình chạy dịch vụ cho trang web của chúng tôi.

Thiết lập trạng thái ban đầu

Ví dụ về trải nghiệm người dùng thông báo đẩy đã bật và đã tắt trong Chrome.

Sau khi đăng ký trình chạy dịch vụ, chúng ta cần thiết lập trạng thái cho giao diện người dùng.

Người dùng mong đợi một giao diện người dùng đơn giản để bật hoặc tắt thông báo đẩy cho trang web của bạn, và họ sẽ muốn chiến dịch đó luôn được cập nhật về mọi thay đổi xảy ra. Trong khu vực khác nếu chúng kích hoạt thông báo đẩy cho trang web của bạn, hãy thoát và quay lại tuần sau, giao diện người dùng của bạn sẽ làm nổi bật thông báo đẩy đã được bật.

Bạn có thể tìm thấy một số nguyên tắc về trải nghiệm người dùng trong tài liệu này, trong bài viết này, chúng tôi sẽ tập trung vào khía cạnh kỹ thuật.

Tại thời điểm này, có thể bạn nghĩ rằng chỉ có hai trạng thái để giải quyết, bật hoặc tắt. Tuy nhiên, có một số tiểu bang khác xung quanh mà bạn cần xem xét.

Sơ đồ nêu bật các điểm khác nhau cần cân nhắc và trạng thái đẩy trong Chrome

Có một số API chúng tôi cần kiểm tra trước khi bật nút của mình và nếu mọi thứ được hỗ trợ, chúng ta có thể bật giao diện người dùng và đặt trạng thái ban đầu thành cho biết liệu thông báo đẩy có được đăng ký hay không.

Do phần lớn các bước kiểm tra này là giao diện người dùng bị vô hiệu hoá, bạn nên đặt trạng thái ban đầu thành tắt. Điều này cũng giúp tránh mọi nhầm lẫn có phải là vấn đề với JavaScript trên trang của bạn hay không, ví dụ: bạn không thể thêm tệp JS được tải xuống hoặc người dùng đã tắt JavaScript.

<button class="js-push-button" disabled>
    Enable Push Messages
</button>

Với trạng thái ban đầu này, chúng ta có thể thực hiện các bước kiểm tra nêu trên trong initialiseState(), tức là sau khi trình chạy dịch vụ của chúng ta được đăng ký.

// Once the service worker is registered set the initial state
function initialiseState() {
    // Are Notifications supported in the service worker?
    if (!('showNotification' in ServiceWorkerRegistration.prototype)) {
    console.warn('Notifications aren\'t supported.');
    return;
    }

    // Check the current Notification permission.
    // If its denied, it's a permanent block until the
    // user changes the permission
    if (Notification.permission === 'denied') {
    console.warn('The user has blocked notifications.');
    return;
    }

    // Check if push messaging is supported
    if (!('PushManager' in window)) {
    console.warn('Push messaging isn\'t supported.');
    return;
    }

    // We need the service worker registration to check for a subscription
    navigator.serviceWorker.ready.then(function(serviceWorkerRegistration) {
    // Do we already have a push message subscription?
    serviceWorkerRegistration.pushManager.getSubscription()
        .then(function(subscription) {
        // Enable any UI which subscribes / unsubscribes from
        // push messages.
        var pushButton = document.querySelector('.js-push-button');
        pushButton.disabled = false;

        if (!subscription) {
            // We aren't subscribed to push, so set UI
            // to allow the user to enable push
            return;
        }

        // Keep your server in sync with the latest subscriptionId
        sendSubscriptionToServer(subscription);

        // Set your UI to show they have subscribed for
        // push messages
        pushButton.textContent = 'Disable Push Messages';
        isPushEnabled = true;
        })
        .catch(function(err) {
        console.warn('Error during getSubscription()', err);
        });
    });
}

Tổng quan ngắn gọn về các bước này:

  • Chúng tôi kiểm tra xem showNotification có trong ServiceWorkerRegistration nguyên mẫu. Nếu không có cookie này, chúng tôi sẽ không thể hiển thị thông báo từ trình chạy dịch vụ của mình khi nhận được thông báo đẩy.
  • Chúng tôi kiểm tra để đảm bảo rằng Notification.permission hiện tại không phải là "denied" Quyền bị từ chối có nghĩa là bạn không thể hiển thị thông báo cho đến khi người dùng thay đổi quyền trong trình duyệt theo cách thủ công.
  • Để kiểm tra xem chế độ thông báo đẩy có được hỗ trợ hay không, chúng tôi sẽ kiểm tra xem PushManager có được hỗ trợ hay không có sẵn trong đối tượng cửa sổ.
  • Cuối cùng, chúng tôi đã sử dụng pushManager.getSubscription() để kiểm tra xem chúng tôi đã có gói thuê bao hay chưa. Nếu có, chúng tôi sẽ gửi thông tin chi tiết về gói thuê bao đến để đảm bảo chúng tôi có thông tin phù hợp và thiết lập giao diện người dùng để biểu thị thông báo đẩy đã được bật hay chưa. Chúng ta sẽ xem xét những chi tiết nào có trong đối tượng gói thuê bao ở phần sau của bài viết này.

Chúng tôi sẽ đợi cho đến khi navigator.serviceWorker.ready được giải quyết để kiểm tra xem có đăng ký và bật nút đẩy vì nút này chỉ sau dịch vụ worker đang hoạt động nên bạn thực sự có thể đăng ký gửi thông báo.

Bước tiếp theo là xử lý thời điểm người dùng muốn bật thông báo đẩy, nhưng trước khi có thể thực hiện điều này, chúng ta cần thiết lập dự án Google Developer Console và thêm một vài tham số vào tệp kê khai để sử dụng Giải pháp gửi thông báo qua đám mây của Firebase (FCM), trước đây được gọi là Google Cloud Messaging (GCM).

Tạo dự án trên Firebase Developer Console

Chrome sử dụng FCM để xử lý việc gửi và phân phối thông báo đẩy; tuy nhiên, để sử dụng API FCM, bạn cần thiết lập dự án trên Bảng điều khiển dành cho nhà phát triển Firebase.

Các bước sau đây dành riêng cho Chrome, Opera dành cho Android và Samsung Trình duyệt mà họ sử dụng FCM. Chúng ta sẽ thảo luận về cách hoạt động của tính năng này trong các trình duyệt khác ở phần sau của bài viết.

Tạo Dự án mới dành cho nhà phát triển Firebase

Để bắt đầu, bạn cần tạo một dự án mới trên https://console.firebase.google.com/ bằng cách nhấp vào "Create New Project" (Tạo dự án mới).

Ảnh chụp màn hình dự án Firebase mới

Thêm tên dự án, tạo dự án và bạn sẽ được chuyển đến dự án trang tổng quan:

Trang chủ dự án Firebase

Trên trang tổng quan này, hãy nhấp vào biểu tượng bánh răng bên cạnh tên dự án ở trên cùng góc bên trái và nhấp vào 'Cài đặt dự án'.

Trình đơn cài đặt dự án Firebase

Trong trang cài đặt, nhấp vào liên kết 'Nhắn tin qua đám mây' .

Trình đơn Nhắn tin qua đám mây của dự án Firebase

Trang này chứa khoá API cho thông báo đẩy mà chúng ta sẽ sử dụng sau này và mã người gửi mà chúng ta cần đưa vào tệp kê khai ứng dụng web trong .

Thêm tệp kê khai ứng dụng web

Đối với thông báo đẩy, chúng ta cần thêm tệp kê khai có trường gcm_sender_id, để thành công gói thuê bao đẩy. Chỉ có tham số này mới được yêu cầu bởi Trình duyệt Chrome, Opera dành cho Android và Samsung để họ có thể sử dụng FCM / GCM.

Các trình duyệt này sử dụng gcm_sender_id khi đăng ký người dùng thiết bị thông minh bằng FCM. Điều này có nghĩa là FCM có thể xác định thiết bị của người dùng và đảm bảo đảm bảo mã nhận dạng người gửi khớp với khoá API tương ứng và người dùng đã cho phép máy chủ của bạn gửi cho họ thông báo đẩy.

Dưới đây là một tệp kê khai cực kỳ đơn giản:

{
    "name": "Push Demo",
    "short_name": "Push Demo",
    "icons": [{
        "src": "images/icon-192x192.png",
        "sizes": "192x192",
        "type": "image/png"
        }],
    "start_url": "/index.html?homescreen=1",
    "display": "standalone",
    "gcm_sender_id": "<Your Sender ID Here>"
}

Bạn cần phải đặt giá trị gcm_sender_id thành mã người gửi từ Dự án Firebase của bạn.

Sau khi bạn đã lưu tệp kê khai vào dự án của mình (tệp manifest.json là name), hãy tham chiếu tệp này từ HTML của bạn với thẻ sau trong phần đầu .

<link rel="manifest" href="/manifest.json">

Nếu không thêm tệp kê khai web có những tham số này, bạn sẽ nhận được một ngoại lệ khi bạn cố gắng đăng ký gửi thông báo cho người dùng, kèm theo lỗi "Registration failed - no sender id provided" hoặc "Registration failed - permission denied".

Đăng ký nhận thông báo đẩy

Bây giờ, bạn đã thiết lập xong tệp kê khai, bạn có thể quay lại JavaScript của trang web.

Để đăng ký, bạn phải gọi phương thức subscribe() trên PushManager, mà bạn truy cập thông qua ServiceWorkerRegistration.

Thao tác này sẽ yêu cầu người dùng cấp cho bạn quyền truy cập vào máy chủ gốc để gửi thông báo đẩy thông báo. Nếu không có quyền này, bạn sẽ không thể đăng ký.

Nếu promise (lời hứa) được trả về do phương thức subscribe() phân giải, bạn sẽ được cấp PushSubscription đối tượng chứa một điểm cuối.

Điểm cuối phải được lưu trên máy chủ của bạn cho mỗi người dùng vì bạn sẽ cần họ gửi thông báo đẩy sau này.

Đoạn mã sau đây đăng ký cho người dùng nhận thông báo đẩy:

function subscribe() {
    // Disable the button so it can't be changed while
    // we process the permission request
    var pushButton = document.querySelector('.js-push-button');
    pushButton.disabled = true;

    navigator.serviceWorker.ready.then(function(serviceWorkerRegistration) {
    serviceWorkerRegistration.pushManager.subscribe()
        .then(function(subscription) {
        // The subscription was successful
        isPushEnabled = true;
        pushButton.textContent = 'Disable Push Messages';
        pushButton.disabled = false;

        // TODO: Send the subscription.endpoint to your server
        // and save it to send a push message at a later date
        return sendSubscriptionToServer(subscription);
        })
        .catch(function(e) {
        if (Notification.permission === 'denied') {
            // The user denied the notification permission which
            // means we failed to subscribe and the user will need
            // to manually change the notification permission to
            // subscribe to push messages
            console.warn('Permission for Notifications was denied');
            pushButton.disabled = true;
        } else {
            // A problem occurred with the subscription; common reasons
            // include network errors, and lacking gcm_sender_id and/or
            // gcm_user_visible_only in the manifest.
            console.error('Unable to subscribe to push.', e);
            pushButton.disabled = false;
            pushButton.textContent = 'Enable Push Messages';
        }
        });
    });
}

Tại thời điểm này, ứng dụng web của bạn đã sẵn sàng nhận thông báo đẩy, mặc dù không có sẽ xảy ra cho đến khi chúng ta thêm trình nghe sự kiện đẩy vào tệp trình chạy dịch vụ của mình.

Trình nghe sự kiện đẩy trình chạy dịch vụ

Khi nhận được một thông báo đẩy (chúng ta sẽ nói về cách gửi một thông báo đẩy thông báo trong phần tiếp theo), sự kiện đẩy sẽ được gửi tới nhân viên dịch vụ, lúc đó bạn sẽ cần để hiển thị thông báo.

self.addEventListener('push', function(event) {
    console.log('Received a push message', event);

    var title = 'Yay a message.';
    var body = 'We have received a push message.';
    var icon = '/images/icon-192x192.png';
    var tag = 'simple-push-demo-notification-tag';

    event.waitUntil(
    self.registration.showNotification(title, {
        body: body,
        icon: icon,
        tag: tag
    })
    );
});

Mã này đăng ký trình nghe sự kiện đẩy và hiển thị thông báo kèm theo tiêu đề, nội dung, biểu tượng và thẻ thông báo được xác định trước. Một điểm tinh tế đáng chú ý trong ví dụ này là event.waitUntil() . Phương thức này lấy một hứa hẹn và mở rộng thời gian tồn tại của một trình xử lý sự kiện (hoặc có thể được coi là duy trì dịch vụ còn sống), cho đến khi lời hứa là đã quyết toán; Trong trường hợp này, Lời hứa được chuyển đến event.waitUntil là Lời hứa được trả về từ showNotification().

Thẻ thông báo hoạt động như một giá trị nhận dạng cho các thông báo riêng biệt. Nếu chúng tôi gửi hai thông báo đẩy cho cùng một điểm cuối, với độ trễ ngắn giữa các điểm cuối và hiển thị thông báo có cùng thẻ, trình duyệt sẽ hiển thị thông báo đầu tiên và thay thế thông báo đó bằng thông báo thứ hai khi nhận được thông báo đẩy.

Nếu bạn muốn hiển thị nhiều thông báo cùng một lúc, hãy sử dụng một thẻ khác hoặc không hề có thẻ nào. Chúng ta sẽ xem xét một ví dụ hoàn chỉnh hơn về việc hiển thị thông báo ở phần sau trong của bạn. Còn bây giờ, hãy đơn giản hoá mọi thứ và xem liệu thông báo đẩy có hiển thị hay không thông báo này.

Đang gửi thông báo đẩy

Chúng tôi đã đăng ký đẩy thông báo và trình chạy dịch vụ của chúng tôi đã sẵn sàng hiển thị , vậy nên đã đến lúc gửi thông báo đẩy thông qua FCM.

Cách này chỉ áp dụng cho các trình duyệt sử dụng FCM.

Khi bạn gửi biến PushSubscription.endpoint đến máy chủ của mình, cho FCM là điểm đặc biệt. Có một tham số ở cuối URL là một registration_id.

Ví dụ về điểm cuối:

https://fcm.googleapis.com/fcm/send/APA91bHPffi8zclbIBDcToXN_LEpT6iA87pgR-J-MuuVVycM0SmptG-rXdCPKTM5pvKiHk2Ts-ukL1KV8exGOnurOAKdbvH9jcvg8h2gSi-zZJyToiiydjAJW6Fa9mE3_7vsNIgzF28KGspVmLUpMgYLBd1rxaVh-L4NDzD7HyTkhFOfwWiyVdKh__rEt15W9n2o6cZ8nxrP

URL FCM là:

https://fcm.googleapis.com/fcm/send

registration_id sẽ là:

APA91bHPffi8zclbIBDcToXN_LEpT6iA87pgR-J-MuuVVycM0SmptG-rXdCPKTM5pvKiHk2Ts-ukL1KV8exGOnurOAKdbvH9jcvg8h2gSi-zZJyToiiydjAJW6Fa9mE3_7vsNIgzF28KGspVmLUpMgYLBd1rxaVh-L4NDzD7HyTkhFOfwWiyVdKh__rEt15W9n2o6cZ8nxrP

Thao tác này dành riêng cho các trình duyệt sử dụng FCM. Trong trình duyệt thông thường, bạn chỉ cần lấy một điểm cuối và bạn sẽ gọi điểm cuối đó theo cách chuẩn và nó sẽ hoạt động bất kể URL là gì.

Tức là trên máy chủ của bạn, bạn cần kiểm tra xem điểm cuối là dành cho FCM và nếu có, hãy trích xuất registration_id. Để thực hiện việc này bằng Python, bạn có thể làm những việc như:

if endpoint.startswith('https://fcm.googleapis.com/fcm/send'):
    endpointParts = endpoint.split('/')
    registrationId = endpointParts[len(endpointParts) - 1]

    endpoint = 'https://fcm.googleapis.com/fcm/send'

Sau khi có ID đăng ký, bạn có thể gọi đến API FCM. Bạn có thể tìm thấy tài liệu tham khảo về API FCM tại đây.

Các khía cạnh chính cần nhớ khi gọi FCM là:

  • Tiêu đề Uỷ quyền có giá trị key=&lt;YOUR_API_KEY&gt; phải được đặt khi bạn gọi API, trong đó &lt;YOUR_API_KEY&gt; là Khoá API trong dự án Firebase.
    • Khoá API được FCM sử dụng để tìm mã người gửi thích hợp, đảm bảo người dùng đã cấp quyền cho dự án của bạn và cuối cùng đảm bảo địa chỉ IP của máy chủ có trong danh sách cho phép của dự án đó.
  • Tiêu đề Content-Type thích hợp của application/json hoặc application/x-www-form-urlencoded;charset=UTF-8 tuỳ thuộc vào việc bạn gửi dữ liệu dưới dạng JSON hoặc dữ liệu biểu mẫu.
  • Một mảng registration_ids – đây là các mã đăng ký của bạn trích xuất từ các điểm cuối từ người dùng của bạn.

Vui lòng xem tài liệu về cách gửi thông báo đẩy từ máy chủ của bạn, nhưng để kiểm tra nhanh trình chạy dịch vụ, bạn có thể sử dụng cURL để gửi thông báo đẩy tới trình duyệt của bạn.

Hoán đổi &lt;YOUR_API_KEY&gt;&lt;YOUR_REGISTRATION_ID&gt; trong lệnh cURL này theo cách của riêng bạn và chạy từ một cửa sổ dòng lệnh.

Bạn sẽ thấy một thông báo thú vị:

    curl --header "Authorization: key=<YOUR_API_KEY>" --header
    "Content-Type: application/json" https://fcm.googleapis.com/fcm/send -d
    "{\"registration_ids\":[\"<YOUR_REGISTRA>TION_ID\"]}"
Ví dụ về thông báo đẩy từ Chrome dành cho Android.

Khi phát triển logic phụ trợ, hãy nhớ rằng tiêu đề Uỷ quyền và của nội dung POST dành riêng cho điểm cuối FCM, vì vậy hãy phát hiện khi điểm cuối dành cho FCM và thêm tiêu đề và định dạng nội dung POST theo cách có điều kiện. Đối với các trình duyệt khác (và hy vọng là Chrome trong tương lai) bạn sẽ cần triển khai Web Push Protocol (Giao thức đẩy web).

Nhược điểm của cách triển khai hiện tại của API đẩy trong Chrome là bạn không thể gửi bất kỳ dữ liệu nào kèm theo thông báo đẩy. Không, không có gì. Lý do là trong tương lai, dữ liệu tải trọng sẽ phải được mã hoá trên trước khi được gửi đến điểm cuối thông báo đẩy. Bằng cách này, điểm cuối, cho dù đó là nhà cung cấp dịch vụ đẩy nào, sẽ không thể dễ dàng xem nội dung thông báo đẩy. Cách này cũng giúp chống lại các lỗ hổng bảo mật khác như xác thực chứng chỉ HTTPS và các cuộc tấn công xen giữa giữa và trình cung cấp thông báo đẩy. Tuy nhiên, lớp mã hoá này chưa được hỗ trợ trong thời gian chờ đợi, bạn sẽ cần thực hiện tìm nạp để lấy thông tin cần thiết nhằm điền thông báo.

Ví dụ về sự kiện đẩy hoàn chỉnh hơn

Thông báo mà chúng ta đã thấy cho đến bây giờ khá cơ bản và đối với các mẫu, nhưng lại kém hiệu quả trong việc cung cấp một trường hợp sử dụng thực tế.

Trên thực tế, hầu hết mọi người đều muốn nhận một số thông tin từ máy chủ của họ trước khi hiển thị thông báo. Đây có thể là dữ liệu để điền sẵn tiêu đề thông báo và nội dung thông báo bằng nội dung cụ thể hoặc tiến một bước xa hơn và lưu vào bộ nhớ đệm một số trang hoặc dữ liệu để khi người dùng nhấp vào thông báo, mọi thứ sẽ truy cập ngay lập tức khi trình duyệt được mở—ngay cả khi không có mạng tại thời điểm đó.

Trong mã sau, chúng ta tìm nạp một số dữ liệu từ một API, chuyển đổi phản hồi thành một và sử dụng đối tượng đó để điền thông báo của chúng ta.

self.addEventListener('push', function(event) {
    // Since there is no payload data with the first version
    // of push messages, we'll grab some data from
    // an API and use it to populate a notification
    event.waitUntil(
    fetch(SOME_API_ENDPOINT).then(function(response) {
        if (response.status !== 200) {
        // Either show a message to the user explaining the error
        // or enter a generic message and handle the
        // onnotificationclick event to direct the user to a web page
        console.log('Looks like there was a problem. Status Code: ' + response.status);
        throw new Error();
        }

        // Examine the text in the response
        return response.json().then(function(data) {
        if (data.error || !data.notification) {
            console.error('The API returned an error.', data.error);
            throw new Error();
        }

        var title = data.notification.title;
        var message = data.notification.message;
        var icon = data.notification.icon;
        var notificationTag = data.notification.tag;

        return self.registration.showNotification(title, {
            body: message,
            icon: icon,
            tag: notificationTag
        });
        });
    }).catch(function(err) {
        console.error('Unable to retrieve data', err);

        var title = 'An error occurred';
        var message = 'We were unable to get the information for this push message';
        var icon = URL_TO_DEFAULT_ICON;
        var notificationTag = 'notification-error';
        return self.registration.showNotification(title, {
            body: message,
            icon: icon,
            tag: notificationTag
        });
    })
    );
});

Một lần nữa, bạn cần nhấn mạnh rằng event.waitUntil() cam kết dẫn đến lời hứa được showNotification() trả về, nghĩa là trình nghe sự kiện của chúng ta sẽ không thoát cho đến khi lệnh gọi fetch() không đồng bộ hoàn tất và thông báo sẽ hiển thị.

Bạn sẽ nhận thấy rằng chúng tôi vẫn hiện thông báo ngay cả khi có lỗi. Đây là vì nếu chúng ta không làm như vậy, Chrome sẽ hiển thị thông báo chung của riêng Chrome.

Mở URL khi người dùng nhấp vào một thông báo

Khi người dùng nhấp vào một thông báo, sự kiện notificationclick sẽ được gửi đi trong trình chạy dịch vụ của bạn. Trong trình xử lý của mình, bạn có thể thực hiện hành động thích hợp, chẳng hạn như đặt tiêu điểm vào một thẻ hoặc mở một cửa sổ bằng một URL cụ thể:

self.addEventListener('notificationclick', function(event) {
    console.log('On notification click: ', event.notification.tag);
    // Android doesn't close the notification when you click on it
    // See: http://crbug.com/463146
    event.notification.close();

    // This looks to see if the current is already open and
    // focuses if it is
    event.waitUntil(
    clients.matchAll({
        type: "window"
    })
    .then(function(clientList) {
        for (var i = 0; i < clientList.length; i++) {
        var client = clientList[i];
        if (client.url == '/' && 'focus' in client)
            return client.focus();
        }
        if (clients.openWindow) {
        return clients.openWindow('/');
        }
    })
    );
});

Ví dụ này mở trình duyệt đến thư mục gốc của trang web, bằng cách tập trung vào một thẻ cùng nguồn gốc hiện có (nếu có) và mở một thẻ mới.

Có một bài đăng dành riêng cho một số việc bạn có thể làm với Notification API tại đây.

Huỷ đăng ký thiết bị của người dùng

Bạn đã đăng ký thiết bị của người dùng và họ sẽ nhận được thông báo đẩy, nhưng làm cách nào bạn huỷ đăng ký cho họ?

Những việc chính cần làm để huỷ đăng ký thiết bị của người dùng là gọi hàm Phương thức unsubscribe() trên PushSubscription và xóa điểm cuối khỏi máy chủ của bạn (chỉ để bạn không gửi thông báo đẩy mà bạn biết là sẽ không nhận được). Mã dưới đây chính xác như sau:

function unsubscribe() {
    var pushButton = document.querySelector('.js-push-button');
    pushButton.disabled = true;

    navigator.serviceWorker.ready.then(function(serviceWorkerRegistration) {
    // To unsubscribe from push messaging, you need get the
    // subscription object, which you can call unsubscribe() on.
    serviceWorkerRegistration.pushManager.getSubscription().then(
        function(pushSubscription) {
        // Check we have a subscription to unsubscribe
        if (!pushSubscription) {
            // No subscription object, so set the state
            // to allow the user to subscribe to push
            isPushEnabled = false;
            pushButton.disabled = false;
            pushButton.textContent = 'Enable Push Messages';
            return;
        }

        var subscriptionId = pushSubscription.subscriptionId;
        // TODO: Make a request to your server to remove
        // the subscriptionId from your data store so you
        // don't attempt to send them push messages anymore

        // We have a subscription, so call unsubscribe on it
        pushSubscription.unsubscribe().then(function(successful) {
            pushButton.disabled = false;
            pushButton.textContent = 'Enable Push Messages';
            isPushEnabled = false;
        }).catch(function(e) {
            // We failed to unsubscribe, this can lead to
            // an unusual state, so may be best to remove
            // the users data from your data store and
            // inform the user that you have done so

            console.log('Unsubscription error: ', e);
            pushButton.disabled = false;
            pushButton.textContent = 'Enable Push Messages';
        });
        }).catch(function(e) {
        console.error('Error thrown while unsubscribing from push messaging.', e);
        });
    });
}

Duy trì cập nhật gói thuê bao

Gói thuê bao có thể không đồng bộ hoá giữa FCM và máy chủ của bạn. Đảm bảo máy chủ của bạn phân tích cú pháp nội dung phản hồi của POST gửi của API FCM, đang tìm kiếm Kết quả của error:NotRegisteredcanonical_id, như giải thích trong tài liệu FCM.

Các gói thuê bao cũng có thể không đồng bộ giữa trình chạy dịch vụ và máy chủ. Ví dụ, sau khi đăng ký/huỷ đăng ký thành công, kết nối mạng có thể khiến bạn không cập nhật được máy chủ của mình; hoặc người dùng có thể thu hồi quyền gửi thông báo. Thao tác này sẽ kích hoạt tính năng tự động huỷ đăng ký. Tên người dùng những trường hợp như vậy bằng cách kiểm tra kết quả của serviceWorkerRegistration.pushManager.getSubscription() theo định kỳ (ví dụ: khi tải trang) và đồng bộ hoá trang này với máy chủ. Có thể bạn cũng muốn tự động đăng ký lại nếu bạn không còn gói thuê bao và Notification.permission == 'granted'.

Trong sendSubscriptionToServer(), bạn sẽ cần cân nhắc cách xử lý của mình không thực hiện được yêu cầu mạng khi cập nhật endpoint. Có một giải pháp là để theo dõi trạng thái của endpoint trong một cookie để xác định xem máy chủ của bạn có cần các chi tiết mới nhất hay không.

Tất cả các bước trên giúp triển khai đầy đủ thông báo đẩy trên web trong Chrome 46. Vẫn còn những tính năng được đặc tả kỹ thuật giúp mọi thứ trở nên dễ dàng hơn (giống như một API chuẩn để kích hoạt thông báo đẩy), nhưng bản phát hành này cho phép bạn hãy bắt đầu tạo thông báo đẩy vào ứng dụng web của bạn ngay hôm nay.

Cách gỡ lỗi ứng dụng web

Trong khi triển khai thông báo đẩy, lỗi sẽ xuất hiện ở một trong hai nơi: trang của bạn hoặc trình chạy dịch vụ của bạn.

Bạn có thể gỡ lỗi trên trang bằng DevTools. Để gỡ lỗi trình chạy dịch vụ vấn đề, bạn có hai lựa chọn:

  1. Chuyển đến chrome://console > Trình chạy dịch vụ. Chế độ xem này không cung cấp nhiều thông tin khác ngoài các trình chạy dịch vụ hiện đang chạy.
  2. Truy cập vào chrome://serviceworker-internals, sau đó bạn có thể xem trạng thái của trình chạy dịch vụ và xem lỗi (nếu có). Trang này là tạm thời cho đến khi Công cụ cho nhà phát triển có một bộ tính năng tương tự.

Một trong những mẹo hay nhất mà tôi có thể đưa ra cho những người mới làm quen với nhân viên dịch vụ là tạo sử dụng hộp đánh dấu có tên "Mở cửa sổ Công cụ cho nhà phát triển và tạm dừng thực thi JavaScript khi khởi động trình chạy dịch vụ để gỡ lỗi." Hộp đánh dấu này sẽ thêm điểm ngắt tại bắt đầu trình chạy dịch vụ và tạm dừng thực thi, điều này cho phép bạn tiếp tục hoặc duyệt qua tập lệnh trình chạy dịch vụ của bạn và xem liệu bạn có gặp bất kỳ vấn đề.

Ảnh chụp màn hình cho thấy vị trí của hộp đánh dấu tạm dừng thực thi trên serviceworker-internals.

Nếu có vẻ như có sự cố giữa FCM và sự kiện đẩy của trình chạy dịch vụ, thì bạn không thể làm gì để gỡ lỗi sự cố vì không có cách nào để bạn để xem Chrome có nhận được gì không. Điều quan trọng cần đảm bảo là phản hồi từ FCM thành công khi máy chủ của bạn thực hiện lệnh gọi API. Ứng dụng sẽ hiển thị chẳng hạn như:

{"multicast_id":1234567890,"success":1,"failure":0,"canonical_ids":0,"results":[{"message_id":"0:1234567890"}]}

Hãy lưu ý phản hồi "success": 1. Thay vào đó, nếu bạn thấy lỗi thì điều đó cho thấy có gì đó không ổn với ID đăng ký FCM và thông báo đẩy tin nhắn sẽ không được gửi tới Chrome.

Gỡ lỗi Trình chạy dịch vụ trên Chrome dành cho Android

Hiện tại, việc gỡ lỗi trình chạy dịch vụ trên Chrome dành cho Android chưa rõ ràng. Bạn cần chuyển đến chrome://inspect để tìm thiết bị của bạn rồi tìm mục trong danh sách có tên "Worker pid:...." URL này có URL của dịch vụ của bạn .

Ảnh chụp màn hình cho thấy vị trí của trình thực thi dịch vụ trong quá trình kiểm tra của Chrome

Trải nghiệm người dùng cho thông báo đẩy

Nhóm Chrome đã tập hợp một tài liệu bao gồm các phương pháp hay nhất về trải nghiệm người dùng của thông báo đẩy cũng như một tài liệu trình bày một số của các trường hợp đặc biệt khi làm việc với thông báo đẩy.

Tương lai của thông báo đẩy trên Chrome và web mở

Phần này đi sâu vào một chút thông tin chi tiết xung quanh một số giao diện của Chrome các phần cụ thể của quá trình triển khai này mà bạn nên biết cũng như cách thức sẽ khác với các cách triển khai trình duyệt khác.

Giao thức đẩy của web và điểm cuối

Điểm hay của tiêu chuẩn Push API là bạn có thể thực hiện điểm cuối, truyền chúng đến máy chủ của bạn và gửi thông báo đẩy bằng cách triển khai Giao thức đẩy web.

Giao thức đẩy web là tiêu chuẩn mới mà các nhà cung cấp dịch vụ đẩy có thể triển khai, giúp nhà phát triển không phải lo lắng về việc ai là nhà cung cấp thông báo đẩy. Chiến lược phát hành đĩa đơn ý tưởng là điều này giúp tránh phải đăng ký khoá API và gửi được định dạng giống như với FCM.

Chrome là trình duyệt đầu tiên triển khai Push API và FCM thì không hỗ trợ Giao thức đẩy web, đó là lý do tại sao Chrome yêu cầu gcm_sender_id và bạn cần sử dụng API nghỉ ngơi cho FCM.

Mục tiêu cuối cùng của Chrome là hướng tới sử dụng Giao thức đẩy web với Chrome và FCM.

Từ giờ đến lúc đó, bạn cần phát hiện điểm cuối &quot;https://fcm.googleapis.com/fcm/send&quot; và xử lý riêng biệt với các điểm cuối khác, chẳng hạn như định dạng dữ liệu tải trọng theo một theo cách cụ thể và thêm khoá Uỷ quyền.

Cách triển khai Giao thức đẩy web?

Firefox Nightly hiện đang nghiên cứu đẩy và có thể sẽ là trình duyệt đầu tiên để triển khai Giao thức đẩy web.

Câu hỏi thường gặp

Thông số kỹ thuật nằm ở đâu?

https://slightlyoff.github.io/ServiceWorker/spec/service_worker/ https://w3c.github.io/push-api/ https://notifications.spec.whatwg.org/

Tôi có thể ngăn chặn các thông báo trùng lặp nếu sự hiện diện của tôi trên web có nhiều nguồn gốc hoặc nếu tôi có cả phiên bản gốc và phiên bản web?

Hiện chưa có giải pháp cho vấn đề này, nhưng bạn có thể theo dõi tiến trình trên Chromium.

Trường hợp lý tưởng là có một số loại mã nhận dạng cho thiết bị của người dùng, sau đó ở phía máy chủ khớp với mã nhận dạng gói thuê bao của ứng dụng gốc và ứng dụng web hãy quyết định xem sẽ gửi thông báo đẩy đến trang nào. Bạn có thể thực hiện việc này thông qua kích thước màn hình, mẫu thiết bị của bạn, chia sẻ khoá được tạo giữa ứng dụng web và ứng dụng gốc, nhưng mỗi phương pháp đều có ưu và nhược điểm.

Tại sao tôi cần có gcm_sender_id?

Đây là yêu cầu bắt buộc để trình duyệt Chrome, Opera dành cho Android và Samsung có thể sử dụng API Giải pháp gửi thông báo qua đám mây của Firebase (FCM). Mục tiêu là sử dụng Giao thức đẩy web khi tiêu chuẩn được hoàn thiện và FCM có thể hỗ trợ tiêu chuẩn này.

Tại sao không sử dụng Web Sockets hoặc Sự kiện do máy chủ gửi (EventSource)?

Lợi thế của việc sử dụng thông báo đẩy là ngay cả khi trang của bạn bị đóng, Service worker sẽ được đánh thức và có thể hiển thị thông báo. Cổng web và EventSource sẽ đóng kết nối khi trang hoặc trình duyệt đóng.

Nếu tôi không cần phân phối sự kiện nền thì sao?

Nếu bạn không cần phân phối dưới nền thì Web Sockets là một lựa chọn tuyệt vời.

Khi nào tôi có thể sử dụng tính năng đẩy mà không hiển thị thông báo (tức là đẩy trong nền ở chế độ im lặng)?

Chưa có tiến trình khi nào tính năng này sẽ hoạt động, nhưng có một ý định triển khai tính năng đồng bộ hoá ở chế độ nền và trong khi chưa được quyết định hay thông số kỹ thuật, vẫn có một số cuộc thảo luận về việc bật đẩy thầm lặng cùng với tính năng đồng bộ hoá trong nền.

Tại sao phương thức này yêu cầu giao thức HTTPS? Làm cách nào để giải quyết vấn đề này trong quá trình phát triển?

Trình chạy dịch vụ yêu cầu các nguồn gốc bảo mật để đảm bảo rằng tập lệnh trình chạy dịch vụ xuất phát từ nguồn gốc dự định và không xuất phát từ một người trung gian cuộc tấn công. Hiện tại, điều đó có nghĩa là bạn phải sử dụng HTTPS trên các trang web trực tiếp, mặc dù localhost sẽ trong quá trình phát triển.

Việc hỗ trợ trình duyệt trông như thế nào?

Chrome hỗ trợ phiên bản ổn định và Mozilla đã triển khai tính năng đẩy trong Firefox Nightly. Xem lỗi triển khai API đẩy để biết thêm thông tin và bạn có thể theo dõi cách triển khai Thông báo tại đây.

Tôi có thể xoá thông báo sau một khoảng thời gian nhất định không?

Hiện tại, việc này chưa thể thực hiện được, nhưng chúng tôi đang lên kế hoạch hỗ trợ thêm để bạn có thể danh sách các thông báo hiện đang hiển thị. Nếu bạn có một trường hợp sử dụng để đặt hết hạn của thông báo sau khi thông báo được hiển thị, chúng tôi muốn biết ý nghĩa, vậy nên hãy thêm nhận xét và chúng tôi sẽ chuyển lại nhận xét cho nhóm Chrome.

Nếu bạn chỉ cần dừng gửi thông báo đẩy cho người dùng sau một khoảng thời gian nhất định cũng như không quan tâm thông báo hiển thị trong bao lâu hiển thị, sau đó bạn có thể sử dụng thông số Thời gian tồn tại (ttl) của FCM, tìm hiểu thêm tại đây.

Những hạn chế của thông báo đẩy trong Chrome là gì?

Có một vài giới hạn được nêu trong bài đăng này:

  • Việc Chrome sử dụng CCM như một dịch vụ đẩy tạo ra một số các yêu cầu liên quan. Chúng tôi đang cùng nhau xem xét liệu có thể khắc phục một số vấn đề trong số này hay không tương lai.
  • Bạn phải hiển thị thông báo khi nhận được thông báo đẩy.
  • Chrome trên máy tính để bàn có cảnh báo rằng nếu Chrome không chạy, hãy đẩy thông báo sẽ không được nhận. Điều này khác với ChromeOS và Android, trong đó thông báo đẩy sẽ luôn nhận được.

Không phải chúng ta nên sử dụng API Quyền sao?

Chiến lược phát hành đĩa đơn API Quyền được triển khai trong Chrome. nhưng không nhất thiết phải dùng được trong mọi trình duyệt. Tìm hiểu thêm tại đây.

Tại sao Chrome không mở thẻ trước đó khi tôi nhấp vào một thông báo?

Vấn đề này chỉ ảnh hưởng đến các trang hiện không do một dịch vụ kiểm soát . Bạn có thể tìm hiểu thêm tại đây.

Điều gì sẽ xảy ra nếu thông báo đã lỗi thời vào thời điểm thiết bị của người dùng nhận được thông báo đẩy?

Bạn luôn phải hiển thị thông báo khi nhận được thông báo đẩy. Trong trường hợp bạn muốn gửi thông báo nhưng thông báo đó chỉ hữu ích trong một khoảng thời gian nhất định, bạn có thể sử dụng tham số "time_to_live" thông số trên CCM để FCM không gửi thông báo đẩy nếu đã quá thời gian hết hạn.

Bạn có thể xem thêm thông tin tại đây.

Điều gì sẽ xảy ra nếu tôi gửi 10 thông báo đẩy nhưng chỉ muốn thiết bị nhận 1 thông báo?

FCM có một 'thu gọn_key' bạn có thể sử dụng để yêu cầu FCM thay thế bất kỳ thông số nào đang chờ xử lý tin nhắn có cùng 'thu gọn_key' với tin nhắn mới.

Bạn có thể xem thêm thông tin tại đây.