You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flagon.apache.org by un...@apache.org on 2021/05/13 20:21:34 UTC

[incubator-flagon-useralejs] branch test updated: [flagon-userale-50] fixes sendOnClose function using sendBeacon

This is an automated email from the ASF dual-hosted git repository.

unclegedd pushed a commit to branch test
in repository https://gitbox.apache.org/repos/asf/incubator-flagon-useralejs.git


The following commit(s) were added to refs/heads/test by this push:
     new 8c212fc  [flagon-userale-50] fixes sendOnClose function using sendBeacon
8c212fc is described below

commit 8c212fcd8f8b92699f0cf6d3b9541a11fb28809f
Author: unclegedd <un...@apache.org>
AuthorDate: Thu May 13 15:20:15 2021 -0500

    [flagon-userale-50] fixes sendOnClose function using sendBeacon
---
 build/UserALEWebExtension/background.js |  49 +++---
 build/UserALEWebExtension/content.js    | 255 ++++++++++++++------------------
 build/userale-2.1.1.js                  | 225 ++++++++++++----------------
 build/userale-2.1.1.min.js              |   2 +-
 example/index.html                      |   6 +
 example/server.js                       |   7 +-
 src/attachHandlers.js                   |   3 -
 src/sendLogs.js                         |  37 +----
 test/sendLogs_spec.js                   |  54 +------
 9 files changed, 254 insertions(+), 384 deletions(-)

diff --git a/build/UserALEWebExtension/background.js b/build/UserALEWebExtension/background.js
index de4735a..30de8b5 100644
--- a/build/UserALEWebExtension/background.js
+++ b/build/UserALEWebExtension/background.js
@@ -1,18 +1,18 @@
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements.  See the NOTICE file distributed with
-    * this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-    * the License.  You may obtain a copy of the License at
-*
-*   http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  See the NOTICE file distributed with
+    * this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+    * the License.  You may obtain a copy of the License at
+*
+*   http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
 */
 
 /* eslint-disable */
@@ -389,21 +389,12 @@ function sendOnInterval(logs, config) {
  */
 
 function sendOnClose(logs, config) {
-  if (!config.on) {
-    return;
-  }
-
-  if (navigator.sendBeacon) {
-    window.addEventListener('unload', function () {
+  window.addEventListener('pagehide', function () {
+    if (logs.length > 0) {
       navigator.sendBeacon(config.url, JSON.stringify(logs));
-    });
-  } else {
-    window.addEventListener('beforeunload', function () {
-      if (logs.length > 0) {
-        sendLogs(logs, config, 1);
-      }
-    });
-  }
+      logs.splice(0); // clear log queue
+    }
+  });
 }
 /**
  * Sends the provided array of logs to the specified url,
diff --git a/build/UserALEWebExtension/content.js b/build/UserALEWebExtension/content.js
index 26c09e8..34168db 100644
--- a/build/UserALEWebExtension/content.js
+++ b/build/UserALEWebExtension/content.js
@@ -1,18 +1,18 @@
-/*
-* Licensed to the Apache Software Foundation (ASF) under one or more
-* contributor license agreements.  See the NOTICE file distributed with
-    * this work for additional information regarding copyright ownership.
-* The ASF licenses this file to You under the Apache License, Version 2.0
-* (the "License"); you may not use this file except in compliance with
-    * the License.  You may obtain a copy of the License at
-*
-*   http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
+/*
+* Licensed to the Apache Software Foundation (ASF) under one or more
+* contributor license agreements.  See the NOTICE file distributed with
+    * this work for additional information regarding copyright ownership.
+* The ASF licenses this file to You under the Apache License, Version 2.0
+* (the "License"); you may not use this file except in compliance with
+    * the License.  You may obtain a copy of the License at
+*
+*   http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
 */
 
 /* eslint-disable */
@@ -762,132 +762,6 @@ function detectBrowser() {
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-var sendIntervalId = null;
-/**
- * Initializes the log queue processors.
- * @param  {Array} logs   Array of logs to append to.
- * @param  {Object} config Configuration object to use when logging.
- */
-
-function initSender(logs, config) {
-  if (sendIntervalId !== null) {
-    clearInterval(sendIntervalId);
-  }
-
-  sendIntervalId = sendOnInterval(logs, config);
-  sendOnClose(logs, config);
-}
-/**
- * Checks the provided log array on an interval, flushing the logs
- * if the queue has reached the threshold specified by the provided config.
- * @param  {Array} logs   Array of logs to read from.
- * @param  {Object} config Configuration object to be read from.
- * @return {Number}        The newly created interval id.
- */
-
-function sendOnInterval(logs, config) {
-  return setInterval(function () {
-    if (!config.on) {
-      return;
-    }
-
-    if (logs.length >= config.logCountThreshold) {
-      sendLogs(logs.slice(0), config, 0); // Send a copy
-
-      logs.splice(0); // Clear array reference (no reassignment)
-    }
-  }, config.transmitInterval);
-}
-/**
- * Provides a simplified send function that can be called before events that would
- * refresh page can resolve so that log queue ('logs) can be shipped immediately. This
- * is different than sendOnClose because browser security practices prevent you from
- * listening the process responsible for window navigation actions, in action (e.g., refresh;
- * you can only detect, after the fact, the process responsible for the current window state.
- * @param  {Array} logs   Array of logs to read from.
- * @param  {Object} config Configuration object to be read from.
- */
-
-function sendOnRefresh(logs, config) {
-  if (!config.on) {
-    return;
-  }
-
-  if (logs.length > 0) {
-    sendLogs(logs, config, 1);
-  }
-}
-/**
- * Attempts to flush the remaining logs when the window is closed.
- * @param  {Array} logs   Array of logs to be flushed.
- * @param  {Object} config Configuration object to be read from.
- */
-
-function sendOnClose(logs, config) {
-  if (!config.on) {
-    return;
-  }
-
-  if (navigator.sendBeacon) {
-    window.addEventListener('unload', function () {
-      navigator.sendBeacon(config.url, JSON.stringify(logs));
-    });
-  } else {
-    window.addEventListener('beforeunload', function () {
-      if (logs.length > 0) {
-        sendLogs(logs, config, 1);
-      }
-    });
-  }
-}
-/**
- * Sends the provided array of logs to the specified url,
- * retrying the request up to the specified number of retries.
- * @param  {Array} logs    Array of logs to send.
- * @param  {string} config     configuration parameters (e.g., to extract URL from & send the POST request to).
- * @param  {Number} retries Maximum number of attempts to send the logs.
- */
-// @todo expose config object to sendLogs replate url with config.url
-
-function sendLogs(logs, config, retries) {
-  var req = new XMLHttpRequest(); // @todo setRequestHeader for Auth
-
-  var data = JSON.stringify(logs);
-  req.open('POST', config.url);
-
-  if (config.authHeader) {
-    req.setRequestHeader('Authorization', config.authHeader);
-  }
-
-  req.setRequestHeader('Content-type', 'application/json;charset=UTF-8');
-
-  req.onreadystatechange = function () {
-    if (req.readyState === 4 && req.status !== 200) {
-      if (retries > 0) {
-        sendLogs(logs, config, retries--);
-      }
-    }
-  };
-
-  req.send(data);
-}
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- * 
- *   http://www.apache.org/licenses/LICENSE-2.0
- * 
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
 var events;
 var bufferBools;
 var bufferedEvents; //@todo: Investigate drag events and their behavior
@@ -1011,7 +885,6 @@ function attachHandlers(config) {
   Object.keys(refreshEvents).forEach(function (ev) {
     document.addEventListener(ev, function (e) {
       packageLog(e, events[ev]);
-      sendOnRefresh(logs$1, config);
     }, true);
   });
   windowEvents.forEach(function (ev) {
@@ -1026,6 +899,104 @@ function attachHandlers(config) {
   return true;
 }
 
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+var sendIntervalId = null;
+/**
+ * Initializes the log queue processors.
+ * @param  {Array} logs   Array of logs to append to.
+ * @param  {Object} config Configuration object to use when logging.
+ */
+
+function initSender(logs, config) {
+  if (sendIntervalId !== null) {
+    clearInterval(sendIntervalId);
+  }
+
+  sendIntervalId = sendOnInterval(logs, config);
+  sendOnClose(logs, config);
+}
+/**
+ * Checks the provided log array on an interval, flushing the logs
+ * if the queue has reached the threshold specified by the provided config.
+ * @param  {Array} logs   Array of logs to read from.
+ * @param  {Object} config Configuration object to be read from.
+ * @return {Number}        The newly created interval id.
+ */
+
+function sendOnInterval(logs, config) {
+  return setInterval(function () {
+    if (!config.on) {
+      return;
+    }
+
+    if (logs.length >= config.logCountThreshold) {
+      sendLogs(logs.slice(0), config, 0); // Send a copy
+
+      logs.splice(0); // Clear array reference (no reassignment)
+    }
+  }, config.transmitInterval);
+}
+/**
+ * Attempts to flush the remaining logs when the window is closed.
+ * @param  {Array} logs   Array of logs to be flushed.
+ * @param  {Object} config Configuration object to be read from.
+ */
+
+function sendOnClose(logs, config) {
+  window.addEventListener('pagehide', function () {
+    if (logs.length > 0) {
+      navigator.sendBeacon(config.url, JSON.stringify(logs));
+      logs.splice(0); // clear log queue
+    }
+  });
+}
+/**
+ * Sends the provided array of logs to the specified url,
+ * retrying the request up to the specified number of retries.
+ * @param  {Array} logs    Array of logs to send.
+ * @param  {string} config     configuration parameters (e.g., to extract URL from & send the POST request to).
+ * @param  {Number} retries Maximum number of attempts to send the logs.
+ */
+// @todo expose config object to sendLogs replate url with config.url
+
+function sendLogs(logs, config, retries) {
+  var req = new XMLHttpRequest(); // @todo setRequestHeader for Auth
+
+  var data = JSON.stringify(logs);
+  req.open('POST', config.url);
+
+  if (config.authHeader) {
+    req.setRequestHeader('Authorization', config.authHeader);
+  }
+
+  req.setRequestHeader('Content-type', 'application/json;charset=UTF-8');
+
+  req.onreadystatechange = function () {
+    if (req.readyState === 4 && req.status !== 200) {
+      if (retries > 0) {
+        sendLogs(logs, config, retries--);
+      }
+    }
+  };
+
+  req.send(data);
+}
+
 var config = {};
 var logs = [];
 var startLoadTimestamp = Date.now();
diff --git a/build/userale-2.1.1.js b/build/userale-2.1.1.js
index 90c80f9..b7d4e3d 100644
--- a/build/userale-2.1.1.js
+++ b/build/userale-2.1.1.js
@@ -764,132 +764,6 @@
    * See the License for the specific language governing permissions and
    * limitations under the License.
    */
-  var sendIntervalId = null;
-  /**
-   * Initializes the log queue processors.
-   * @param  {Array} logs   Array of logs to append to.
-   * @param  {Object} config Configuration object to use when logging.
-   */
-
-  function initSender(logs, config) {
-    if (sendIntervalId !== null) {
-      clearInterval(sendIntervalId);
-    }
-
-    sendIntervalId = sendOnInterval(logs, config);
-    sendOnClose(logs, config);
-  }
-  /**
-   * Checks the provided log array on an interval, flushing the logs
-   * if the queue has reached the threshold specified by the provided config.
-   * @param  {Array} logs   Array of logs to read from.
-   * @param  {Object} config Configuration object to be read from.
-   * @return {Number}        The newly created interval id.
-   */
-
-  function sendOnInterval(logs, config) {
-    return setInterval(function () {
-      if (!config.on) {
-        return;
-      }
-
-      if (logs.length >= config.logCountThreshold) {
-        sendLogs(logs.slice(0), config, 0); // Send a copy
-
-        logs.splice(0); // Clear array reference (no reassignment)
-      }
-    }, config.transmitInterval);
-  }
-  /**
-   * Provides a simplified send function that can be called before events that would
-   * refresh page can resolve so that log queue ('logs) can be shipped immediately. This
-   * is different than sendOnClose because browser security practices prevent you from
-   * listening the process responsible for window navigation actions, in action (e.g., refresh;
-   * you can only detect, after the fact, the process responsible for the current window state.
-   * @param  {Array} logs   Array of logs to read from.
-   * @param  {Object} config Configuration object to be read from.
-   */
-
-  function sendOnRefresh(logs, config) {
-    if (!config.on) {
-      return;
-    }
-
-    if (logs.length > 0) {
-      sendLogs(logs, config, 1);
-    }
-  }
-  /**
-   * Attempts to flush the remaining logs when the window is closed.
-   * @param  {Array} logs   Array of logs to be flushed.
-   * @param  {Object} config Configuration object to be read from.
-   */
-
-  function sendOnClose(logs, config) {
-    if (!config.on) {
-      return;
-    }
-
-    if (navigator.sendBeacon) {
-      window.addEventListener('unload', function () {
-        navigator.sendBeacon(config.url, JSON.stringify(logs));
-      });
-    } else {
-      window.addEventListener('beforeunload', function () {
-        if (logs.length > 0) {
-          sendLogs(logs, config, 1);
-        }
-      });
-    }
-  }
-  /**
-   * Sends the provided array of logs to the specified url,
-   * retrying the request up to the specified number of retries.
-   * @param  {Array} logs    Array of logs to send.
-   * @param  {string} config     configuration parameters (e.g., to extract URL from & send the POST request to).
-   * @param  {Number} retries Maximum number of attempts to send the logs.
-   */
-  // @todo expose config object to sendLogs replate url with config.url
-
-  function sendLogs(logs, config, retries) {
-    var req = new XMLHttpRequest(); // @todo setRequestHeader for Auth
-
-    var data = JSON.stringify(logs);
-    req.open('POST', config.url);
-
-    if (config.authHeader) {
-      req.setRequestHeader('Authorization', config.authHeader);
-    }
-
-    req.setRequestHeader('Content-type', 'application/json;charset=UTF-8');
-
-    req.onreadystatechange = function () {
-      if (req.readyState === 4 && req.status !== 200) {
-        if (retries > 0) {
-          sendLogs(logs, config, retries--);
-        }
-      }
-    };
-
-    req.send(data);
-  }
-
-  /*
-   * Licensed to the Apache Software Foundation (ASF) under one or more
-   * contributor license agreements.  See the NOTICE file distributed with
-   * this work for additional information regarding copyright ownership.
-   * The ASF licenses this file to You under the Apache License, Version 2.0
-   * (the "License"); you may not use this file except in compliance with
-   * the License.  You may obtain a copy of the License at
-   * 
-   *   http://www.apache.org/licenses/LICENSE-2.0
-   * 
-   * Unless required by applicable law or agreed to in writing, software
-   * distributed under the License is distributed on an "AS IS" BASIS,
-   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   * See the License for the specific language governing permissions and
-   * limitations under the License.
-   */
   var events;
   var bufferBools;
   var bufferedEvents; //@todo: Investigate drag events and their behavior
@@ -1078,7 +952,6 @@
     Object.keys(refreshEvents).forEach(function (ev) {
       document.addEventListener(ev, function (e) {
         packageLog(e, events[ev]);
-        sendOnRefresh(logs$1, config);
       }, true);
     });
     windowEvents.forEach(function (ev) {
@@ -1093,6 +966,104 @@
     return true;
   }
 
+  /*
+   * Licensed to the Apache Software Foundation (ASF) under one or more
+   * contributor license agreements.  See the NOTICE file distributed with
+   * this work for additional information regarding copyright ownership.
+   * The ASF licenses this file to You under the Apache License, Version 2.0
+   * (the "License"); you may not use this file except in compliance with
+   * the License.  You may obtain a copy of the License at
+   * 
+   *   http://www.apache.org/licenses/LICENSE-2.0
+   * 
+   * Unless required by applicable law or agreed to in writing, software
+   * distributed under the License is distributed on an "AS IS" BASIS,
+   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   * See the License for the specific language governing permissions and
+   * limitations under the License.
+   */
+  var sendIntervalId = null;
+  /**
+   * Initializes the log queue processors.
+   * @param  {Array} logs   Array of logs to append to.
+   * @param  {Object} config Configuration object to use when logging.
+   */
+
+  function initSender(logs, config) {
+    if (sendIntervalId !== null) {
+      clearInterval(sendIntervalId);
+    }
+
+    sendIntervalId = sendOnInterval(logs, config);
+    sendOnClose(logs, config);
+  }
+  /**
+   * Checks the provided log array on an interval, flushing the logs
+   * if the queue has reached the threshold specified by the provided config.
+   * @param  {Array} logs   Array of logs to read from.
+   * @param  {Object} config Configuration object to be read from.
+   * @return {Number}        The newly created interval id.
+   */
+
+  function sendOnInterval(logs, config) {
+    return setInterval(function () {
+      if (!config.on) {
+        return;
+      }
+
+      if (logs.length >= config.logCountThreshold) {
+        sendLogs(logs.slice(0), config, 0); // Send a copy
+
+        logs.splice(0); // Clear array reference (no reassignment)
+      }
+    }, config.transmitInterval);
+  }
+  /**
+   * Attempts to flush the remaining logs when the window is closed.
+   * @param  {Array} logs   Array of logs to be flushed.
+   * @param  {Object} config Configuration object to be read from.
+   */
+
+  function sendOnClose(logs, config) {
+    window.addEventListener('pagehide', function () {
+      if (logs.length > 0) {
+        navigator.sendBeacon(config.url, JSON.stringify(logs));
+        logs.splice(0); // clear log queue
+      }
+    });
+  }
+  /**
+   * Sends the provided array of logs to the specified url,
+   * retrying the request up to the specified number of retries.
+   * @param  {Array} logs    Array of logs to send.
+   * @param  {string} config     configuration parameters (e.g., to extract URL from & send the POST request to).
+   * @param  {Number} retries Maximum number of attempts to send the logs.
+   */
+  // @todo expose config object to sendLogs replate url with config.url
+
+  function sendLogs(logs, config, retries) {
+    var req = new XMLHttpRequest(); // @todo setRequestHeader for Auth
+
+    var data = JSON.stringify(logs);
+    req.open('POST', config.url);
+
+    if (config.authHeader) {
+      req.setRequestHeader('Authorization', config.authHeader);
+    }
+
+    req.setRequestHeader('Content-type', 'application/json;charset=UTF-8');
+
+    req.onreadystatechange = function () {
+      if (req.readyState === 4 && req.status !== 200) {
+        if (retries > 0) {
+          sendLogs(logs, config, retries--);
+        }
+      }
+    };
+
+    req.send(data);
+  }
+
   var config = {};
   var logs = [];
   var startLoadTimestamp = Date.now();
diff --git a/build/userale-2.1.1.min.js b/build/userale-2.1.1.min.js
index 5bbe42d..9349895 100644
--- a/build/userale-2.1.1.min.js
+++ b/build/userale-2.1.1.min.js
@@ -16,4 +16,4 @@
  * @preserved
  */
 
-!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports):"function"==typeof define&&define.amd?define(["exports"],n):n((e="undefined"!=typeof globalThis?globalThis:e||self).userale={})}(this,(function(e){"use strict";function n(e){return(n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}var t="2.1.1",o=null;fun [...]
+!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports):"function"==typeof define&&define.amd?define(["exports"],n):n((e="undefined"!=typeof globalThis?globalThis:e||self).userale={})}(this,(function(e){"use strict";function n(e){return(n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}var t="2.1.1",o=null;fun [...]
diff --git a/example/index.html b/example/index.html
index f6bf846..3576ff5 100644
--- a/example/index.html
+++ b/example/index.html
@@ -82,5 +82,11 @@ limitations under the License.
   <input type="radio" name="Use Case" value="other"> Other
 </form>
 <br>
+<div class="container">
+  <button id="NonLink Button"> Don't Click Me!</button>
+</div>
+<br>
+<p>Click on the Link to Test Logging with Page Navigation</p>
+<a href="http://flagon.incubator.apache.org/"><button id="Linked Button">Link to Flagon Page</button></a>
 </body>
 </html>
\ No newline at end of file
diff --git a/example/server.js b/example/server.js
index aef6766..0f983c7 100644
--- a/example/server.js
+++ b/example/server.js
@@ -53,9 +53,11 @@ app.use(function (req, res, next) {
 });
 app.use(bodyParser.urlencoded({extended: true, limit: '100mb'}));
 app.use(bodyParser.json({limit: '100mb'}));
+app.use(bodyParser.text())
 app.use('/build', express.static(path.join(__dirname, '/../build')));
 app.use('/', express.static(__dirname));
 app.set('view engine', 'jade');
+app.use('/', express.static(__dirname))
 
 
 app.get('/', function (req, res) {
@@ -63,7 +65,8 @@ app.get('/', function (req, res) {
 });
 
 app.post('/', function (req, res) {
-  console.log(req.body);
+  const body = typeof req.body === "string" ? JSON.parse(req.body) : req.body
+  console.log(body)
 
   let delimiter = ',\n\t';
 
@@ -75,7 +78,7 @@ app.post('/', function (req, res) {
   }
   
   const logLength = req.body.length - 1;
-  req.body.forEach(function (log, i) {
+  body.forEach(function (log, i) {
     if (i === logLength) {
       delimiter = '';
     }
diff --git a/src/attachHandlers.js b/src/attachHandlers.js
index 5baa201..e440c99 100644
--- a/src/attachHandlers.js
+++ b/src/attachHandlers.js
@@ -15,10 +15,8 @@
  * limitations under the License.
  */
 
-import { logs } from './packageLogs';
 import { packageLog } from './packageLogs.js';
 import { packageIntervalLog} from './packageLogs';
-import { sendOnRefresh } from "./sendLogs";
 
 let events;
 let bufferBools;
@@ -149,7 +147,6 @@ export function attachHandlers(config) {
   Object.keys(refreshEvents).forEach(function(ev) {
     document.addEventListener(ev, function(e) {
       packageLog(e, events[ev]);
-      sendOnRefresh(logs,config);
     }, true);
   });
 
diff --git a/src/sendLogs.js b/src/sendLogs.js
index 9d84706..f3c37a1 100644
--- a/src/sendLogs.js
+++ b/src/sendLogs.js
@@ -52,44 +52,17 @@ export function sendOnInterval(logs, config) {
 }
 
 /**
- * Provides a simplified send function that can be called before events that would
- * refresh page can resolve so that log queue ('logs) can be shipped immediately. This
- * is different than sendOnClose because browser security practices prevent you from
- * listening the process responsible for window navigation actions, in action (e.g., refresh;
- * you can only detect, after the fact, the process responsible for the current window state.
- * @param  {Array} logs   Array of logs to read from.
- * @param  {Object} config Configuration object to be read from.
- */
-export function sendOnRefresh(logs, config) {
-  if (!config.on) {
-    return;
-  }
-  if (logs.length > 0) {
-    sendLogs(logs, config, 1);
-  }
-}
-
-/**
  * Attempts to flush the remaining logs when the window is closed.
  * @param  {Array} logs   Array of logs to be flushed.
  * @param  {Object} config Configuration object to be read from.
  */
 export function sendOnClose(logs, config) {
-  if (!config.on) {
-    return;
-  }
-
-  if (navigator.sendBeacon) {
-    window.addEventListener('unload', function() {
+  window.addEventListener('pagehide', function () {
+    if (logs.length > 0) {
       navigator.sendBeacon(config.url, JSON.stringify(logs));
-    });
-  } else {
-    window.addEventListener('beforeunload', function() {
-      if (logs.length > 0) {
-        sendLogs(logs, config, 1);
-      }
-    })
-  }
+      logs.splice(0); // clear log queue
+    }
+  });
 }
 
 /**
diff --git a/test/sendLogs_spec.js b/test/sendLogs_spec.js
index 9ae846d..56c7ac3 100644
--- a/test/sendLogs_spec.js
+++ b/test/sendLogs_spec.js
@@ -18,6 +18,7 @@ import {expect} from 'chai';
 import {JSDOM} from 'jsdom';
 import sinon from 'sinon';
 import {sendOnInterval, sendOnClose} from '../src/sendLogs';
+import 'global-jsdom/register'
 
 describe('sendLogs', () => {
     it('sends logs on an interval', (done) => {
@@ -90,57 +91,14 @@ describe('sendLogs', () => {
     });
 
     it('sends logs on page exit with navigator', () => {
-        const html = `<html><head></head><body></body></html>`;
-        const dom = new JSDOM(html)
-        const originalNavigator = global.navigator;
-        const originalWindow = global.window;
-        let called = false;
-        global.window = dom.window;
+        const sendBeaconSpy = sinon.spy()
         global.navigator = {
-            sendBeacon: () => {
-                called = true;
-            },
+            sendBeacon: sendBeaconSpy
         };
-
-        const evt = window.document.createEvent('CustomEvent');
-        evt.initEvent('unload', true, true);
+        sendOnClose([], {on: true, url: 'test'})
         sendOnClose([{foo: 'bar'}], {on: true, url: 'test'});
-
-        window.dispatchEvent(evt);
-        window.close();
-
-        expect(called).to.equal(true);
-        global.window = originalWindow;
-        global.navigator = originalNavigator;
-    });
-    it('sends logs on page exit without navigator', () => {
-        const html = `<html><head></head><body></body></html>`;
-        const dom = new JSDOM(html)
-        const window = dom.window
-        const originalNavigator = global.navigator;
-        const originalXMLHttpRequest = global.XMLHttpRequest;
-        const originalWindow = global.window;
-        let requests = 0;
-        const xhr = sinon.useFakeXMLHttpRequest();
-        global.XMLHttpRequest = xhr;
-        global.window = window;
-        global.XMLHttpRequest = xhr;
-        global.navigator = {sendBeacon: false,};
-        xhr.onCreate = () => {
-            requests++;
-        };
-
-        const evt = window.document.createEvent('CustomEvent');
-        evt.initEvent('beforeunload', true, true);
-        sendOnClose([{foo: 'bar'}], {on: true, url: 'test'});
-
-        window.dispatchEvent(evt);
-        window.close();
-
-        expect(requests).to.equal(1);
-        global.window = originalWindow;
-        global.navigator = originalNavigator;
-        global.XMLHttpRequest = originalXMLHttpRequest;
+        global.window.dispatchEvent(new CustomEvent('pagehide'))
+        sinon.assert.calledOnce(sendBeaconSpy)
     });
 
     it('does not send logs on page exit if config is off', () => {