Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AJAX Post Gets Canceled By Redirect

I'm writing a small script to capture link clicks and save the link's URL into a database table in order to track how many times each link on a particular page is clicked. The links are to external sites.

So, I capture the click event in my JavaScript function, use jQuery to post to a PHP page that saves the data in MySQL, and then the JavaScript function redirects the user to the URL of the link they clicked on.

The problem I'm running into is that it seems like the post never completes because the of redirect. I've worked around this by calling the redirect inside the post callback, but that adds a few second delay because it doesn't get called until after the post completes. I'm looking for a way to just post the data and redirect the user immediately, regardless of whether or not the post succeeds or fails.

This is the current code with the workaround. It works fine, but adds the delay:

function trackClicks(event)
{
    var clicked = $(this).attr('href');

    $.post
    (
        $('#track-click-post-url').attr('value'),
        {
            action: 'track_landing_page_clicks',
            clicked_url: clicked,
            nonce: $('#track-click-nonce').attr('value')
        },
        function( response )
        {
            window.location = clicked;
        }
    );

    event.preventDefault(); 
}

And this is what I'd like to do, but when I try it never completes:

function trackClicks(event)
{
    var clicked = $(this).attr('href');

    $.post
    (
        $('#track-click-post-url').attr('value'),
        {
            action: 'track_landing_page_clicks',
            clicked_url: clicked,
            nonce: $('#track-click-nonce').attr('value')
        }
    );

    window.location = clicked;
    event.preventDefault(); 
}
like image 635
Ian Dunn Avatar asked Jun 09 '11 21:06

Ian Dunn


1 Answers

jQuery doesn't provide a callback for what you're looking for. Here are the available ready states:

Value   State   Description
0   UNSENT  open()has not been called yet.
1   OPENED  send()has not been called yet.
2   HEADERS_RECEIVED    send() has been called, and headers and status are available.
3   LOADING Downloading; responseText holds partial data.
4   DONE    The operation is complete.

You're looking for readystate 2, as that's the earliest you're aware of the fact that the server received the message.

This should get you off the ground:

var xhr = new XMLHttpRequest();
xhr.open("POST", clicked);
xhr.onreadystatechange = function() {
    if (xhr.readyState >= 2) window.location = clicked;
};
xhr.send($('#track-click-post-url').attr('value'));

https://developer.mozilla.org/en/XMLHttpRequest for further reading.

like image 125
Robert Avatar answered Oct 10 '22 22:10

Robert