Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Call a POST request for logging from window unload

Tags:

I have been struggling to write code that will make a POST request reliably on close of the tab window. Navigator.sendBeacon seems to be exactly what I need (I only require this to work for Google Chrome).

$(global).bind('unload', function () {
  let body = {
    UserEmail: appState.user.email,
    Job: {
      Id: appState.jobId
    },
    Timestamp: '/Date(' + new Date().getTime() + ')/',
    EventOrigin: 'PdfReviewClient',
    Event: 'JobClosed'
  };
  let headers = {
    Authorization: `JWT ${authenticationState.token}`,
    'Content-Type': 'application/json; charset=utf8'
  };
  let blob = new Blob([JSON.stringify(body)], headers);
  navigator.sendBeacon(configuration.rootApiUrl + 'jobevents', blob);
});

My beacon includes custom headers, that's why I create a Blob.

However, this request does not seem to be happening. This is especially hard to debug since the window closes. So the question is, why is my beacon not sending?

like image 389
Scotty H Avatar asked Jan 18 '17 22:01

Scotty H


1 Answers

The issue was the only header you can set with navigator.sendBeacon is Content-Type, and you set that by setting type in the Blob options. The server route had to be modified to accommodate the request without an Authorization header (I passed it as a URL parameter instead - weird for a POST request, but seemingly the only way to do that with a beacon). Here's how it looked in the end:

$(global).bind('unload', function () {
  if(appState.jobId == null) return;

  let headers = {
    type: 'application/json'
  };

  let jobEventLoggingBody = {
    UserEmail: appState.user.email,
    Job: {
      Id: appState.jobId
    },
    Timestamp: '/Date(' + new Date().getTime() + ')/',
    EventOrigin: 'PdfReviewClient',
    Event: 'JobClosed'
  };
  let jobEventLoggingUrl = `${configuration.rootApiUrl}jobevents?jwt=${authenticationState.token}`;
  let jobEventLoggingBlob = new Blob([JSON.stringify(jobEventLoggingBody)], headers);
  navigator.sendBeacon(jobEventLoggingUrl, jobEventLoggingBlob);
});

See also this question which specifically addresses sending headers in beacons.

like image 51
Scotty H Avatar answered Sep 24 '22 10:09

Scotty H