简体   繁体   中英

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(); 
}

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.

When you leave a page, all pending requests are killed, and the new page loads. The 1st way is the correct way. Yes, there will be a delay when a link is clicked, that's because the POST request is running.

You can't run a request in the background of a page, if the user is not on that page.

Maybe you can save the link URL in a cookie, and put it into the DB when the next page loads.

Why do you post using Javascript when you are going to load a page any way?

Just update the db with the link clicked on the new page.

Perhaps using the referrer URL to track on what page the click was.

Or some other solution to get on what page the click was (eg url param) or some other way.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM