Ошибка обратной передачи на странице ASP.NET при использовании Google Analytics

Я использую ASP.NET для создания небольшого веб-приложения. На одной из моих страниц есть элементы управления LinkButton, которые работали нормально, пока я не добавил ссылку на Google Analytics код к нему. Теперь, когда я нажимаю на кнопку ссылки, я получаю сообщение об ошибке:

Ошибка выполнения Microsoft JScript: значение свойства __doPostBack равно null или не определено, а не является функцией или объектом

Другие ссылки и элементы управления на странице работают нормально. Если я уберу ссылку на скрипт Google Analytics со страницы, тоже все будет нормально. Похоже, проблема возникает из-за взаимодействия между скриптом Google Analytics и элементами управления LinkButton, пытающимися выполнить обратную передачу страницы.

ОБНОВЛЕНИЕ. Еще я заметил следующее. Когда ссылка на скрипт Google Analytics отсутствует, HTML-код, который генерирует ASP.NET, выглядит нормально:

HTML-структура без кода Google Analytics

Однако, как только я добавляю код Google Analytics, HTML портится:

HTML-структура с кодом Google Analytics

Проверьте этот тег формы! Теперь я предполагаю, что ошибка обратной передачи возникает из-за того, что элементы управления linkbutton размещаются вне формы ASP.NET. Но почему? ЗАВЕРШИТЬ ОБНОВЛЕНИЕ.

Любые идеи о том, как решить эту проблему? Спасибо.

ДАЛЬНЕЙШЕЕ ОБНОВЛЕНИЕ. После долгих экспериментов я смог решить эту проблему самостоятельно. Я добавил ответ ниже, показывающий мои выводы. Спасибо всем, кто разместил ответы здесь. ЗАВЕРШИТЬ ОБНОВЛЕНИЕ.


person CesarGon    schedule 03.06.2011    source источник
comment
Можем ли мы увидеть соответствующие разделы источника для вашей страницы? Убедитесь, что ваши теги script закрыты, и, возможно, попробуйте переместить их в конец страницы, а не в начало.   -  person mikey    schedule 05.06.2011
comment
@mikey: все теги правильно закрыты; Я проверил вчетверо (как минимум). Я опубликую источник завтра, как только доберусь до своего офиса. Какие разделы исходного кода страницы вы хотели бы видеть? Я также попытаюсь переместить ссылку на скрипт Google Analytics в конец страницы. Спасибо.   -  person CesarGon    schedule 05.06.2011
comment
Убедитесь, что вы также закрываете тег ‹head›. Я никогда не видел такой странности, хотя я думаю, что это что-то маленькое и легко пропустить. Кроме того, я бы, вероятно, начал искать что-то странное в самом коде .js.   -  person mikey    schedule 05.06.2011
comment
Просто чтобы уточнить, вы вставляете код Google Analytics прямо в конец своей страницы (непосредственно перед </body>)?   -  person keyboardP    schedule 05.06.2011
comment
@keyboardP: Нет. Я вставляю его прямо перед закрывающим тегом ‹/head›, как предлагает Google.   -  person CesarGon    schedule 06.06.2011
comment
@CesarGon. Я не был уверен, что вы используете традиционный сценарий (где он находится в теле code.google.com/apis/analytics/docs/tracking/) или асинхронный. Ничего, по крайней мере, это исправлено :)   -  person keyboardP    schedule 06.06.2011
comment
@keyboardP: О, понятно. Что ж, спасибо за помощь. :-)   -  person CesarGon    schedule 06.06.2011


Ответы (5)


После долгих настроек, техподдержки и экспериментов я решил проблему. Мой код выглядел так:

<head runat="server">
    <title><asp:ContentPlaceHolder ID="cphPageTitle" runat="server"></asp:ContentPlaceHolder></title>
    <link href="_private/Normal.css" rel="stylesheet" type="text/css" />
    <script src="_private/GoogleAnalytics.js" type="text/javascript" />
</head>

Это вызвало проблему, которую я описываю в своем ОП. Все исправлено, когда я переключаюсь на следующее:

<head runat="server">
    <title><asp:ContentPlaceHolder ID="cphPageTitle" runat="server"></asp:ContentPlaceHolder></title>
    <link href="_private/Normal.css" rel="stylesheet" type="text/css" />
    <script src="_private/GoogleAnalytics.js" type="text/javascript"></script>
</head>

Обратите внимание, что script теперь закрывается полным закрывающим тегом, а не самозакрывающимся тегом. Я предположил, что script может самозакрываться без побочных эффектов, но, очевидно, все ведет себя по-другому, когда вы закрываете его по-другому. Это проливает свет на то, почему.

person CesarGon    schedule 06.06.2011
comment
вы нашли ответ на свой вопрос... Ура :D - person Nitin S; 08.06.2011
comment
@NitinJS: Да, видел. Спасибо. :-) - person CesarGon; 08.06.2011
comment
@TFD: я использую новый асинхронный код. См. google.com/support/googleanalytics/bin/answer. py?answer=174090, где ясно и жирным шрифтом указано, что код должен быть вставлен непосредственно перед закрывающим тегом ‹/head›. Страница, которую вы цитируете, относится к старой (традиционной) версии кода. - person CesarGon; 09.06.2011
comment
@CeasarGon - смотри мой ответ. Пол Айриш работает в Google в сообществе разработчиков и сказал, что единственная причина, по которой Google предлагает размещать фрагмент кода как можно выше, это отслеживать как можно скорее. Он сказал, что не согласен с идеей отслеживания посещения, которое уходит до загрузки страницы, и, таким образом, ставит его прямо перед закрывающим тегом </body>, чтобы он знал, что каждое отслеживаемое посещение является реальным посещением. - person Code Maverick; 10.06.2011
comment
@Scott: Спасибо за ваш комментарий. Моя ОП не о том, куда поместить сценарий; эта тема как-то возникла как второстепенная, но я не собирался ее обсуждать. Мой OP касается плохо отформатированного HTML, который был получен, по-видимому, в результате взаимодействия кода Google Analytics и чего-то еще. К счастью, это уже было решено несколько дней назад, как вы можете видеть в моем собственном ответе, а также в OP. В любом случае, спасибо. :-) - person CesarGon; 10.06.2011
comment
@CesarGon - Нет, я знаю. Мой комментарий был просто ответом на ваш комментарий, в котором вы сказали, что сайт Google дал понять, что код должен быть вставлен перед закрывающим тегом </head>. Я просто хотел рассказать вам, почему они так сказали. - person Code Maverick; 10.06.2011
comment
Спасибо - это также решило аналогичную проблему с помощью плагина jquery. - person ccook; 02.02.2012

Как уже предлагалось в клавиатуре P, вы должны поместить скрипт аналитики Google в элемент <body>, желательно в конец (то есть прямо перед закрывающим тегом </body>), чтобы он не блокировал загрузку страницы. См. http://developer.yahoo.com/performance/rules.html#js_bottom для обоснования.

Кроме того, вполне возможно, что скрипт Google Analytics добавляет недопустимые элементы (такие как <input> ) внутри элемента <head>, что объясняет, почему текущая настройка так эффектно ломает вашу страницу.

person Gijs    schedule 05.06.2011
comment
Google предлагает размещать скрипт прямо перед закрывающим тегом ‹/head›, а не внутри тела. Я следую совету Google. Я тоже пытался перенести его на тело, но ничего не улучшается. - person CesarGon; 06.06.2011
comment
На самом деле, Google говорит, что и в конце <head>, и в конце тела все в порядке, если вы внимательно прочитали ссылку Феофаниса. Если поставить тег в теле, то я был бы крайне удивлен, если бы поломка была такой же, ведь тег <head> будет таким же, как и без всякого скрипта google analytics. Скрипт вставит элемент скрипта рядом с первым тегом скрипта, поэтому вы также можете попробовать переместить все скрипты в тело. В любом случае нам, вероятно, понадобится сгенерированный исходный код HTML (а не скриншот), чтобы понять, что здесь не так. - person Gijs; 06.06.2011
comment
Кроме того, каково содержимое js-файла _private Google Analytics? Ты document.writing что-нибудь оттуда? Изменить DOM каким-то другим способом? - person Gijs; 06.06.2011
comment
@Gijs: я не могу найти в документации Google ссылки на размещение скрипта GA в теле. Ссылка, предоставленная Theofanis, говорит, что другие скрипты могут быть помещены в тело, но не говорит, что скрипт GA должен быть; по крайней мере, я этого не вижу. Что касается вашего другого вопроса, файл _private/GoogleAnalytics.js содержит точно код, опубликованный Theofanis, то есть код, который в противном случае вы вставили бы между тегами <script> и </script> на своей странице. - person CesarGon; 06.06.2011
comment
@CesarGon: рад, что ты решил проблему! Что касается моей справки, то точная цитата такова: для лучшей производительности во всех браузерах мы рекомендуем размещать другие скрипты на вашем сайте одним из следующих способов: - перед фрагментом кода отслеживания в разделе ‹head› вашего HTML - после обоих фрагмент кода отслеживания и все содержимое страницы (например, в нижней части тела HTML) (извиняюсь за плохое форматирование, я не могу понять, как улучшить поведение Markdown в комментариях...) - person Gijs; 06.06.2011
comment
@Gijs: Спасибо! Я видел этот раздел и понимаю, что он относится к другим скриптам (т. е. вы размещаете другие скрипты на своем сайте...). Он просит вас поместить другие сценарии либо перед сценариями GA, либо в самом конце, например, в нижней части тела. Обсуждается, куда поместить другие скрипты, а не скрипт GA. - person CesarGon; 06.06.2011
comment
... и я должен научиться читать. Извиняюсь! Хотя я со всем уважением не согласен с Google в том, что принято помещать скрипты в тег head... (И там, где я работаю, у нас есть тег script в конце <body> на всех наших веб-ресурсах (несколько миллионов посетителей в день) и у нас нет проблем) - person Gijs; 06.06.2011
comment
:-D Нет проблем! Но спасибо за помощь! - person CesarGon; 06.06.2011

Это неправильный способ добавления кода Google Analytics. Это должно выглядеть примерно так:

<script type="text/javascript">

  var _gaq = _gaq || [];
  _gaq.push(['_setAccount', 'UA-XXXXX-X']);
  _gaq.push(['_trackPageview']);

  (function() {
    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
  })();

</script>

... и он должен быть вставлен прямо перед тегом </head>, согласно Google:

http://www.google.com/support/analytics/bin/answer.py?hl=ru_US&answer=174090&utm_id=ad

person Theofanis Pantelides    schedule 05.06.2011
comment
Что не так с тем, что я сказал? Я знаю, как выглядит скрипт Google Analytics; Благодарю. :-) И я помещаю его именно туда, прямо перед закрывающим тегом ‹/head›. - person CesarGon; 06.06.2011

Я использую метод Матиаса Байненса:

<script>

    var _gaq = [['_setAccount', 'UA-XXXXX-X'], ['_trackPageview']];

    (function(d, t) {

        var g = d.createElement(t),
            s = d.getElementsByTagName(t)[0];

        g.async = g.src = '//www.google-analytics.com/ga.js';
        s.parentNode.insertBefore(g, s);

    }(document, 'script'));

</script>

Кроме того, единственная причина, по которой Google предлагает вам размещать его как можно выше в документе, заключается в том, что вы можете отслеживать посещение, которое может закрыть вашу страницу до того, как она полностью загрузится. Я не знаю, кто действительно захочет отслеживать посетителей, которые не ждут полной загрузки страницы. Для меня это ненастоящий визит, и цифры сбрасываются. Я размещаю его непосредственно перед закрывающим тегом </body>, чтобы знать, что все мои отслеживаемые посетители полностью загрузили страницу.

person Code Maverick    schedule 09.06.2011
comment
Спасибо за отличную ссылку, Скотт. И за интересный момент о том, что не отслеживаются частично загруженные страницы. Однако проблема, которую я описал в OP, была решена пару дней назад. - person CesarGon; 10.06.2011

Только что

<script type="text/javascript">
    if (!<%=Page.IsPostBack.ToString().Tolower()%>)
    {
        var _gaq = _gaq || [];
        _gaq.push(['_setAccount', 'UA-xxxxxxxx-xx']);
        _gaq.push(['_trackPageview']);
        (function() {
            var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
            ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
            var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
        })();
    }
</script>
person Michele    schedule 19.06.2012