简体   繁体   English

如何在页面重定向之前确保服务器请求已完成?

[英]How do I ensure server request is complete before page redirect?

EDIT: Just to clarify, my main question boils down to this: if you issue an AJAX request to some server (in this case Google's), but then the client leaves the page before the server completes the request, is it possible (or likely) that the server would abort the request as well, or would the server try to complete the request (in spite of having no one to respond to any more)? 编辑:只是为了澄清,我的主要问题归结为:如果您向某台服务器(在这种情况下为Google的)发出AJAX请求,但随后客户端在服务器完成该请求之前就离开了该页面,这是否可能(或可能) ),服务器也会终止请求,还是服务器会尝试完成请求(尽管没有人再回应)?

Feel free to read the rest for all the specifics, if you want. 如果需要,请随时阅读其余所有内容。


I am using Google Analytics on a page that is meant to immediately redirect. 我在要立即重定向的页面上使用Google Analytics(分析)。 Since the Google javascript file ga.js is loaded asynchronously, I need to make sure that all the script tags that are added dynamically by the javascript are tracked and that the page redirect only happens after those scripts complete. 由于Google javascript文件ga.js是异步加载的,因此我需要确保跟踪由javascript动态添加的所有脚本标签,并且页面重定向仅在这些脚本完成后发生。 I already handled that part. 我已经处理了那部分。

The file ga.js seems to make a request to a __utm.gif file with parameters, which is what performs the actual tracking. ga.js文件似乎是使用参数向__utm.gif文件发出了请求,该文件会执行实际的跟踪。 That request obviously isn't being made from a file I can control, so here are my questions: 该请求显然不是由我可以控制的文件发出的,所以这是我的问题:

First of all, is the request asynchronous (I suspect it is)? 首先,请求是异步的吗(我怀疑是这样)? Secondly, how can I make sure that that request has time to complete before I redirect the page (I'd prefer not to simply redirect after "enough time" has passed)? 其次,如何确保在重定向页面之前该请求有时间完成(我宁愿不要在“足够的时间”过去之后简单地重定向)? Would the request still complete if the originating page redirected before the request was finished (after all, I don't need any data back from Google)? 如果在请求完成之前重定向了原始页面,请求是否仍将完成(毕竟,我不需要从Google返回任何数据)?

EDIT: Here's my code: 编辑:这是我的代码:

<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>

If you redirect before the request completes, it will be cancelled on the client side. 如果您在请求完成之前重定向,它将在客户端被取消。 meaning, the server may have gotten the post and acted on it, but you will not get the results. 意思是,服务器可能已经收到帖子并采取了相应措施,但您不会获得结果。 if these items are added dynamically you cannot use any onload type of functions. 如果这些项是动态添加的,则不能使用任何onload类型的函数。 i would imagine the google files your adding will have some type of callback you can use that will redirect you. 我想您添加的google文件将具有某种类型的回调,您可以使用它来重定向您。

edit: if you want to load the script in a way that you will know exactly when it is done loading so you can redirect to another page i would use jquery's $.getScript function. 编辑:如果您想以某种方式加载脚本,您将确切地知道何时完成加载,以便可以重定向到另一个页面,我将使用jquery的$ .getScript函数。 it allows for a callback once the file has loaded then you can redirect instantly api.jquery.com/jQuery.getScript 文件加载后,它允许进行回调,然后您可以立即重定向api.jquery.com/jQuery.getScript

For the current state of ga.js you can check tracking completing using this code: 对于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);

Usage example: 用法示例:

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']);

But you should always keep in mind that if GA changes their tracking logic, this code will be broken. 但您应始终牢记,如果GA更改了其跟踪逻辑,则该代码将被破坏。

You also should add timeout (what if load-event will never occure). 您还应该添加超时(如果加载事件将永远不会发生)。

And don't use i.onload, because GA-script override this attribute. 并且不要使用i.onload,因为GA脚本会覆盖此属性。

For the tracking that depends on __utm.gif, the request shouldn't need to complete for the metrics to work. 对于依赖__utm.gif的跟踪,该请求不需要完成即可生效。 Once the browser sends the request (with all the params), GA has what it needs. 浏览器发送了请求(包含所有参数)后,GA便满足了需求。 So you just need to make sure that the image request fires. 因此,您只需要确保触发图像请求即可。

If this is an interstitial page with no real content, you may be able to do something like check the length of the document's images collection; 如果这是一个没有实际内容的插页式页面,则您可以执行类似检查文档图像集合长度的操作; when length > 0, then you know GA has created the IMG and set its src (thereby triggering the request). 当length> 0时,您就知道GA已创建IMG并设置了其src(从而触发了请求)。 Not sure about the details of that collection, but I know stuff like that used to exist; 不确定该收藏的详细信息,但我知道类似的东西曾经存在过。 maybe it still does. 也许仍然如此。 In that case, a simple setInterval to perform the test and kick off the redirect should suffice. 在这种情况下,一个简单的setInterval即可执行测试并启动重定向。

Edit: Since the GA stuff adds scripts to the document, you can check the DOM structure to see if scripts with the proper src value exist. 编辑:由于GA的东西将脚本添加到文档,您可以检查DOM结构以查看是否存在具有正确src值的脚本。 That may get you closer to chaining the redirect from the right kind of event. 这样可以使您更接近于链接来自正确事件的重定向。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何确保在发布之前完成对表单DOM的更改? - How can I ensure that changes to a form DOM are complete before POSTing? CheerioCrawler:如何在提取数据之前确保页面已完全加载? - CheerioCrawler: How do I ensure a page is fully loaded before extracting the data? 如何通过Ajax完成用户名和传递请求时重定向页面 - How can i redirect page when username and pass request complete via ajax 我如何重定向到json请求类型的任何其他页面? - how do i redirect to any other page for json request type? 如何在加载页面之前提交ajax请求 - How do i submit an ajax request before the page is loaded QUnit,Sinon.js - 我如何确保Post-Fake Server有正确的请求体? - QUnit, Sinon.js - How do I ensure Post to Fake Server has correct request body? 在离开页面之前获取Ajax请求以完成 - Get Ajax request to complete before leaving the page OAuth 2 流程完成后如何重定向父页面? - How can I redirect the parent page after OAuth 2 flow is complete? 如何在重定向之前显示消息 - How do I show a message before redirect 我有一个在插页式重定向页面上运行的跟踪脚本。 我怎么知道脚本在重定向之前有足够的时间执行? - I have a tracking script that runs on an interstitial redirect page. How do I know the script had enough time to execute before the redirect?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM