问题
It's been a while already since almost all sites I visit pop-up a message regarding cookies and such. I never understood why but, ignorantly, I always clicked "OK".
Fearing that could interfere with Google AdSense, YouTube, Vimeo or even Facebook (Comments Plugin) I use, I tried to understand a bit more, even to not give any excuse for not get paid (when applicable). Then I read, in general lines, the part that I care most (since I have no contact forms or user registration) that "unless authorized cookies must not be recorded in users' browsers".
But if my site is static, generated with Hugo for what matters, what good could add a banner to the bottom or all-screen overlay do? Users could consent, but I wouldn't have a way to know if they did consent or not because it's static, only HTML/JS/CSS, no databases, would I? I mean, how could I store this user preference?
EDIT
Because of the, sometimes, unacceptable policy of this community of closing (and sometimes downvoting and fleeing) topics without code — like if conceptual questions are entirely and utterly wrong — and given the interest of some members in this matter, as promised, I've coded a very basic example:
<!DOCTYPE html>
<html>
<head>
<title>GDPR Compliance Implementation</title>
<style stype="text/css">
html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,video{margin:0;padding:0;border:0;font:inherit;font-size:100%;vertical-align:baseline}html,body{color:#242729;font-family:Arial,"Helvetica Neue",Helvetica,sans-serif;font-size:13px;line-height:1.26666667}body{background:#FFF;box-sizing:border-box;color:#242729;display:flex;flex-direction:column;font-family:Arial,"Helvetica Neue",Helvetica,sans-serif;font-size:13px;line-height:1.30769231;min-height:100%;min-width:1075px}a,.s-link{color:#07C;cursor:pointer;text-decoration:none}a.s-link__inherit,.s-link.s-link__inherit{color:inherit}.td-underline{text-decoration:underline!important}div{display:block}p{clear:both;margin-bottom:1em;margin-top:0}input[type="submit"],input[type="button"],button,.button,.btn,[class*="btn-"],.hero-box.double-panel .panel.white .btn{background-color:transparent;border:1px solid transparent;border-radius:2px;box-sizing:border-box;cursor:pointer;display:inline-block;font-family:inherit;font-weight:400;line-height:1;min-height:2.46153846em;outline:none;padding:.61538462em 1em;position:relative;text-align:center;text-decoration:none;touch-action:manipulation;transition:color .1s ease-in,background-color .1s ease-in,border-color .1s ease-in,box-shadow .1s ease-in;vertical-align:middle}svg:not(:root),symbol,image,marker,pattern,foreignObject{overflow:hidden}svg{width:14px;height:14px}.svg-icon{vertical-align:bottom;-moz-transform:rotate(360deg)}.s-btn .svg-icon{transition:opacity 200ms cubic-bezier(.165,.84,.44,1);margin:-.30769231em .15384615em -.15384615em -.53846154em}select,input,button,.button,a.button:link,.btn,[class*="btn-"],.hero-box.double-panel .panel.white .btn{background-color:#0095ff;border-color:#07c;box-shadow:inset 0 1px 0 #66bfff;color:#FFF}.svg-icon:not(.native) *{fill:currentColor}.s-btn{background-color:transparent;border:1px solid transparent;border-color:rgba(0,89,153,0);border-radius:2px;box-shadow:0 0 0 0 rgba(0,149,255,0);color:#07C;cursor:pointer;font-family:inherit;font-size:inherit;font-weight:400;line-height:1.15384615;outline:none;padding:.8rem;position:relative}.s-btn,.s-btn:focus{background-color:rgba(0,119,204,0)}.s-btn,.s-btn:hover,.s-btn:focus,.s-btn.is-selected,.s-btn[disabled]{background-image:none}.s-btn__inverted{box-shadow:0 0 0 0 rgba(0,149,255,0);color:rgba(204,234,255,0.9)}.s-btn__inverted,.s-btn__inverted:focus{background-color:rgba(255,255,255,0)}.bg-black-700{background-color:#3b4045!important}.fc-white{color:#FFF!important}.baw0{border-width:0}.lh-lg{line-height:1.61538462!important}.ps-fixed{position:fixed}.r0{right:0}.b0{bottom:0!important}.l0{left:0}.grid{display:flex}.grid-center{align-items:center!important;justify-content:center!important}.p16{padding:16px!important}.gs8{margin:-4px}.mx-auto{margin-left:auto;margin-right:auto}.m0{margin:0}.mb-0{margin-bottom:0!important}.mt-10p{margin-top:10%}.ml-auto{margin-left:auto}.gsx,.gsx>.grid,.gsx>[class*="grid--cell"]{margin-bottom:0;margin-top:0}.gs8>.grid,.gs8>.grid--cell{margin:4px}.wmx10{max-width:81.025641rem!important}.z-banner{z-index:5000!important}.hidden{display:none!important}
</style>
</head>
<body>
<div class="mx-auto mt-10p">
<p>GDPR Compliance Implementation</p>
<p>
Have you agree with GDPR Compliance?
<span id="hasCompliedWith">NO</span>
</p>
<p id="disagreeWithGDPR">
<a href="javascript:void(0)">Click here</a> to disagree with GDPR
</p>
</div>
<div id="js-gdpr-consent-banner" class="p16 bg-black-700 fc-white ps-fixed b0 l0 r0 z-banner" role="banner" aria-hidden="false">
<div class="wmx10 mx-auto grid grid__center jc-spacebetween gs8 gsx" role="alertdialog" aria-describedby="notice-message">
<div class="grid--cell" aria-label="notice-message">
<p class="mb0 lh-lg">
This site uses cookies to deliver our services and to show you relevant ads and job listings.
By using our site, you acknowledge that you have read and understand our <a class="s-link s-link__inherit td-underline fc-white" target="_blank" href="https://stackoverflow.com/legal/cookie-policy">Cookie Policy</a>, <a class="s-link s-link__inherit td-underline fc-white" target="_blank" href="https://stackoverflow.com/legal/privacy-policy">Privacy Policy</a>, and our <a class="s-link s-link__inherit td-underline fc-white" target="_blank" href="https://stackoverflow.com/legal/terms-of-service/public">Terms of Service</a>.
Your use of Stack Overflow’s Products and Services, including the Stack Overflow Network, is subject to these policies and terms.
</p>
</div>
<div class="grid--cell ml-auto" aria-label="notice-dismiss">
<button class="s-btn s-btn__inverted fc-white bg-black-700 baw0 p16 js-notice-close" role="status" aria-hidden="true">
<svg aria-hidden="true" id="gdpr" class="svg-icon m0 iconClearSm" width="14" height="14" viewBox="0 0 14 14">
<path d="M12 3.41L10.59 2 7 5.59 3.41 2 2 3.41 5.59 7 2 10.59 3.41 12 7 8.41 10.59 12 12 10.59 8.41 7z"></path>
</svg>
</button>
</div>
</div>
</div>
<script type="text/javascript">
/*!
* JavaScript Cookie v2.2.0
* https://github.com/js-cookie/js-cookie
*
* Copyright 2006, 2015 Klaus Hartl & Fagner Brack
* Released under the MIT license
*/
!function(e){var n;if("function"==typeof define&&define.amd&&(define(e),n=!0),"object"==typeof exports&&(module.exports=e(),n=!0),!n){var t=window.Cookies,o=window.Cookies=e();o.noConflict=function(){return window.Cookies=t,o}}}(function(){function g(){for(var e=0,n={};e<arguments.length;e++){var t=arguments[e];for(var o in t)n[o]=t[o]}return n}return function e(l){function C(e,n,t){if("undefined"!=typeof document){if(1<arguments.length){"number"==typeof(t=g({path:"/"},C.defaults,t)).expires&&(t.expires=new Date(1*new Date+864e5*t.expires)),t.expires=t.expires?t.expires.toUTCString():"";try{var o=JSON.stringify(n);/^[\{\[]/.test(o)&&(n=o)}catch(e){}n=l.write?l.write(n,e):encodeURIComponent(String(n)).replace(/%(23|24|26|2B|3A|3C|3E|3D|2F|3F|40|5B|5D|5E|60|7B|7D|7C)/g,decodeURIComponent),e=encodeURIComponent(String(e)).replace(/%(23|24|26|2B|5E|60|7C)/g,decodeURIComponent).replace(/[\(\)]/g,escape);var r="";for(var i in t)t[i]&&(r+="; "+i,!0!==t[i]&&(r+="="+t[i].split(";")[0]));return document.cookie=e+"="+n+r}for(var c={},f=function(e){return e.replace(/(%[0-9A-Z]{2})+/g,decodeURIComponent)},a=document.cookie?document.cookie.split("; "):[],u=0;u<a.length;u++){var s=a[u].split("="),p=s.slice(1).join("=");this.json||'"'!==p.charAt(0)||(p=p.slice(1,-1));try{var d=f(s[0]);if(p=(l.read||l)(p,d)||f(p),this.json)try{p=JSON.parse(p)}catch(e){}if(c[d]=p,e===d)break}catch(e){}}return e?c[e]:c}}return(C.set=C).get=function(e){return C.call(C,e)},C.getJSON=function(e){return C.call({json:!0},e)},C.remove=function(e,n){C(e,"",g(n,{expires:-1}))},C.defaults={},C.withConverter=e,C}(function(){})});
window.onload = function(e) {
checkStatus();
document.getElementById( 'gdpr' ).onclick = function(e) {
Cookies.set( 'gdpr', '1' );
checkStatus();
}
document.querySelector( '#disagreeWithGDPR a' ).onclick = function(e) {
Cookies.remove( 'gdpr' );
checkStatus();
}
function checkStatus() {
if( typeof Cookies.get( 'gdpr' ) !== 'undefined' ) {
document.getElementById( 'hasCompliedWith' ).innerHTML = 'YES';
document.getElementById( 'js-gdpr-consent-banner' ).classList.add("hidden");
document.querySelector( '#disagreeWithGDPR' ).style.display = 'block';
} else {
document.getElementById( 'hasCompliedWith' ).innerHTML = 'NO';
document.getElementById( 'js-gdpr-consent-banner' ).classList.remove("hidden");
document.querySelector( '#disagreeWithGDPR' ).style.display = 'none';
}
}
}
</script>
</body>
</html>
It's kind of... ridiculous, seriously, having to write a cookie just to say you won't write any cookies. o.O
Anyway... It's a very basic implementation, with markup and styles borrowed from Stack Overflow's own message — displayed every time cookies are cleared, even though when closing the message in here an AJAX Request is made to update the User Account, which should not show the message again for the same User, after all, he/she already accepted before.
The routine reads the value of the cookie using js-cookie's code for Cookie Manipulation (here obfuscated by JSCompress) and shows the acceptance message if not finding it or then a very clear way to disagree with GDPR at any time if the User has previously agreed — even though nothing is blocked if the User hasn't agreed yet.
It's possible this code doesn't work in here. I had to start my PHP built-in web-server to access it as http instead of file:///
来源:https://stackoverflow.com/questions/50815510/gdpr-compliance-on-static-sites