Недавно я получаю эту ошибку postMessage не удалось клонировать. Это происходит в большинстве последних браузеров, таких как Chrome 68, Firefox 61.0, IE11, Edge.
Failed to execute 'postMessage' on 'Window':
function (a){if (qe.$a.hasOwnProperty(a))return qe.$a[a]}could not be cloned.
Трассировка стека:
Error: Failed to execute 'postMessage' on 'Window':
function (a){if (qe.$a.hasOwnProperty(a))return qe.$a[a]}could not be cloned.
at _reportEvent (eval at (:1:35637), :94:35)
at eval (eval at (:1:35637), :55:5)
at eval (eval at (:1:35637), :433:11)
Поиск по источнику моей страницы в DevTools показывает gtm.js как источник фрагмента кода:
На моей странице есть код отслеживания Диспетчера тегов Google. Почему это происходит?
Я также недавно начал видеть эту ошибку - в Linux + Chrome, iOS + Safari, Windows + Chrome. Мы только недавно добавили в наше приложение Диспетчер тегов Google. Следующая строка трассировки стека - at _reportEvent.
Первое, что мы говорим, было 2018-08-30T17: 13 UTC. Кажется, есть во всех браузерах / устройствах, и мы также проследили это до GTM.
Следующее может помочь: stackoverflow.com/questions/42376464/…
@DanieSchoeman видел это, но поскольку этой ошибки нет в коде GTM, мы не можем исправить ее таким образом. Я думаю?
исправление: ... поскольку эта ошибка находится в коде GTM ...
Я вообще не вижу этой проблемы с моей собственной установкой GTM, поэтому я думаю, что это может быть связано с конкретными тегами, которые есть у тех, кто получает эту ошибку. Я думаю, что было бы действительно полезно, если бы мы могли видеть некоторые ссылки на ваши производственные сайты или контейнеры GTM для дальнейшей диагностики, откуда именно возникла эта проблема.
На случай, если это поможет выяснить причину: единственный активный код отслеживания в моем GTM - для Facebook Pixel. Существует также код отслеживания Pardot, однако он не активен для имени хоста, в котором возникают ошибки. Я также отредактировал вопрос, добавив трассировку стека, которая показывает, что ошибка является анонимным блоком кода.
Я отредактировал вопрос, включив в него снимок экрана, показывающий gtm.js как источник функции.
@MichaelM включает ли ваш gtm.js соответствующую функцию (см. Снимок экрана в отредактированном вопросе)? Я не получаю эту ошибку в каждом клиенте (я не могу ее воспроизвести). Так что окружающая среда, наверное, актуальна.
Нашел еще один список вещей, которые могут вызвать проблемы, которые могут вызвать проблемы: analyticsmania.com/post/… и analyticsmania.com/post/google-tag-manager-404-error-gtm-js
Вполне может быть, что [(a)), [a] или $ a] пусто по той или иной причине: (a) {if (qe. $ A.hasOwnProperty (a)) return qe. $ A [ а]}
Я вижу это в библиотеках Javascript Microsoft Power BI.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Это происходит постоянно, если что-то не может быть продублировано структурированный алгоритм клонирования. Этот алгоритм используется window.postMessage. Если мы прочитаем документацию от window.postMessage для первого параметра:
message
Data to be sent to the other window. The data is serialized using the structured clone algorithm.
а затем откройте описание из структурированный алгоритм клонирования (см. последнюю ссылку выше), после чего мы можем прочитать:
The structured clone algorithm is an algorithm defined by the HTML5 specification for copying complex JavaScript objects. It is used internally when transferring data to and from Workers via
postMessage()or when storing objects withIndexedDB. It builds up a clone by recursing through the input object while maintaining a map of previously visited references in order to avoid infinitely traversing cycles.Things that don't work with structured clone
ErrorandFunctionobjects cannot be duplicated by the structured clone algorithm; attempting to do so will throw aDATA_CLONE_ERRexception.Attempting to clone
DOMnodes will likewise throw aDATA_CLONE_ERRexception.Certain parameters of objects are not preserved:
- The
lastIndexfield ofRegExpobjects is not preserved.- Property descriptors, setters, and getters (as well as similar metadata-like features) are not duplicated. For example, if an object is marked read-only using a property descriptor, it will be read-write in the duplicate, since that's the default condition.
- The prototype chain does not get walked and duplicated.
Supported types
- All primitive types(Note: However not symbols)
BooleanobjectStringobjectDateRegExp(Note: The lastIndex field is not preserved.)BlobFileFileListArrayBufferArrayBufferView(Note: This basically means all typed arrays like Int32Array etc.)ImageDataArrayObject(Note: This just includes plain objects (e.g. from object literals))MapSet
Я протестировал это с некоторыми объектами и могу показать вам следующие примеры, когда это происходит ...
Пример ошибки с пользовательской функцией
var obj = {something: function(){}};
window.postMessage(obj, '*'); // DataCloneErrorПример ошибки с собственной функцией
var obj = {something: window.alert};
window.postMessage(obj, '*'); // DataCloneErrorТо же самое мы увидим с собственными функциями, такими как Boolean, Date, String, RegExp, Number, Array.
Пример ошибки с собственным объектом
var obj = {something: document};
window.postMessage(obj, '*'); // DataCloneErrorОшибка-Пример с объектом HTML-элемента
var obj = {something: document.createElement('b')};
window.postMessage(obj, '*'); // DataCloneErrorМы могли бы написать больше примеров, если бы прочитали описание из Структурированный алгоритм клонирования выше, но я думаю, что здесь этого достаточно.
В нашем коде мы могли использовать только поддерживаемые типы (см. Список выше) в наших объектах. Но не в нашем коде мы должны связаться с разработчиками из этого кода и написать им, как они должны исправить свой код. В случае с Диспетчером тегов Google вы можете записать его в официальный форум Google Tag Manager с описанием того, как они должны исправить свой код.
Обходной путь для некоторых браузеров
В некоторых браузерах вы не можете переопределить собственные методы по соображениям безопасности. Например IE не позволяет переопределить window.postMessage. Но другие браузеры, такие как Chrome, позволяют переопределить этот метод следующим образом:
var postMessageTemp = window.postMessage;
window.postMessage = function(message, targetOrigin, transfer)
{
postMessageTemp(JSON.parse(JSON.stringify(message)), targetOrigin, transfer)
};
Но обратите внимание, что window является глобальным объектом контекста JavaScript и не создается из prototype. Другими словами: вы не можете отменить его с помощью window.prototype.postMessage = ....
Пример обходного пути
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.info('We do not have any errors.');Как реализовать это обходное решение
Поместите эту замещающую функцию window.postMessage в часть сценария на своей HTML-странице перед сценарием Диспетчера тегов Google. Но лучше вы могли бы помочь разработчикам из Google Tag Manager понять и исправить эту ошибку, и вы можете дождаться исправления скрипта Google Tag Manager.
Похоже, кто-то разместил вопрос на форуме GTM: productforums.google.com/forum/#!topic/tag-manager/…
@Yoshi, но это тот же вопрос, что и от OP, и никто не ответил на этот вопрос. Это было скопировано из нашего вопроса до того, как мы ответили на этот вопрос. Может быть, кто-то захотел заработать на этом награду.
Привет, Бхарата, спасибо за прекрасный ответ. Как вы показали несколько причин, почему это происходит, и это приемлемо, поскольку я пробовал их со своей стороны. Основная проблема, с которой я сталкиваюсь, заключается в том, что ошибка не возникает ни на одном из устройств, на которых я ее тестирую. Как вы предложили, я могу попробовать метод перезаписи, но, опять же, могу только предположить, что он работает. Надеюсь, что это работает.
@cris причина, по которой вы можете не увидеть его на своих устройствах, заключается в том, что он исходит от сканеров Facebook. Смотрите мой дополнительный ответ.
Ты классный друг
@NadeemAhmad, я думаю, вы что-то неправильно поняли. Может быть, вы выполнили один из 4 первых фрагментов со строкой кода window.postMessage(obj, '*'); // DataCloneError? В этом случае это должна быть ошибка. Я не зря написал туда комментарий. Только в последнем фрагменте есть решение. Вы это неправильно поняли?
@Bharata да, я попробовал фрагмент временного решения. Я передал большой кусок объекта, и это вызвало это.
@NadeemAhmad, не могли бы вы опубликовать свой полный код с этим большим фрагментом объекта на каком-нибудь сайте вроде codepen.io, пожалуйста? Мне нужна ссылка на этот код, чтобы исправить мой код.
@NadeemAhmad, если вы не можете воспроизвести свою ошибку, то не хотели бы вы отозвать мой ответ, потому что я написал свой ответ очень старательно и ответственно. И я не могу понять, почему я получил за это голос против. Даже если вы получили одну ошибку, это не повод для отрицательного голоса - я не могу знать все ситуации.
Эти ошибки вызваны поисковыми роботами Facebook, выполняющими код JavaScript.
У меня были случаи этой ошибки с этих IP-адресов (все в диапазонах IP-адресов Facebook) и пользовательских агентов:
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)
Чтобы получить обновленный список IP-адресов сканера Facebook, см. Эту команду от https://developers.facebook.com/docs/sharing/webmasters/crawler/:
whois -h whois.radb.net -- '-i origin AS32934' | grep ^route
Вам нужно будет обновить механизм отчетов об ошибках, чтобы отфильтровать ошибки из этих диапазонов IP-адресов.
Вы можете сделать это на стороне клиента в JavaScript, определив IP-адрес пользователя в случае ошибки (см. Как получить IP-адрес клиента с помощью JavaScript?).
Или вы можете сделать это на стороне сервера. Вот пример для 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));
}
}
Понятия не имею, как Facebook сканирует веб-сайты, но разве не странно видеть, что ошибка возникает в нескольких браузерах / устройствах, если все они исходят от поисковых роботов Facebook?
@RMenke Хороший улов. Разве это не ошибки, исходящие от фреймов, загружаемых Facebook в Instagram и Facebook?
@RMenke это странно, но данные не лгут - см. Мой отредактированный ответ для моих журналов IP-адресов facebook, вызывающих ошибку на смешанных платформах / браузерах
Вы можете получить всегда актуальный список IP-адресов сканера Facebook с whois -h whois.radb.net -- '-i origin AS32934' | grep ^route developers.facebook.com/docs/sharing/webmasters/crawler
@ Джейк, спасибо. Я обновил свой ответ, включив в него эту команду и пример кода использования записей CIDR.
Вы можете стать жертвой путаницы, которую я испытал при использовании сервис-воркеров через Окно рабочего окна. Этот пакет использует два разных экземпляра своих модулей. Есть набор статических модулей. Также есть еще один набор, находящийся под зонтиком основного модуля Workbox. Они внутренне вызывают свои статические аналоги
var payload = {key: "value"},
{ Workbox, messageSW } = await import('workbox-window'), // these represent static modules without a contextual `this`
wb = new Workbox('/service-worker.js'); // calls to this works on a single instance that interfaces with the underlying static equivalents
Это означает, что пока вам нужно сделать
messageSW(wb.getSW(), payload);
Вызов wb.messageSW(wb.getSW(), payload) приводит к ошибке OP, потому что фактическая полезная нагрузка здесь - это циклический сервис-воркер, а не полезная нагрузка нашего литерала объекта. Созданная версия в этом случае будет работать с:
wb.messageSW( payload);
Я только начал видеть эту ошибку в нашем приложении несколько дней назад, хотя мы не внесли изменений в код. Это происходит во всех основных браузерах (Chrome 68, Firefox, Edge 17), но только в Windows.