20 Dec 2020 - tsp
Last update 20 Dec 2020
7 mins
Yes, no-one really likes cookie banners. And technically they don’t serve any real purpose. But there is a bunch of people without much knowledge about web technology that seem to be incapable of configuring their browsers and tend to decide on some strange laws and so here we are with the (in)famous EU directive 2009/136/EC also known as the cookie law. Please note that I’m not a lawyer so nothing on this page is legal advice.
As we all know these banners are required in case someone includes some third
domain content that might add an Set-Cookie
http header that might include
some stuff that might be used for user tracking. So here is one of the most
simple methods on how to implement such a banner in case these third party
resources are only loaded - or are legally promising - to only set these headers
after some kind of action has been taken (the cookie constent).
Warning: Personal opinion following up to the next heading …
First off - I personally don’t think this is a good solution and there is a really simple and easy way to solve that problem:
And keep in mind that cookies are not the only means of tracking as long as you have JavaScript enabled.
But as of today politicans seem to lack understanding of the basic principles of the WWW and so we are required to display banners asking one if one wants to allow the page to store information - which is technically not valid since the browser stores this information and returns it voluntarily on behalf of the user to the servers at the next request - and requires the users to rely on the pages author being honest and storing tracking information only after consent instead of technically preventing it which would be way easier.
The following solution works in case all actions that require the consent banner to be displayed are triggered by JavaScript and not simple HTTP tags (note that this might also be the case).
The idea is pretty simply:
div
) will be empty
in markup so it doesn’t disturbe anyone when having scripts disabled.DOMContentLoaded
listener. The event handler is simply
So let’s dive directly into the code. On the HTML page one only requires the element to be filled anywhere inside the body:
<div id="cookieBanner"></div>
Inside the head
section one imports the script:
<script type="text/javascript" src="/cookieconsent.js"></script>
The script file is also pretty simple. First off it contains three simple helper functions for easier cookie handling:
function cookieConsentSetCookie(name, expires, content) {
let currentDate = new Date();
currentDate.setTime(currentDate.getTime() + (expires * 24 * 60 * 60 * 1000));
document.cookie = name + "=" + content + ";expires="+(currentDate.toUTCString())+";path=/";
}
function cookieConsentDeleteCookie(name) {
document.cookie = name + "=;expires=Thu, 01 Jan 1970 00:00:01 GMT;path=/";
}
function cookieConsentGetCookie(name) {
let pstring = name + "=";
let decodedCookie = decodeURIComponent(document.cookie);
let cookieArray = decodedCookie.split(';');
for(var i = 0; i < cookieArray.length; i++) {
let cookie = cookieArray[i];
// Trim whitespace
while (cookie.charAt(0) == ' ') {
cookie = cookie.substring(1);
}
if (cookie.indexOf(pstring) == 0) {
return cookie.substring(name.length, cookie.length);
}
}
return false;
}
These helper functions allow one to set a cookie with name and parameter, delete a cookie by setting it’s expiration date into the past and a method to read a given cookie from the browsers context. Note that these are rather generic although one has to keep in mind that not all cookies are accessible from JavaScript.
Then there is a function that contains some custom code that will be executed after consent has been given - this can be used to load additional features like social media sharing, advertising javascript, start fetching of ads, etc.:
function cookieconsentStartAdProcessing() {
// ToDo
}
The last part is the event handler that gets executed as soon as the DOM is ready:
window.addEventListener('DOMContentLoaded', () => {
if(!cookieConsentGetCookie('cookieConsent')) {
let banner = document.getElementById('cookieBanner');
if(!banner) { return; }
// Fill with content. Replace with your own content
banner.innerHTML = "<h2>Cookie consent</h2> <button id=\"cookieNope\">No Cookies</button> <button id=\"cookieOk\">Ok, accept cookies</button>";
let buttonNope = document.getElementById('cookieNope');
let buttonOk = document.getElementById('cookieOk');
if(buttonNope) {
buttonNope.addEventListener('click', () => {
banner.style = "display: none;";
});
}
if(buttonOk) {
buttonOk.addEventListener('click', () => {
banner.style = "display: none;";
cookieconsentStartAdProcessing();
cookieConsentSetCookie("cookieConsent", 31, "yes");
});
}
banner.style = "display: block;";
} else {
cookieconsentStartAdProcessing();
cookieConsentSetCookie("cookieConsent", 31, "yes");
}
});
As one can see the code is really simple. At first it locates the div
that
will be used as banner container and fills it by writing into the innerHTML
property. This is the easiest way to get content into an HTML element using
JavaScript. Then it located the single button or both buttons inside the form that
will be used to give or decline consent. The event handler attached to decline
simply hides the banner again, the accept button hides the banner too, calls
the startup function, and sets a cookie for the next 31 days. Everytime the
user visits the page again the cookie is set again for another 31 days. One has
of course also to provide a way of revoking consent - this can be done simply by
providing an button that calls the cookieConsentDeleteCookie
function again - on
this page it’s done on the data protection policy
page.
The last element required is some kind of design. As the current page suggests
I’m not a designer so there are not many tips I can give for that. Basically
what I’ve done for this page is a simple stylesheet based approach that positions
the banner at a fixed window location, allows one to scroll inside (for mobile
devices with smaller screens) and of course set the banner to be hidden
by default. Since I’m using float objects inside my cookie banner I’ve also
added a clear
statement after the banner division itself.
#cookieBanner {
position: fixed;
top: 20%;
max-height: 50%;
overflow: scroll;
display: none;
border: 5px solid red;
background-color: yellow;
padding: 1em 1em 1em 1em;
margin-left: 1em;
margin-right: 1em;
}
#cookieBanner:after {
clear: both;
}
This article is tagged:
Dipl.-Ing. Thomas Spielauer, Wien (webcomplains389t48957@tspi.at)
This webpage is also available via TOR at http://rh6v563nt2dnxd5h2vhhqkudmyvjaevgiv77c62xflas52d5omtkxuid.onion/