Skip to content

Commit 2f291a7

Browse files
Paul Boocockpaulboocock
authored andcommitted
Update beacon support to handle "gotchas" (close snowplow#716)
1 parent d7319f7 commit 2f291a7

2 files changed

Lines changed: 44 additions & 3 deletions

File tree

src/js/lib/helpers.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -348,6 +348,37 @@
348348
}
349349
};
350350

351+
/**
352+
* Attempt to get a value from sessionStorage
353+
*
354+
* @param string key
355+
* @return string The value obtained from sessionStorage, or
356+
* undefined if sessionStorage is inaccessible
357+
*/
358+
object.attemptGetSessionStorage = function (key) {
359+
try {
360+
return sessionStorage.getItem(key);
361+
} catch(e) {
362+
return undefined;
363+
}
364+
};
365+
366+
/**
367+
* Attempt to write a value to localStorage
368+
*
369+
* @param string key
370+
* @param string value
371+
* @return boolean Whether the operation succeeded
372+
*/
373+
object.attemptWriteSessionStorage = function (key, value) {
374+
try {
375+
sessionStorage.setItem(key, value);
376+
return true;
377+
} catch(e) {
378+
return false;
379+
}
380+
};
381+
351382
/**
352383
* Finds the root domain
353384
*/

src/js/out_queue.js

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,9 @@
6565
var queueName,
6666
executingQueue = false,
6767
configCollectorUrl,
68-
outQueue;
68+
outQueue,
69+
preflightName,
70+
beaconPreflight;
6971

7072
//Force to lower case if its a string
7173
eventMethod = eventMethod.toLowerCase ? eventMethod.toLowerCase() : eventMethod;
@@ -92,7 +94,9 @@
9294
bufferSize = (localStorageAccessible() && useLocalStorage && usePost && bufferSize) || 1;
9395

9496
// Different queue names for GET and POST since they are stored differently
95-
queueName = ['snowplowOutQueue', functionName, namespace, usePost ? 'post2' : 'get'].join('_');
97+
queueName = `snowplowOutQueue_${functionName}_${namespace}_${usePost ? 'post2' : 'get'}`;
98+
// Storage name for checking if preflight POST has been sent for Beacon API
99+
preflightName = `spBeaconPreflight_${functionName}_${namespace}`;
96100

97101
if (useLocalStorage) {
98102
// Catch any JSON parse errors or localStorage that might be thrown
@@ -286,6 +290,9 @@
286290
xhr.onreadystatechange = function () {
287291
if (xhr.readyState === 4 && xhr.status >= 200 && xhr.status < 400) {
288292
clearTimeout(xhrTimeout);
293+
if (useBeacon && !beaconPreflight) {
294+
helpers.attemptWriteSessionStorage(preflightName, true);
295+
}
289296
onPostSuccess(numberToSend);
290297
} else if (xhr.readyState === 4 && xhr.status >= 400) {
291298
clearTimeout(xhrTimeout);
@@ -300,7 +307,10 @@
300307
if (batch.length > 0) {
301308
var beaconStatus;
302309

303-
if (useBeacon) {
310+
//If using Beacon, check we have sent at least one request using POST as Safari doesn't preflight Beacon
311+
beaconPreflight = beaconPreflight || (useBeacon && helpers.attemptGetSessionStorage(preflightName));
312+
313+
if (beaconPreflight) {
304314
const headers = { type: 'application/json' };
305315
const blob = new Blob([encloseInPayloadDataEnvelope(attachStmToEvent(batch))], headers);
306316
try {

0 commit comments

Comments
 (0)