通过重定向取消了 AJAX Post 请求

6
我正在编写一个小脚本来捕获链接点击并将链接的URL保存到数据库表中,以便跟踪特定页面上每个链接被点击的次数。这些链接指向外部网站。
因此,我在我的JavaScript函数中捕获了点击事件,使用jQuery发布到一个PHP页面,该页面将数据保存在MySQL中,然后JavaScript函数将用户重定向到他们所单击的链接的URL。
我遇到的问题是,由于重定向,似乎发布永远不会完成。我通过在发布回调内调用重定向来解决了这个问题,但是由于直到发布完成后才调用它,因此会添加几秒钟的延迟。我正在寻找一种方法,即使发布成功或失败,也可以立即发布数据并重定向用户。
这是当前带有解决方法的代码。它可以正常工作,但会增加延迟:
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(); 
}

我想要做的是这样的,但每次尝试时都无法完成:

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(); 
}
3个回答

7

jQuery没有提供你所寻找的回调函数。以下是可用的准备状态:

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.

你需要寻找readyState 2,因为这是你知道服务器收到消息最早的时间。
以下是可以帮助你入门的内容:
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'));

点击此处了解更多关于XMLHttpRequest的信息。


+1 for readyState,但是即使你离开页面,服务器是否会继续处理请求呢? - gen_Eric
1
@Rocket,它在服务器发送头文件和状态码后触发。在执行SQL操作之前发送头文件和状态码肯定是可能的,但除非他特别这样做,否则可以安全地假设服务器在开始响应时已经完成了请求(否则它怎么知道是否需要抛出500等错误)。 - Robert
谢谢 Robert,这就是我需要的信息 :) - Ian Dunn

0

当您离开页面时,所有未完成的请求都将被终止,并加载新页面。第一种方式是正确的方式。是的,当单击链接时会有延迟,因为POST请求正在运行。

如果用户不在该页面上,则无法在页面的后台运行请求。

也许您可以将链接URL保存在cookie中,并在下一个页面加载时将其放入数据库中。


1
我并不关心交易是否完成。只要请求发送到服务器后,我就想立即将它们重定向,无论之后发生了什么。我不需要得到任何响应。因此,等待那0.5-1.5秒钟似乎是浪费时间。 - Ian Dunn

0
为什么在页面加载时您会使用Javascript进行发布?
只需使用新页面上点击的链接更新数据库。
也许可以使用引荐URL来跟踪点击所在的页面。
或者使用其他解决方案来获取点击所在的页面(例如URL参数)或其他方式。

这些链接指向外部页面。我会更新问题以澄清这一点。 - Ian Dunn

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接