29

I am using new browser feature(navigator.sendBeacon) to POST async data to node.js server.

But i am unable to receive it on node server. So could any one tell me how to receive data posted by sendBeacon on node server.

node server code is:

var express = require('express');
var app = express();
var bodyParser = require('body-parser');

// set cross origin header to allow cross-origin request.
app.use(function(req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
  next();
});

app.use(bodyParser.json());

app.post('/',function(req,res){
    console.log('i got the request',req.body)
});

var server = app.listen(3000, function() {
    console.log('Express is listening to http://localhost:3000');
});

client side code

navigator.sendBeacon('http://localhost:3000/','{"a":9}')
coder
  • 1,874
  • 2
  • 22
  • 31

2 Answers2

45

navigator.sendBeacon POST uses Content-Type:text/plain;charset=UTF-8 to transmit string data. So just add bodyParser.text() to parse 'text/plain' data:

Server:

...
app.use(bodyParser.json());
app.use(bodyParser.text());
...

Client:

navigator.sendBeacon('http://localhost:3000/', JSON.stringify({a:9}));

Update

Apparently you can use Blob to add Content-Type:application/json header in your request:

Client:

var blob= new Blob([JSON.stringify({a:9})], {type : 'application/json; charset=UTF-8'}); // the blob
navigator.sendBeacon('http://localhost:3000/', blob )
hassansin
  • 16,918
  • 3
  • 43
  • 49
  • 2
    `application/x-www-form-urlencoded`, `multipart/form-data`, and `text/plain` are the only permitted values for sendBeacon Content-Type now - https://stackoverflow.com/questions/45274021/sendbeacon-api-not-working-temporarily-due-to-security-issue-any-workaround – Avocado Dec 06 '19 at 17:56
  • 2
    For more recent versions of express, use `app.use(express.text())` – e18r Aug 27 '20 at 13:11
0

we can send data by formData.

send data in client:

const formData = new FormData()
formData.append('resource', JSON.stringify({a:'test'}))
const success = navigator.sendBeacon('/api/url', formData)

receive data in server with express:

Express js form data

with koa2, I use koa2-formidable middleware only /api/url router.

JackChouMine
  • 947
  • 8
  • 22