Как убедиться, что запрос к серверу завершен перед перенаправлением страницы? - PullRequest
0 голосов
/ 27 июля 2011

РЕДАКТИРОВАТЬ: Просто чтобы уточнить, мой главный вопрос сводится к следующему: если вы отправляете запрос AJAX на некоторый сервер (в данном случае Google), но затем клиент покидает страницу до завершения серверазапрос, возможно (или вероятно), что сервер также прервет запрос, или сервер попытается завершить запрос (несмотря на то, что больше некому будет отвечать)?

Feelможете прочесть все остальное, если хотите.


Я использую Google Analytics на странице, предназначенной для немедленного перенаправления.Поскольку файл javascript Google ga.js загружается асинхронно, я должен убедиться, что все теги сценариев, которые динамически добавляются с помощью javascript, отслеживаются и что перенаправление страницы происходит только после завершения этих сценариев.Я уже обработал эту часть.

Файл ga.js, кажется, выполняет запрос к файлу __utm.gif с параметрами, что и является фактическим отслеживанием.Этот запрос, очевидно, сделан не из файла, которым я могу управлять, поэтому вот мои вопросы:

Прежде всего, является ли запрос асинхронным (я подозреваю, что это так)?Во-вторых, как я могу убедиться, что у этого запроса есть время для выполнения, прежде чем я перенаправлю страницу (я бы предпочел не просто перенаправлять после того, как прошло «достаточно времени»)?Будет ли запрос завершен, если исходная страница будет перенаправлена ​​до его завершения (в конце концов, мне не нужны никакие данные от Google)?

РЕДАКТИРОВАТЬ: Вот мой код:

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
     <title>Redirecting...</title>

     <script type="text/javascript">
        /* <![CDATA[ */

        // Holds a value for each script. When all the values contained in this array are true, all loading has completed.
        var scripts = [];

        function scriptDetectLoaded(script)
        {
            scripts.push({ loaded: false, element: script });
            var index = scripts.length - 1;

            // Will set this script as loaded
            var callback = function ()
            {
                //console.log("Script with index " + index + " finished loading");
                scripts[index].loaded = true;
            };

            // For most browsers
            script.onload = callback;
            // For IE
            script.onreadystatechange = function ()
            {
                if (this.readyState == "complete")
                    callback();
            };

            return index;
        }

        /* ]]> */
     </script>

     <!-- Google analytics code -->
     <script type="text/javascript">
        /* <![CDATA[ */
        var _gaq = _gaq || [];
        _gaq.push(['_setAccount', 'UA-MY_ID-1']);
        _gaq.push(['_trackPageview']);

        (function ()
        {
            //debugger;
            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';
            scriptDetectLoaded(ga); var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
        })();
        /* ]]> */
    </script>
</head>
<body>
    <noscript>
        <p>Please enable JavaScript and refresh this page. Our site won't work correctly without it.</p>
        <p><a href="http://www.google.com/search?q=how+to+enable+javascript" target="_blank">How do I enable JavaScript?</a></p>
    </noscript>

<!-- Google Code for New Account Conversion Page -->
<script type="text/javascript">
    /* <![CDATA[ */
    //debugger;
    var google_conversion_id = SOME_ID;
    var google_conversion_language = "en";
    var google_conversion_format = "2";
    var google_conversion_color = "ffffff";
    var google_conversion_label = "SOME_LABEL";
    var google_conversion_value = 0;

    (function () {
        var gad = document.createElement('script'); gad.type = 'text/javascript'; gad.async = true;
        gad.src = document.location.protocol + "//www.googleadservices.com/pagead/conversion.js";
        scriptDetectLoaded(gad); var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(gad, s);
    })();
    /* ]]> */
</script>
<noscript>
    <div style="display:inline;">
        <img height="1" width="1" style="border-style:none;" alt="" src="http://www.googleadservices.com/pagead/conversion/1056222251/?label=keCSCNO9qAIQq9jS9wM&amp;guid=ON&amp;script=0"/>
    </div>
</noscript>

    <!-- Redirect Page -->
    <script type="text/javascript">
        /* <![CDATA[ */
        //debugger;
        var url = '/console';
        var interval = 100 /*milliseconds*/;
        var timeout = 5000 /*milliseconds*/;
        var count = 0;

        // Set a repeating function that checks to ensure all the scripts have loaded.
        // Once all the scripts have loaded, redirect the page.
        var id = setInterval(function ()
        {
            count += interval;

            // Check for timeout
            if (count > timeout)
            {
                //console.log("Timed out.");
                redirect();
            }

            // Check to make sure all scripts have loaded
            for (var i = 0, len = scripts.length; i < len; i++)
            {
                if (!scripts[i].loaded)
                    return;
            }

            // If we make it here, redirect
            redirect();
        }, interval);

        function redirect()
        {
            location.replace(url);

            // Run this in case the page doesn't redirect properly.
            clearInterval(id);

            var a = document.createElement("a");
            a.href = url;
            a.innerHTML = "Please click here to proceed";

            var p = document.getElementById("message");
            p.innerHTML = "";
            p.appendChild(a);
        }
        /* ]]> */
    </script>

    <p id="message">Please wait as we redirect the page.</p>
</body>
</html>

Ответы [ 3 ]

1 голос
/ 27 июля 2011

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

edit: если вы хотите загрузить скрипт так, чтобы точно знать, когда он будет завершентак что вы можете перенаправить на другую страницу, я бы использовал функцию $ .getScript jquery.он позволяет выполнить обратный вызов после загрузки файла, и вы можете мгновенно перенаправить api.jquery.com / jQuery.getScript

0 голосов
/ 14 августа 2012

Для текущего состояния ga.js вы можете проверить завершение отслеживания, используя этот код:

(function (global) {

    var listeners = []
        , ImageReworked
        , ImageNative = Image
    ;

    function stringMatch(haystack, needle) {
        if (typeof needle.valueOf() === 'string' && haystack.indexOf(needle) !== -1) {
            return true;
        } else if (needle instanceof RegExp && haystack.match(needle)) {
            return true;
        }
    }

    global.addImageListener = function (url, handler) {
        if (!listeners.length) {
            Image = ImageReworked;
        }
        listeners.push([url, handler]);
    };

    global.removeImageListener = function (url, handler) {
        var newListeners = [];
        listeners.forEach(function (el) {
            if (url.constructor !== el[0].constructor //this will not work for object in different windows
                || el[0].toString() !== url.toString()
                || (handler && handler !== el[1])) {
                newListeners.push(el);
            }
        });
        listeners = newListeners;
        if (!listeners.length) {
            Image = ImageNative;
        }
    };

    ImageReworked = function(w, h) {
        var i = new ImageNative(w, h)
        ;

        function handler() {
            listeners.forEach(function (el) {
                var url = el[0]
                    , handler = el[1]
                ;

                if (stringMatch(i.src, url)) {
                    handler(i.src);
                }
            });
        }

        if (i.addEventListener) {
            i.addEventListener('load', handler, false);
        } else if (i.attachEvent) {
            i.attachEvent('onload', handler);
        }

        return i;
    };
})(window);

Пример использования:

addImageListener(/__utm/, function (src) {
    var parameters = {};

    window.removeImageListener(new RegExp('__utm'));//see, regexp can be created by new RegExp!

    (foundParameters = src.match(/(\?|&)(.*?\=[^?&]*)/g)) && foundParameters.forEach(function (parameter) {
        var pair = parameter.replace(/^(\?|&)/, '').split('=');
        parameters[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1]);
    });
    console.log(parameters);
});

_gaq.push(['_setAccount', gaid], ['_trackPageview']);

Но вы всегда должны помнить, что если GA изменит свою логику отслеживания, этот код будет нарушен.

Вы также должны добавить тайм-аут (что, если событие загрузки никогда не произойдет).

И не используйте i.onload, потому что GA-скрипт переопределяет этот атрибут.

0 голосов
/ 27 июля 2011

Для отслеживания, которое зависит от __utm.gif, запрос не должен завершаться, чтобы показатели работали.Как только браузер отправляет запрос (со всеми параметрами), GA имеет то, что ему нужно.Так что вам просто нужно убедиться, что запрос изображения запускается.

Если это промежуточная страница без реального контента, вы можете сделать что-то вроде проверки длины коллекции изображений документа;когда длина> 0, то вы знаете, что GA создал IMG и установил его src (тем самым инициируя запрос).Не уверен насчет деталей этой коллекции, но я знаю такие вещи, которые раньше существовали;может быть, это все еще делает.В этом случае достаточно простого setInterval для выполнения теста и запуска перенаправления.

Редактировать: поскольку материал GA добавляет сценарии в документ, вы можете проверить структуру DOM, чтобы увидеть, соответствуют ли сценарии соответствующимзначение src существует.Это может приблизить вас к цепочке перенаправления с правильного типа события.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...