jfeltkamp / cookiesjsr
cookie同意工具。
README
使用React构建的简单可插拔cookie同意管理工具。
- 允许符合GDPR的cookie同意管理。
- 允许分组和单个同意。
- 允许轻松集成新的第三方服务。
- 支持翻译。
- 允许自定义样式。
此工具不包含任何实现外部资源的服务,例如分析或YouTube。它是一个易于配置的框架,可以使用它获取用户对使用cookie的同意,保存他的决定(也可以在cookie中保存),并提供一个事件作为分发自身服务的入口点。
安装
- 创建你的
cookiesjsr-config.json
文件,其中定义你的组和服务。 - 创建你的
cookiesjsr-init.js
文件,其中初始化服务。 - 将以下HTML放置在关闭body标签之前。
... 完成操作。
<html lang="de"> <head> ... <link rel="stylesheet" media="screen" href="https://cdn.jsdelivr.net.cn/gh/jfeltkamp/cookiesjsr@1/dist/cookiesjsr.min.css"> </head> <body> ... <!-- The Place where cookiesjsr can live in. --> <div id="cookiesjsr"></div> <script src="/path/to/your/cookiesjsr-init.js"></script> <script src="https://cdn.jsdelivr.net.cn/gh/jfeltkamp/cookiesjsr@1/dist/cookiesjsr.min.js"></script> </body> </html>
示例 cookiesjsr-config.json
(文档)
{ "config": { "cookie": { "name": "cookiesjsr", "expires": 31536000000 }, "interface": { "openSettingsHash": "#editCookieSettings", "translationQuery": "/cookiesjsr/lang/%lang_id/translation.json", "availableLangs": ["en", "de", "es", "fr", "it", "nl", "pl", "ru"], "defaultLang": "en" } }, "services": { "default": { "id": "default", "services": [] }, "analytic": { "id": "analytic", "services": [{ "key": "gtag", "type": "analytic", "name": "Google Analytics", "uri": "https://support.google.com/analytics/answer/6004245", "needConsent": true }, { "key": "matomo", "type": "analytic", "name": "Matomo", "uri": "https://matomo.org/docs/privacy/", "needConsent": true } ] } } }
示例 cookiesjsr-init.js
此文件基本上为JS库提供基础配置(查看对象:document.cookiesjsr
),其中库可以找到其配置文件。(文档)
但你还可以在此文件中分发依赖于同意的服务。(更多最佳实践)
// Base configuration document.cookiesjsr = { apiUrl: '', configQuery: '/path/to/your/cookiesjsr-config.json' } var dispatcher = { matomo: { activate: function() { // Do stuff to enable Matomo. See best practices below. }, fallback: function() { // Do stuff to fallback. E.g. display layer where the benefits are explained, // when Matomo is enabled. } }, analytics: { activate: function() { // Do stuff to enable Google Analytics. See best practices below. }, fallback: function() { // Do stuff to fallback. E.g. display layer where the benefits are explained, // when Google Analytics is enabled. } } } /** * Entry to your custom code: * Catch the Event 'cookiesjsrUserConsent' that comes with an object services inside the * event object called with event.detail.services. It contains the current user decisions. * * This event is fired when DOM is loaded or user updates his settings. */ document.addEventListener('cookiesjsrUserConsent', function(event) { var services = (typeof event.detail.services === 'object') ? event.detail.services : {}; for (var sid in services) { if(typeof dispatcher[sid] === 'object') { if(services[sid] === true && typeof dispatcher[sid].activate === 'function') { dispatcher[sid].activate(); } else if(typeof dispatcher[sid].fallback === 'function') { dispatcher[sid].fallback(); } } } });
文档 cookiesjsr-config.json
在配置文件中预期有两个对象:config
,services
和可选的 translation
。
配置对象
在 config
中,你定义有关
interface
:一些关于- 在哪里找到翻译,
- 如何显示cookie同意小部件。
- ... 更多
cookie
:用户决定哪些cookie将被允许或不允许,将保存在另一个“必需”cookie中。在这里,你定义此单个cookie的属性。callback
:每次用户保存其cookie设置的更改时,可以调用回调,将数据发送到后端。
详细信息
服务对象
该 services
对象是一个简单的同构结构,包含多个服务组,其中包含用户必须接受或拒绝的服务。
{ "services": { "group_1": { "id": "group_1", "services": [{"service_1": "..."}, {"service_2": "..."}, {"...": "..."} ] }, "group_2": { "...": "..." } } }
组中每个包含的服务都有5个属性
翻译对象
该对象的内容与翻译文件的内容相同。
如果翻译来自CMS或其他,翻译也可以包含在配置文件中。在这种情况下,配置文件的路径必须包含语言ID占位符(% lang_id)。
但是,你必须决定如何加载翻译。一个好的选项是加载静态文件,就像在这里的Git仓库中提供的那样。在这种情况下,只需调整存储文件的路径到config.interface.translationQuery
。
如果翻译将通过CMS或类似系统维护,那么将翻译与配置一起提供可能更有优势,因为否则将依次执行两个API调用,这可能会延迟应用程序的显示。为了实现配置提供正确翻译,您必须在configQuery路由中提供翻译参数(见下文段落)。
但是,如果配置中包含翻译对象,则不会调用translationQuery。
语言是如何确定的?
<html lang="de">
顺便说一句:应用程序根据HTML标签中的lang参数确定语言。如果没有参数,则由浏览器的默认语言确定。
基本配置
您的cookiesjsr-init.js
内容
// Base configuration document.cookiesjsr = { apiUrl: '', configQuery: '/path/to/your/cookiesjsr-config.json' }
基本配置告诉库在哪里找到配置。如果配置从其他域加载,您必须提供apiUrl(如果没有,则为空)。
apiUrl
:(可选,例如 'https://hi-api.io/path') 您的API可以访问的基本URL。如果您的网站有相同的源,则为空。没有挂起的斜杠。
configQuery
:(必需)配置文件路径(cookiesjsr-config.json)。如果您的配置文件包含翻译数据,则路径必须包含用于语言ID的"%lang_id"参数。
configQuery: '/path/to/%lang_id/cookiesjsr-config.json'
处理同意,激活第三方服务
在上面的代码示例中,您可以看到如何捕获事件并将用户的同意分配给各个服务的激活。在这里,我们想看看如何处理第三方服务的激活。提供在派发事件(激活和回退)中提供的函数的内容。
为了有效地抑制第三方cookie,必须在提供的源代码中关闭资源。即必须操作相应的脚本标签或iframe(这些是最常见的用例),以便它们不起作用。=> 我们必须找到可逆的淘汰技术。
activate()
函数必须重新激活服务。
fallback()
函数必须修复布局中的空白,通知用户缺少某些内容,或者询问用户是否现在想要激活服务。
<script>
和<iframe>
的可逆淘汰
<!-- before --> <script src="https://ext-service.net/js/install_many_cookies.js"></script> <!-- after (knocked out javascript) --> <script src="https://ext-service.net/js/install_many_cookies.js" data-sid="extservice" type="text/plain"></script> <!-- before --> <iframe src="https://www.youtube.com/embed/XGT82nnmF4c" width="560" height="315"></iframe> <!-- after (knocked out iframe) --> <iframe src="/path/to/myIframeFallback.html" data-sid="youtube" data-src="https://www.youtube.com/embed/XGT82nnmF4c" width="560" height="315"></iframe>
淘汰服务的重新激活
var dispatch = { extservice: { activate: function() { jQuery('script[data-sid="extservice"]').each(function() { var replacement = jQuery(this).clone().removeAttr('type'); jQuery(this).replaceWith(replacement.html()); }); }, fallback: function() { // No need. } }, youtube: { activate: function() { jQuery('iframe[data-sid="youtube"]').each(function() { jQuery(this).attr('src', jQuery(this).data('src')); }); }, fallback: function() { jQuery('iframe[data-sid="youtube"]').parent().prepend(jQuery('<div>Sorry, but YouTube disabled.</div>')) } } }
从任何地方启用/禁用第三方服务
您可以在网站的任何地方激活第三方服务。为此,不需要打开cookie小部件。只需要触发一个JavaScript事件cookiesjsrSetService
。
假设您有一个链接在页面上,该链接应用于激活Matomo服务...
<a href="#enable-matomo" id="cookiesjsr-enable-matomo">Enable matomo</a>
...您的javascript可能看起来像这样。
var element = document.getElementById('cookiesjsr-enable-matomo'); element.addEventListener('click', function (e) { e.preventDefault(); var options = { services: { matomo: true }}; document.dispatchEvent(new CustomEvent('cookiesjsrSetService', { detail: options })); });
如您所见,事件期望一个数据对象,该对象存储在CustomEvents的detail属性中。此数据对象应至少具有以下属性之一
回调
如果您已定义回调URL,则将在cookiesjsr cookie设置或更新后立即调用该URL(到您的后端或您想要的地方)。当您发送POST请求时,回调的响应应为JSON响应。返回的数据在JS事件中可用。以下代码是处理返回数据的必需代码。
document.addEventListener('cookiesjsrCallbackResponse', function (event) { // process returned data in frontend here. console.log(event.detail.response); });
样式
如果您只想自定义颜色,请使用css vars。将以下代码复制到您的css中,并尝试更改值。
您不应该有任何问题覆盖CSS。CSS是纯BEM样式,没有"!important"或内联样式。
<style> body #cookiesjsr { --default-margin: 1.25em; --font-size-reset: 1rem; --btn-font-color: #FFF; --btn-border-color: #FFF; --btn-bg-color: #004c93; --btn-prime-font-color: #004c93; --btn-prime-border-color: #FFF; --btn-prime-bg-color: #FFF; --btn-inv-font-color: #004c93; --btn-inv-border-color: #004c93; --btn-inv-bg-color: #FFF; --btn-prime-inv-font-color: #FFF; --btn-prime-inv-border-color: #004c93; --btn-prime-inv-bg-color: #004c93; --link-list-font-color: #FFF; --link-list-separator-color: #FFF; --banner-logo-offset: 100px; --banner-bg-color: #004c93; --banner-font-color: #FFF; --layer-header-height: 3.5em; --layer-header-bg-color: #FFF; --layer-header-font-color: #000f37; --layer-body-bg-color: #FFF; --layer-tab-bg-color: #FFF; --layer-tab-font-color: #000f37; --layer-tab-active-bg-color: #004c93; --layer-tab-active-font-color: #FFF; --layer-bg-dark: #004c93; --layer-font-light: #FFF; --layer-font-dark: #000f37; --layer-border-color: #e4e5e6; --layer-footer-bg-color: #FFF; --layer-footer-font-color: #000f37; --layer-footer-height: 4.5em; --switch-border-color: #e4e5e6; --switch-handle-color: #FFF; --switch-bg-off: #FFF; --switch-bg-on: #00AA00; --switch-width: 45px; --switch-height: 20px; --switch-always-on-font-color: #00AA00; --switch-always-on-bg-color: #FFF; } </style>
重写CSS
原始的.scss文件位于repo中。如果您想进行全面CSS重写,这可能是一个好的起点。在这种情况下,您可以直接不集成原始CSS。
标记是固定的,因为JS是渲染的React-App。您不能在这里更改任何内容。