Analytics

Suivi sans cookie pour les Iframes intersites

Mis à jour le 25 mai 2021: Ajout d’informations sur son utilisation avec GA4. Comme Google Analytics 4 ne dispose pas d’un mécanisme pour désactiver le stockage des cookies, seule la deuxième solution (envoyer dataLayer événements de l’iframe au parent) décrits dans cet article fonctionneront pour GA4.

Me voilà de retour avec <iframe> et suivi inter-domaines. J’ai déjà publié quelques articles sur le sujet, ma solution mise à jour étant la plus récente. Ces articles abordent le problème général de transmettre l’ID client du parent au <iframe>.

Ce faisant, le <iframe> peut prendre l’ID client de l’URL du cadre et créer le _ga biscuit dans le <iframe>autorisant les accès du parent et les <iframe> d’utiliser le même identifiant client. Génial.

Cependant, il y a un hic qui devient de plus en plus troublant avec l’augmentation des mécanismes de protection contre le pistage des navigateurs : si le <iframe> charge le contenu intersitele navigateur doit autoriser l’accès aux cookies dans un contexte tiers. En d’autres termes, si le navigateur bloque cookies tiersles <iframe> ne pourra pas écrire le cookie, et le suivi de Google Analytics échouera.

Message de publication Iframe

Cet article propose deux solutions à ce problème.

Les première est qu’il envoie l’identifiant client Google Analytics du parent au <iframe> en utilisant window.postMessageet le cadre enfant peut interroger ces informations sur chaque page, ce qui signifie que les cookies ne sont pas nécessaires pour stocker l’ID client.

Les seconde solution est que le cadre enfant envoie en fait chaque dataLayer message au parent, afin que le cadre enfant n’ait pas à suivre quoi que ce soit par lui-même. Le parent gère le suivi du cadre enfant à la place.

En utilisant window.postMessage est plus robuste que la décoration de lien de mes propositions précédentes, car elle ne force pas le rechargement du cadre et ne nécessite pas non plus que le cadre enfant prenne en charge les cookies. C’est un peu plus compliqué à mettre en place, cependant.

Avertissement! Je ne plaisante pas à propos de cette dernière déclaration. Cette configuration nécessite un peu de code personnalisé et vous travaillez avec une communication bilatérale entre deux fenêtres. Veuillez lire attentivement cet article afin de comprendre ce qui se passe avant de copier-coller du code dans votre ou vos conteneurs Google Tag Manager.

Table des matières

Table des matières

[+show] [–hide]

Quel est le problème exactement?

Heureux que vous ayez demandé !

Lorsqu’une page charge un <iframe> de intersite d’origine, ce cadre est chargé dans un contexte tiers, et tout accès au stockage du navigateur à partir de ce <iframe> exigera que le navigateur autorise les cookies tiers pour le <iframe placer.

Un terme clé ici est intersite. Cela signifie que le top nom de domaine sous contrôle privé du <iframe> est différent de celui de la page parent.

Dans les exemples ci-dessous, le premier nom de domaine sous contrôle privé est en italique.

  • www.simoahava.com
  • www.gtmtools.com
  • www.ebay.co.uk
  • sahava.github.io
  • analytique.google.com

Si l’un des sites ci-dessus a chargé un autre site de la liste dans un <iframe>ce contenu serait chargé d’un site à l’autre et toute opération de cookie dans la page intégrée nécessiterait l’accès aux cookies tiers.

Les exemples suivants sont tous même sitemême s’ils sont d’origine croisée :

  • www.simoahava.com
  • simoahava.com
  • Blog.simoahava.com
  • tracking.endpoint.simoahava.com

Toute communication entre les pages de la liste ci-dessus se produirait dans un même site (ou de première partie), et l’accès aux cookies ne serait pas limité.

Comme je l’ai mentionné dans l’introduction, cela ne fera que condamner le suivi dans le contenu intégré en raison de la façon dont les navigateurs implémentent les protections de suivi.

Sur www.cookiestatus.com

Sur www.cookiestatus.com

Même si Google a récemment fait une véritable non-annonce en disant qu’il supprimerait progressivement les cookies tiers d’ici 2022, Google Chrome rendra en fait les choses plus difficiles pour l’accès aux cookies intersites beaucoup, beaucoup plus tôt.

Chrome v80 (publié le 4 février 2020), applique les restrictions de cookies SameSite, ce qui signifie que si un cookie doit être accessible dans un contexte tiers, il nécessite le SameSite=None et Secure ensemble de drapeaux. Par défaut, ce sont ne pas Positionner.

Toi pouvez définir ces drapeaux avec le cookieFlags paramètre, mais notez que cela ne résout que le “problème” de Google Chrome. Cela ne fait pas fonctionner ces cookies dans les navigateurs qui bloquent les cookies tiers.

Heureusement, il existe un moyen de contourner cela.

Nous pouvons ignorer complètement les cookies.

Solution 1 : Transmettre l’ID client du parent à l’enfant

REMARQUE! Comme il n’existe actuellement aucun mécanisme pour désactiver le stockage des cookies dans les déploiements de Google Analytics 4, cette solution ne fonctionnera que pour Universal Analytics. Pour GA4, vous devez utiliser la solution 2 ci-dessous.

Jetons un coup d’œil à une autre illustration célèbre de votre serviteur :

processus postMessage

Il y a beaucoup de potentiel conditions de course dans le mélange, certaines précautions doivent donc être prises. Voici comment fonctionne la page parent :

  1. La page parent commence à écouter les messages de la <iframe> dès que Google Tag Manager se charge.
  2. Une fois que la page parent reçoit le childReady message, il commence à interroger le tracker Google Analytics jusqu’à ce qu’un délai d’expiration maximum soit atteint.
  3. Dès que le tracker Google Analytics est disponible, la page mère renvoie l’identifiant client au <iframe>.

Et voici comment le <iframe> la page réagit :

  1. Les <iframe> la page commence à envoyer le childReady message dès que Google Tag Manager se charge.
  2. Une fois que la page parent répond avec l’ID client (ou qu’un délai d’attente est atteint), la page enfant arrête d’envoyer le message.
  3. La page enfant écrit l’ID client dans dataLayer.

Nous savons maintenant comment l’ID client sera transmis au <iframe>mais cela ne suffit pas encore.

Chaque balise Google Analytics dans le <iframe> doit être configuré pour fonctionner avec cette configuration !

Plus précisément, ils ont tous besoin de deux des champs défini, de préférence dans une variable Paramètres Google Analytics :

  • storage mis à none pour éviter que le tracker échoue s’il ne peut pas écrire le cookie d’identification client.
  • clientId mis à la valeur de la dataLayer.

Nous y reviendrons sous peu, ne vous inquiétez pas.

Solution 2 : transférer tous les messages de la couche de données de l’enfant au parent

Si vous ne voulez pas faire de suivi dans le <iframe> (je ne vous blâme pas), vous pouvez en fait déléguer le suivi au parent en envoyant tous dataLayer messages au parent pour traitement.

Il s’agit de la seule solution viable pour suivre le trafic iframe intersite avec GA4.

Cela signifie que la page parent gérerait les balises pour les interactions natives de la page parent aussi bien que ceux qui se produisent dans le <iframe>.

transfert de messages dataLayer

Le processus est presque le même qu’avec la première solution. Voici comment fonctionne la page parent :

  1. La page parent commence à écouter les messages de la <iframe> dès que Google Tag Manager se charge.
  2. Une fois que la page parent reçoit le childReady message, il répond par un parentReady message.
  3. Si le cadre enfant envoie un message dans dataLayer-format compatible, la page parent pousse ce message dans son propre dataLayer.

Sur le <iframe>voici ce qui se passe :

  1. Les <iframe> la page commence à envoyer le childReady message dès que Google Tag Manager se charge.
  2. Une fois que la page parent répond avec parentReadyle cadre enfant “détourne” le dataLayer.push() et envoie tous les messages qui lui sont transmis à la page parent.

Les messages du cadre enfant sont nommés pour les garder séparés du “natif” du parent dataLayer messages, et ils incluent des métadonnées sur le <iframe> (principalement l’URL et le titre).

Couche de données parent

La configuration de la page parent

Cet article combine tous les deux solutions en un seul ensemble de balises HTML personnalisées, une pour la page parent et une pour l’enfant <iframe>.

Sur la page parent, c’est-à-dire la page envoyant l’identifiant client au <iframe> et en attendant les messages envoyés par l’enfant, vous devez créer un Balise HTML personnalisée qui tire sur un Affichage des pages déclencheur. Vous pouvez utiliser le Toutes les pages déclencheur si vous le souhaitez, mais vous pouvez tout aussi bien créer un Affichage des pages déclencheur qui ne se déclenche que sur les pages dont vous connaissez le <iframe> exister.

La balise HTML personnalisée

La balise HTML personnalisée elle-même doit contenir le code suivant :

<script>   (function() {     // Universal Analytics tracking ID whose _ga cookie to use.     // If using GA4, you can leave this setting untouched.     var trackingId = 'UA-XXXXX-Y';          // Maximum time in milliseconds to wait for GA tracker to load.     // Again, irrelevant for GA4.     var maxGATime = 2000;          // Set to the origin ("https://www.domain.com") of the iframe you want to communicate with     var childOrigin = 'https://www.iframe-domain.com';          // Don't touch anything that follows     var pollInterval = 200;          var postCallback = function(event) {       if (event.origin !== childOrigin) return;       if (event.data !== 'childReady' && !event.data.event) return;              if (event.data === 'childReady') {         // Send event that parent is ready         event.source.postMessage('parentReady', event.origin);          var pollCallback = function() {           // Stop polling if maxTime reached           maxGATime -= pollInterval;           if (maxGATime <= 0) window.clearInterval(poll);                      // Only proceed if GA loaded and tracker accessible           var ga = window[window['GoogleAnalyticsObject']];           if (ga && ga.getAll) {             // Get tracker that matches the Tracking ID you provided             var tracker = ga.getAll().filter(function               return t.get('trackingId') === trackingId;              }).shift();                          // Send message back to frame with Client ID             if (tracker) {               event.source.postMessage({                 event: 'clientId',                 clientId: tracker.get('clientId')               }, event.origin);             }             // Stop polling if not already done so             window.clearInterval(poll);           }         };                  // Start polling for Google Analytics tracker         var poll = window.setInterval(pollCallback, pollInterval)       }              // Push dataLayer message from iframe to dataLayer of parent       if (event.data.event) {         window.dataLayer.push(event.data);       }     };          // Start listening for messages from child frame     window.addEventListener('message', postCallback);   })(); </script>

Il se passe pas mal de choses ici, alors passons en revue le code ! Si vous ne vous souciez pas de cette analyse approfondie, vous pouvez passer directement à la manière dont vous devrez peut-être configurer le conteneur de page parent pour prendre en charge la configuration du transfert de message.

Configuration

Tout d’abord, il y a les éléments de configuration :

// Tracking ID whose _ga cookie to use var trackingId = 'UA-XXXXX-Y';  // Maximum time in milliseconds to wait for GA tracker to load var maxGATime = 2000;  // Set to the origin ("https://www.domain.com") of the iframe you want to communicate with var childOrigin = 'https://www.iframe-domain.com'; 

Les trackingId doit être défini sur l’identifiant de suivi Google Analytics du traceur dont _ga cookie que vous souhaitez utiliser. En effet, plusieurs cookies GA peuvent stocker chacun l’ID client pour un ID de suivi différent. Si vous n’êtes pas sûr, tapez simplement votre ID de suivi habituel comme valeur du trackingId variable.

Ensemble maxGATime au temps maximum pendant lequel la page attend le chargement de Google Analytics. Vous pouvez certainement régler cela beaucoup plus haut que 2000 (2 secondes) si vous le souhaitez, mais je déconseille les sondages indéfinis.

Les trackingId et maxGATime les paramètres ne sont pertinents que pour Universal Analytics. Si vous effectuez un suivi vers GA4, vous n’avez pas besoin de modifier ces valeurs par défaut.

Met le childOrigin au origine du <iframe> vous souhaitez envoyer les données. Les origine est tout dans l’URL jusqu’au premier chemin sabrer. Ainsi, si l’URL est https://www.simoahava.com/my-home-page/les origine serait https://www.simoahava.com.

Il est important de ne pas avoir la barre oblique finale, car cela fait partie de la chemin composant et non le origine.

L’auditeur

Sur la dernière ligne du bloc de code principal, nous ajoutons le message auditeur:

window.addEventListener('message', postCallback); 

Cela signifie que lorsqu’un <iframe> envoie un postMessage à la page parent, le listener déclenche et exécute le postCallback une fonction.

var postCallback = function(event) {   if (event.origin !== childOrigin) return;   if (event.data !== 'childReady' && !event.data.event) return;    if (event.data === 'childReady') {     // Send event that parent is ready     event.source.postMessage('parentReady', event.origin);      var pollCallback = function() {       // Stop polling if maxTime reached       maxGATime -= pollInterval;       if (maxGATime <= 0) window.clearInterval(poll);        // Only proceed if GA loaded and tracker accessible       var ga = window[window['GoogleAnalyticsObject']];       if (ga && ga.getAll) {         // Get tracker that matches the Tracking ID you provided         var tracker = ga.getAll().filter(function           return t.get('trackingId') === trackingId;          }).shift();          // Send message back to frame with Client ID         if (tracker) {           event.source.postMessage({             event: 'clientId',             clientId: tracker.get('clientId')           }, event.origin);         }         // Stop polling if not already done so         window.clearInterval(poll);       }     };      // Start polling for Google Analytics tracker     var poll = window.setInterval(pollCallback, pollInterval)   }      // Push dataLayer message from iframe to dataLayer of parent   if (event.data.event) {     window.dataLayer.push(event.data);   } }; 

Tout d’abord, si le message récupéré n’était pas attendu (par exemple, venant d’un autre <iframe> ou a le mauvais contenu), le rappel arrête l’exécution.

Si le message a été du <iframe>la première chose à faire est de notifier à la trame enfant que le parent a reçu le message et est prêt à démarrer une communication bilatérale.

Ensuite, un window.setInterval commence à interroger la page parent toutes les 200 millisecondes jusqu’à la valeur par défaut de 2 secondes complètes. A chaque sondage, le script vérifie si le tracker Google Analytics a été créé. Si c’est le cas, le script prend le clientId du tracker, et le renvoie au <iframe> en utilisant event.source.postMessage(). Une fois cette opération effectuée, l’interrogation est arrêtée manuellement pour éviter que l’ID client ne soit envoyé plusieurs fois au <iframe>.

Essentiellement, la page parent doit attendre deux choses :

  1. Pour que la page enfant signale qu’elle est prête à recevoir des messages.
  2. Pour que le tracker Google Analytics soit disponible, afin que l’ID client puisse en être extrait.

Le dernier bloc de code vérifie si le message du cadre enfant contient un objet avec le event propriété, auquel cas il pousse cet objet entier dans la page parent dataLayer.

Configuration du système de transfert de messages

La page parent écoute dataLayer messages transférés depuis le système intégré <iframe>. Vous pouvez créer des balises, des déclencheurs et des variables qui réagissent à ces messages.

Tous les déclencheurs seront de type Déclencheur d’événement personnalisé. C’est parce que tous les événements envoyés depuis le cadre seront ajoutés avec le iframe. préfixe – même ceux sans event valeur (ils seront envoyés en tant que iframe.Message). Ainsi, si vous souhaitez déclencher une balise lorsqu’un lien est cliqué dans le <iframe>le déclencheur pourrait ressembler à ceci :

Cliquez sur le lien Iframe

Cela nécessite un peu de configuration manuelle pour que tout soit opérationnel. Mais cela peut rendre l’ensemble de votre configuration beaucoup plus fluide, car vous n’aurez pas besoin d’intégrer de code supplémentaire dans le <iframe>.

Chaque message envoyé depuis le <iframe> est automatiquement enrichi de certaines informations au niveau de la page :

{   iframe: {     pageData: {       url: 'https://www.iframe-domain.com/iframe-page?iframequery=iframevalue#iframeHash',       title: 'The Iframe Page Title | Iframe Company'     }   } } 

Si vous souhaitez mettre à jour les balises de votre page parent pour utiliser le <iframe> données au niveau de la page, vous devez créer des variables de couche de données pour iframe.pageData.url (l’URL du <iframe> pages) et iframe.pageData.title (le titre de la page).

Une fois que vous avez tout configuré, vous êtes prêt à configurer le <iframe> page!

La configuration de la page intégrée (enfant)

C’est là que les choses se compliquent. Dans ce guide, nous couvrons un cas d’utilisation assez typique où le <iframe> le contenu n’interagit qu’en tant qu’intégration. Il n’y a donc aucun scénario où l’utilisateur visiterait la page chargée dans le <iframe> dans un contexte first-party ou top-frame. Je discuterai également brièvement de ce scénario plus tard, mais pour l’instant supposons que la page dans le <iframe> n’est accessible qu’en tant qu’élément intégré.

Vous aurez besoin de faire Trois choses dans le conteneur Google Tag Manager du <iframe> page.

  1. Créez une balise HTML personnalisée qui communique avec la page parent.
  2. Mettre à jour les paramètres de tous de vos balises Universal Analytics (et App+Web pendant que vous y êtes).
  3. Mettez à jour les déclencheurs de vos balises Universal Analytics afin qu’elles ne se déclenchent pas tant qu’elles n’ont pas reçu l’ID client du parent.

La balise HTML personnalisée

Créez une nouvelle balise HTML personnalisée et configurez-la pour qu’elle se déclenche sur le Toutes les pages déclencheur. Si la <iframe> est une application d’une seule page, vous ne devez toujours déclencher que la balise HTML personnalisée sur le déclencheur Toutes les pages, et non à chaque changement de page SPA, par exemple.

Voici ce que vous devez copier-coller dans le tag :

<script>   (function() {     // If not in iframe, do nothing     try {       if (window.top === window.self) return;     } catch(e) {}          // Set to false to prevent dataLayer messages from being sent to parent     var sendDataLayerMessages = true;          // Set the prefix that will be used in the event name, and under which all     // the dataLayer properties will be embedded     var dataLayerMessagePrefix = 'iframe';          // Set to parent origin ("https://www.domain.com")     var parentOrigin = 'https://www.parent-domain.com';      // Maximum time in milliseconds to poll the parent frame for ready signal     var maxTime = 2000;          // Don't touch anything that follows     var pollInterval = 200;     var parentReady = false;          var postCallback = function(event) {       if (event.origin !== parentOrigin) return;       if (event.data.event !== 'clientId' && event.data !== 'parentReady') return;              if (event.data.event === 'clientId') {         window.dataLayer.push({           event: 'clientId',           clientId: event.data.clientId         });       }              if (event.data === 'parentReady' && !parentReady) {         window.clearInterval(poll);         if (sendDataLayerMessages) startDataLayerMessageCollection();         parentReady = true;       }     };          var pollCallback = function() {       // If maximum time is reached, stop polling       maxTime -= pollInterval;       if (maxTime <= 0) window.clearInterval(poll);       // Send message to parent that iframe is ready to retrieve Client ID       window.top.postMessage('childReady', parentOrigin);     };          var createMessage = function(obj) {       if (!Array.isArray(obj) && typeof obj === 'object') {         var flattenObj = JSON.parse(JSON.stringify(obj)); 		var message = {};         // Add metadata about the page into the message         message[dataLayerMessagePrefix] = {           pageData: {             url: document.location.href,             title: document.title           }         };         for (var prop in flattenObj) {           if (flattenObj.hasOwnProperty(prop) && prop !== 'gtm.uniqueEventId') {             if (prop === 'event') {               message.event = dataLayerMessagePrefix + '.' + flattenObj[prop];             } else {               message[dataLayerMessagePrefix][prop] = flattenObj[prop];             }           }         }         if (!message.event) message.event =...
Source : www.simoahava.com

Articles similaires

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Bouton retour en haut de la page
Index