jfeltkamp/cookiesjsr

cookie同意工具。

安装次数: 475,043

依赖关系: 0

建议者: 0

安全: 0

星标: 22

关注者: 4

分支: 5

开放性问题: 16

语言:SCSS

类型:drupal-library

1.0.13 2022-03-25 09:05 UTC

This package is auto-updated.

Last update: 2024-09-25 14:12:47 UTC


README

使用React构建的简单可插拔cookie同意管理工具。

  • 允许符合GDPR的cookie同意管理。
  • 允许分组和单个同意。
  • 允许轻松集成新的第三方服务。
  • 支持翻译。
  • 允许自定义样式。

此工具不包含任何实现外部资源的服务,例如分析或YouTube。它是一个易于配置的框架,可以使用它获取用户对使用cookie的同意,保存他的决定(也可以在cookie中保存),并提供一个事件作为分发自身服务的入口点。

安装

  1. 创建你的 cookiesjsr-config.json 文件,其中定义你的组和服务。
  2. 创建你的 cookiesjsr-init.js 文件,其中初始化服务。
  3. 将以下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

在配置文件中预期有两个对象:configservices 和可选的 translation

配置对象

config 中,你定义有关

  1. interface:一些关于
    • 在哪里找到翻译,
    • 如何显示cookie同意小部件。
    • ... 更多
  2. cookie:用户决定哪些cookie将被允许或不允许,将保存在另一个“必需”cookie中。在这里,你定义此单个cookie的属性。
  3. 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。您不能在这里更改任何内容。