tag manager google attribute javascript error-handling google-tag-manager

javascript - attribute - Error al ejecutar ''postMessage'' en ''Window'' GoogleTagManager



google tag manager (2)

Esto sucede todo el tiempo, si algo no puede ser duplicado por el algoritmo de clonación estructurada . Este algoritmo es utilizado por window.postMessage . Si leemos la documentación de window.postMessage para el primer parámetro:

mensaje
Datos a enviar a la otra ventana. Los datos se serializan utilizando el algoritmo de clonación estructurada .

y luego abra la descripción del algoritmo de clonación estructurada (vea el último enlace arriba) luego podemos leer:

El algoritmo de clonación estructurada es un algoritmo definido por la especificación HTML5 para copiar objetos complejos de JavaScript. Se usa internamente al transferir datos hacia y desde Trabajadores a través de postMessage() o al almacenar objetos con IndexedDB . Construye un clon recurriendo a través del objeto de entrada mientras mantiene un mapa de las referencias visitadas previamente para evitar ciclos de desplazamiento infinitos.

Cosas que no funcionan con clones estructurados.

  • Function objetos de Error y Function no pueden ser duplicados por el algoritmo de clonación estructurada; intentar hacerlo lanzará una excepción DATA_CLONE_ERR .
  • Intentar clonar los nodos DOM también lanzará una excepción DATA_CLONE_ERR .
  • Ciertos parámetros de los objetos no se conservan:

    • El campo lastIndex de los objetos RegExp no se conserva.
    • Los descriptores de propiedades, los definidores y los captadores (así como las características similares a metadatos similares) no están duplicados. Por ejemplo, si un objeto se marca de solo lectura con un descriptor de propiedad, se leerá y escribirá en el duplicado, ya que esa es la condición predeterminada.
    • La cadena del prototipo no se camina y se duplica.

Tipos soportados

Lo probé con algunos objetos y puedo mostrarte los siguientes ejemplos cuando esto suceda ...

Ejemplo con función personalizada

var obj = {something: function(){}}; window.postMessage(obj, ''*''); // DataCloneError

Ejemplo con función nativa.

var obj = {something: window.alert}; window.postMessage(obj, ''*''); // DataCloneError

Lo mismo veremos con funciones nativas como Boolean , Date , String , RegExp , Number , Array .

Ejemplo con objeto nativo

var obj = {something: document}; window.postMessage(obj, ''*''); // DataCloneError

Ejemplo con objeto elemento HTML

var obj = {something: document.createElement(''b'')}; window.postMessage(obj, ''*''); // DataCloneError

Podríamos escribir más ejemplos si leemos la descripción del algoritmo de clonación estructurada anterior, pero creo que aquí es suficiente.

Qué podríamos hacer para evitar este error.

En nuestro código solo podríamos usar tipos compatibles (consulte la lista anterior) en nuestros objetos. Pero no en nuestro código tenemos que contactar a los desarrolladores de este código y escribirles cómo tienen que corregir su código. En el caso de Google Tag Manager, puede escribirlo en el Foro oficial de Google Tag Manager con una descripción de cómo deben corregir su código.

Solución para algunos navegadores.

En algunos navegadores no se pueden anular los métodos nativos por razones de seguridad. Por ejemplo, IE no permite anular window.postMessage . Pero otros navegadores como Chrome permiten anular este método de la siguiente manera:

var postMessageTemp = window.postMessage; window.postMessage = function(message, targetOrigin, transfer) { postMessageTemp(JSON.parse(JSON.stringify(message)), targetOrigin, transfer) };

Pero tenga en cuenta que la window es un objeto global del contexto de JavaScript y no se crea a partir del prototype . En otras palabras: no puede anularlo con window.prototype.postMessage = ...

Ejemplo con solución

var obj = {something: window}; var postMessageTemp = window.postMessage; window.postMessage = function(message, targetOrigin, transfer) { function cloneObject(obj) { var clone = {}; for(var i in obj) { if(typeof(obj[i]) == ''object'' && obj[i] != null) { if((''''+obj[i]) == ''[object Window]'') { delete obj[i]; continue; } clone[i] = cloneObject(obj[i]); } else clone[i] = obj[i]; } return clone; } // to avoid weird error causing by window object by JSON.stringify() execution. var clone = cloneObject(message); postMessageTemp(JSON.parse(JSON.stringify(clone)), targetOrigin, transfer) }; window.postMessage(obj, ''*''); console.log(''We do not have any errors.'');

Cómo implementar esta solución

window.postMessage función window.postMessage en la parte de secuencia de comandos en su página HTML antes de la secuencia de comandos de Google Tag Manager. Pero de una mejor manera, podría ayudar a los desarrolladores de Google Tag Manager a comprender y corregir este error y puede esperar a que se corrija el script de Google Tag Manager.

Recientemente, recibí este mensaje de correo no se pudo clonar error. Está sucediendo en la mayoría de los últimos navegadores como Chrome 68, Firefox 61.0, IE11, Edge.

Error al ejecutar ''postMessage'' en ''Window'': la function (a){if(qe.$a.hasOwnProperty(a))return qe.$a[a]} no pudo clonarse.

La traza de pila es:

Error: Error al ejecutar ''postMessage'' en ''Window'': function (a){if(qe.$a.hasOwnProperty(a))return qe.$a[a]} no se pudo clonar.
en _reportEvent (eval at (: 1: 35637),: 94: 35)
en eval (eval at (: 1: 35637),: 55: 5)
en eval (eval at (: 1: 35637),: 433: 11)

Buscando en la fuente de mi página en DevTools muestra gtm.js como la fuente del fragmento de código:

Tengo un código de seguimiento de Google Tag Manager en mi página. ¿Por qué está pasando esto?


Estos errores son causados ​​por los rastreadores de Facebook que ejecutan el código JavaScript.

He tenido ocurrencias de este error en estas IP (todas en los rangos de IP de Facebook) y en los agentes de usuario:

66.220.149.14 - Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:62.0) Gecko/20100101 Firefox/62.0 31.13.115.2 - Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36 173.252.87.1 - Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36 69.171.251.11 - facebookexternalhit/1.1 (+http://www.facebook.com/externalhit_uatext.php)

Para obtener una lista actualizada de las direcciones IP del rastreador de Facebook, vea este comando en https://developers.facebook.com/docs/sharing/webmasters/crawler/ :

whois -h whois.radb.net -- ''-i origin AS32934'' | grep ^route

Deberá actualizar su mecanismo de informe de errores para filtrar los errores de estos rangos de IP.

Puede hacer esto en el lado del cliente en JavaScript determinando la dirección IP del usuario en caso de error (consulte ¿Cómo obtener la dirección IP del cliente utilizando JavaScript? ).

O podrías hacer esto en el lado del servidor. Aquí hay un ejemplo para ASP.NET MVC:

using System.Linq; // Requires the IPAddressRange NuGet library: // https://www.nuget.org/packages/IPAddressRange/ using NetTools; public class FacebookClientDetector { /// <summary> /// The list of CIDR ranges of facebook IPs that its crawlers use. /// To generate, run /// whois -h whois.radb.net -- ''-i origin AS32934'' | grep ^route /// https://developers.facebook.com/docs/sharing/webmasters/crawler/ /// </summary> static readonly string[] facebookIpRanges = new string[] { "204.15.20.0/22", "69.63.176.0/20", "66.220.144.0/20", "66.220.144.0/21", "69.63.184.0/21", "69.63.176.0/21", "74.119.76.0/22", "69.171.255.0/24", "173.252.64.0/18", "69.171.224.0/19", "69.171.224.0/20", "103.4.96.0/22", "69.63.176.0/24", "173.252.64.0/19", "173.252.70.0/24", "31.13.64.0/18", "31.13.24.0/21", "66.220.152.0/21", "66.220.159.0/24", "69.171.239.0/24", "69.171.240.0/20", "31.13.64.0/19", "31.13.64.0/24", "31.13.65.0/24", "31.13.67.0/24", "31.13.68.0/24", "31.13.69.0/24", "31.13.70.0/24", "31.13.71.0/24", "31.13.72.0/24", "31.13.73.0/24", "31.13.74.0/24", "31.13.75.0/24", "31.13.76.0/24", "31.13.77.0/24", "31.13.96.0/19", "31.13.66.0/24", "173.252.96.0/19", "69.63.178.0/24", "31.13.78.0/24", "31.13.79.0/24", "31.13.80.0/24", "31.13.82.0/24", "31.13.83.0/24", "31.13.84.0/24", "31.13.85.0/24", "31.13.86.0/24", "31.13.87.0/24", "31.13.88.0/24", "31.13.89.0/24", "31.13.90.0/24", "31.13.91.0/24", "31.13.92.0/24", "31.13.93.0/24", "31.13.94.0/24", "31.13.95.0/24", "69.171.253.0/24", "69.63.186.0/24", "31.13.81.0/24", "179.60.192.0/22", "179.60.192.0/24", "179.60.193.0/24", "179.60.194.0/24", "179.60.195.0/24", "185.60.216.0/22", "45.64.40.0/22", "185.60.216.0/24", "185.60.217.0/24", "185.60.218.0/24", "185.60.219.0/24", "129.134.0.0/16", "157.240.0.0/16", "157.240.8.0/24", "157.240.0.0/24", "157.240.1.0/24", "157.240.2.0/24", "157.240.3.0/24", "157.240.4.0/24", "157.240.5.0/24", "157.240.6.0/24", "157.240.7.0/24", "157.240.9.0/24", "157.240.10.0/24", "157.240.16.0/24", "157.240.19.0/24", "157.240.11.0/24", "157.240.12.0/24", "157.240.13.0/24", "157.240.14.0/24", "157.240.15.0/24", "157.240.17.0/24", "157.240.18.0/24", "157.240.20.0/24", "157.240.21.0/24", "157.240.22.0/24", "157.240.23.0/24", "129.134.0.0/17", "157.240.0.0/17", "69.171.250.0/24", "204.15.20.0/22", "69.63.176.0/20", "69.63.176.0/21", "69.63.184.0/21", "66.220.144.0/20", "69.63.176.0/20", }; public static bool IsFacebookClient(string ip) { IPAddressRange parsedIp; if (!IPAddressRange.TryParse(ip, out parsedIp)) { return false; } return facebookIpRanges.Any(cidr => IPAddressRange.Parse(cidr).Contains(parsedIp)); } }