AJAX GET race condition?

2019-04-13 10:41发布

问题:

I am attempting to track events when links are clicked on my site in a method similar to the following.

<a href="/example" class="track">Example</a>

<script type="text/javascript">
    jQuery(function($) {
        // track clicks on all anchor tags that require it
        $('a.track').live('click', function(e) {
            // send an AJAX request to our event tracking URL for the server to track it
            $.get('/events/track', {
                    url: $(this).attr('href'),
                    text: $(this).text()
            });
        });
    });
</script>

The problem that I'm having is that a new page load interrupts the AJAX request, and so sometimes these events aren't being tracked. I know Google Analytics has a _trackPageview function that can be attached to onclick events though, and this doesn't seem to be an issue for that. I'm wondering what's different about their call vs. mine that I'm seeing this race condition, and GA isn't. e.g.:

<a href="/example" onclick="javascript:pageTracker._trackPageview('/click/example');">Example</a>

Note that I'm not worried about the result of the AJAX request...I simply want it to ping the server with the fact that an event happened.

(Also, I expect I'll get at least one answer that says to simply track the new page load from the server side, not the client side. This is not an acceptable answer for this question. I'm looking for something like how Google Analytics' trackPageview function works on the click event of anchor tags regardless of a new page being loaded.)

回答1:

Running Google's trackPageview method through a proxy like Charles shows that calls to trackPageview( ) request a pixel from Google's servers with various parameters set, which is how most analytics packages wind up implementing such pieces of functionality (Omniture does the same).

Basically, to get around ansynchronous requests not completing, they have the client request an image and crunch the parameters passed in those requests on the server side.

For your end, you'd need to implement the same thing: write a utility method that requests an image from your server, passing along the information you're interested in via URL parameters (something like /track.gif?page=foo.html&link=Click%20Me&bar=baz); the server would then log those parameters in the database and send back the gif.

After that, it's merely slicing and dicing the data you've collected to generate reports.



回答2:

Matt,

If you just want to make sure that the tracking pixel request is made and you don't depend upon response then just doing document.write for the tracking pixel image will do the work.

And you can do the document.write in your onclick handler.

AFA race condition between href and onclick handler of anchor element is concerned the order is well defined.

the event handler script is executed first the default action takes place afterwards (in this case the default handler is href) (Source : Href and onclick issue in anchor link)

But yes, if you depend upon the response of the tracking request to the server then you will have to make it synchronous.

Suggested option would be to call some javascript function to wrap the already defined onclick handlers and then in the order make the calls. Make sure that your tracking request is not asynchronous.

Though it is suggested that you should not be dependent upon the response of the tracking pixel request.