From 10d7e6e2723e4c519a4d16d6b0811ae95370204d Mon Sep 17 00:00:00 2001 From: Martin Tournoij Date: Mon, 3 Jun 2024 09:31:45 +0100 Subject: [PATCH] count.js: use img-based fallback if sendBeacon fails Mostly for CSP errors; in some cases it's not easy to configure that. For example NeoCities blocks it by default and allows changing it only on the paid plan (but does allow `img-src *`). It just adds a few bytes, so not too bad. --- public/count.js | 19 ++++++++++++++++++- tpl/help/countjs-versions.md | 3 ++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/public/count.js b/public/count.js index e85f0bc9..88c5dfbd 100644 --- a/public/count.js +++ b/public/count.js @@ -147,7 +147,24 @@ var url = goatcounter.url(vars) if (!url) return warn('not counting because path callback returned null') - navigator.sendBeacon(url) + + if (!navigator.sendBeacon(url)) { + // This mostly fails due to being blocked by CSP; try again with an + // image-based fallback. + var img = document.createElement('img') + img.src = url + img.style.position = 'absolute' // Affect layout less. + img.style.bottom = '0px' + img.style.width = '1px' + img.style.height = '1px' + img.loading = 'eager' + img.setAttribute('alt', '') + img.setAttribute('aria-hidden', 'true') + + var rm = function() { if (img && img.parentNode) img.parentNode.removeChild(img) } + img.addEventListener('load', rm, false) + document.body.appendChild(img) + } } // Get a query parameter. diff --git a/tpl/help/countjs-versions.md b/tpl/help/countjs-versions.md index f5c09cfe..54c17bea 100644 --- a/tpl/help/countjs-versions.md +++ b/tpl/help/countjs-versions.md @@ -9,7 +9,8 @@ but you may need to update it in the future for new features. Latest ------ -- Only use `navigator.sendBeacon`, removing the ``-based fallback. +- Use ``-based fallback if `navigator.sendBeacon` fails, for example due to + Content-Security-Policy errors. v4 (8 Dec 2023) ---------------