未加星标

Browser push notifications using JavaScript

字体大小 | |
[前端(javascript) 所属分类 前端(javascript) | 发布者 店小二05 | 时间 2016 | 作者 红领巾 ] 0人收藏点击收藏

Browser push notifications using JavaScript
Picture credit: wingify

In this article, we will discuss about sending browser push notifications using javascript. The image given below is a sample browser push notification.

There are so many third party vendors who are providing this service with basic subscription costing around 25 30$/month

Some of them are: moengage , pushcrew , pushengage , izooto , more…

So if you are a JavaScript developer, you will be able to do this without any third party subscription. Let me explain it in detail.

What is a Service Worker?

It is a script that runs silently in the background of a browser which is registered against an origin and path. A registered service worker doesn’t need the webpage to be opened in order to work. It runs in a separate thread which is non-blocking in manner and is designed to be asynchronous hence we cannot use APIs such as synchronous XHR and local storage inside a service worker.

Service workers are so powerful. If you are a black hat, you can use it to hijack network connections and reconstruct their response. For such security reasons, they are allowed to be run only over HTTPS. For development, you can use localhost which is considered as a secure origin.

Support

Service workers are currently supported in Chrome (version 42 and above), Firefox (version 44 and above),and opera(version 27 and above) on desktop. On mobiles, it is available on Android (version 4 and above) default browser and on Android Chrome. For Edge,this technology is under development and for Safari it is under consideration.

To check for installed service workers on your browser for different domains;

For Chrome:

chrome://serviceworker-internals


Browser push notifications using JavaScript

For Firefox:

about:serviceworkers
Browser push notifications using JavaScript

And in your js script, you can use below expression to check for the support of service worker for any browser.

('serviceWorker' in navigator) //returns true if service worker is supported in the browser/. Service Worker Life Cycle
Browser push notifications using JavaScript
Now lets start building the first Web push Notification application with payload. Create a project in Google Developer Console and generate a GCM browser API key which you will be using in your node script later. Project Structure:
Browser push notifications using JavaScript
Implementation:

First we will create a file called service-worker.js which will add event listeners to the service worker workspace up on registration.

self.addEventListener('install', function(event) {
event.waitUntil(self.skipWaiting()); //will install the serviceworker
});
self.addEventListener('activate', function(event) {
event.waitUntil(self.clients.claim()); //will activate the serviceworker
});
// Register event listener for the 'push' event.
self.addEventListener('push', function(event) {
// Retrieve the textual payload from event.data (a PushMessageData object).
var payload = JSON.parse(event.data.text());
var clickUrl = payload.url;
// Keep the service worker alive until the web push notification is created.
event.waitUntil(
// Show a notification
self.registration.showNotification(payload.title, {
body: payload.body,
icon: payload.icon
})
);
});
// Register event listener for the 'notificationclick' event.
self.addEventListener('notificationclick', function(event) {
event.waitUntil(
// Retrieve a list of the clients of this service worker.
self.clients.matchAll().then(function(clientList) {
// If there is at least one client, focus it.
if (clientList.length > 0) {
return clientList[0].focus();
}
// Otherwise, open a new page.
return self.clients.openWindow(clickUrl);
})
);
});

Now we will create index.js file where service worker registration is initiated.

var endpoint;
var key;
var authSecret;
// Register a Service Worker.
navigator.serviceWorker.register('service-worker.js')
.then(function(registration) {
// Use the PushManager to get the user's subscription to the push service.
//service worker.ready will return the promise once the service worker is registered. This can help to get rid of
//errors that occur while fetching subscription information before registration of the service worker
return navigator.serviceWorker.ready.then(function(serviceWorkerRegistration) {
return serviceWorkerRegistration.pushManager.getSubscription()
.then(function(subscription) {
// If a subscription was found, return it.
if (subscription) {return subscription;
}
// Otherwise, subscribe the user (userVisibleOnly allows to specify that we don't plan to
// send browser push notifications that don't have a visible effect for the user).
return serviceWorkerRegistration.pushManager.subscribe({userVisibleOnly: true
});
});
});
}).then(function(subscription) { //chaining the subscription promise object
// Retrieve the user's public key.
var rawKey = subscription.getKey ? subscription.getKey('p256dh') : '';
key = rawKey ?
btoa(String.fromCharCode.apply(null, new Uint8Array(rawKey))) :
'';
var rawAuthSecret = subscription.getKey ? subscription.getKey('auth') : '';
authSecret = rawAuthSecret ?
btoa(String.fromCharCode.apply(null, new Uint8Array(rawAuthSecret))) :
'';
endpoint = subscription.endpoint;
// Send the subscription details to the server using the Fetch API.
fetch('/register', {
method: 'post',
headers: {
'Content-type': 'application/json'
},
body: JSON.stringify({
endpoint: subscription.endpoint,
key: key,
authSecret: authSecret,
}),
});
});
// Ask the server to send the client a notification (for testing purposes, in real
// applications the notification will be generated by some event on the server).
document.getElementById('doIt').addEventListener('click', function() {
fetch('/sendNotification', {
method: 'post',
headers: {
'Content-type': 'application/json'
},
body: JSON.stringify({
endpoint: endpoint,
key: key,
authSecret: authSecret,
title: document.getElementById("notificationTitle").value,
body: document.getElementById("notificationBody").value,
icon: document.getElementById("notificationIcon").value,
link: document.getElementById("notificationLink").value
}),
});
});

your manifest.json

{
"name": "Push Notifications",
"short_name": "push Notifications",
"start_url": "./index.html",
"display": "standalone",
"gcm_sender_id": "xxxxxxxxxxx",
"gcm_user_visible_only": true
}

Include the script in your index.html file

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Service Workers -Push Notifications</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="manifest" href="manifest.json">
</head>
<body>
<span> Title</span>
<input type="text" id="notificationTitle" />
<br/>
<span> body</span>
<input type="text" id="notificationBody" />
<br/>
<span> Icon Url</span>
<input type="url" id="notificationIcon" />
<br/>
<span> Link</span>
<input type="url" id="notificationLink" />
<br/>
<button id="doIt">Send notification</button>
<script src="./index.js"></script>
</body>
</html>

your server side script will be in server.js

// Use the web-push library to hide the implementation details of the communication
// between the application server and the push service.
// For details, see https://tools.ietf.org/html/draft-ietf-webpush-protocol and
// https://tools.ietf.org/html/draft-ietf-webpush-encryption.
var express = require('express');
var app = express();
var webPush = require('web-push');
var bodyParser = require('body-parser')
webPush.setGCMAPIKey(process.env.GCM_API_KEY);
app.set('port', 5000);
app.use(express.static(__dirname + '/'));
app.use(bodyParser.json())
webPush.setGCMAPIKey(process.env.GCM_API_KEY);
app.post('/register', function(req, res) {
// A real world application would store the subscription info.
res.sendStatus(201);
});
app.post('/sendNotification', function(req, res) {
webPush.sendNotification(req.body.endpoint, {
TTL: 4000,
payload: JSON.stringify({
'title': req.body.title,
'icon': req.body.icon,
'body': req.body.body,
url: req.body.link
}),
userPublicKey: req.body.key,
userAuth: req.body.authSecret,
})
ndStatus(201);
}, function(err) {
console.log(err);
});
});
app.listen(app.get('port'), function() {
console.log('Node app is running on port', app.get('port'));
});
.then(function() {
res.sendStatus(201);
}, function(err) {
console.log(err);
});
});
app.listen(app.get('port'), function() {
console.log('Node app is running on port', app.get('port'));
});

Note:Hope the code is self explanatory as we have put comments everywhere.

Running your project:

Install the node dependencies and start your server using command “ node serve r ” which will serve the static index.html at its base.

Now open http://localhost:5000 on your browser


Browser push notifications using JavaScript

Click “ Allow ” to let the browser allow notifications from the domain “ http://localhost:5000 ”


Browser push notifications using JavaScript

Fill the form and send notification


Browser push notifications using JavaScript

YAY! GOT IT


Browser push notifications using JavaScript
What if your production site doesn’t use HTTP’s.

You can go with a third party library where you need to buy a basic subscription that costs around 25 30$/month.

Let me explain what do they do to your HTTP site. When user wants to activate browser push notifications on your http site, they will open a popup window in HTTP’s having their domain name and with a sub domain(usually your domain name) of your choice. So the moment a user registers, a service worker will be registered under this domain name.

An example would be

e.g. https://cronj.notificationcrew.com

where ‘notificationcrew’ is the third party vendors domain name. There is no workaround without a HTTP’s site. So if you are having some other HTTP’s site, you can create a sub domain having name same as your HTTP domain name. Let’s say http://cronj.com is your HTTP site and you have some other HTTP’s site which is as https://subscribe.com . Your subdomain would be something like https://cronj.subscribe.com

Now here you can gather browser endpoint data by opening a popup window on your HTTP site (http://cronj.com).The popup window will be served over HTTP’s which will hold all your service worker scripts. e.g: https://cronj.subscribe.com/notificationsubscribe.html will be opened in a popup that can have markup and service worker scripts included.

You need to “Allow” notifications on the browser default popup which means browser will allow notifications that are registered under this domain name.Service workers will now be registered in your browser and you will be saving the browser subscription info in your application database by making an ajax call.

As now you have the browser endpoints data with you,your server can request GCM to fire a notification to these endpoints.

At this point,what if the user wants to unsubscribe from the notifications.

You have notifications activated, but you cannot have access to the service worker subscription data from a HTTP domain. It is not recommended to open a popup on HTTP’s every time the user wants to unsubscribe/resubscribe to notifications.

Here Comes the browser fingerprinting,

Fingerprinting is a technique which is outlined in the research by Electronic Frontier Foundation, of anonymously identifying a web browser with accuracy of up to 94%. As they explained, “Browser is queried its agent string, screen resolution and color depth, installed plugins with supported mime types, timezone offset and other capabilities, such as local storage and session storage. Then these values are passed through a hashing function to produce a fingerprint that gives weak guarantees of uniqueness”.

Since the accuracy is 94%, we will use fingerprint + ip address for 100% accuracy.

We will store this unique identification (fingerprint + ip address) of the browser along with the push subscription data in the database. When user visits your HTTP site, you can generate the fingerprint again and check for the push subscription details in the database. You can even have a flag like DND(Do Not Disturb) which you could reset every time the user unsubscribe/re-subscribe from the HTTP domain.

本文前端(javascript)相关术语:javascript是什么意思 javascript下载 javascript权威指南 javascript基础教程 javascript 正则表达式 javascript设计模式 javascript高级程序设计 精通javascript javascript教程

主题: JavaJavaScriptChromeAndroidFirefox
分页:12
转载请注明
本文标题:Browser push notifications using JavaScript
本站链接:http://www.codesec.net/view/480351.html
分享请点击:


1.凡CodeSecTeam转载的文章,均出自其它媒体或其他官网介绍,目的在于传递更多的信息,并不代表本站赞同其观点和其真实性负责;
2.转载的文章仅代表原创作者观点,与本站无关。其原创性以及文中陈述文字和内容未经本站证实,本站对该文以及其中全部或者部分内容、文字的真实性、完整性、及时性,不作出任何保证或承若;
3.如本站转载稿涉及版权等问题,请作者及时联系本站,我们会及时处理。
登录后可拥有收藏文章、关注作者等权限...
技术大类 技术大类 | 前端(javascript) | 评论(0) | 阅读(40)