Rails 3 + Ajax:如果我在代码后添加警报,Ajax只会触发吗?

时间:2014-04-10 16:37:32

标签: jquery ruby-on-rails

我正在开发电子商务网站。在结帐时,在您填写结算地址的过程中,您可以决定登录。当您按下"登录"时,它应该保存您已经输入到表单中的任何内容,然后再进入登录页面

然而,我的AJAX似乎并没有开始上演。在开发过程中,当我点击链接时,一切都运行得很好。

我视图中的链接:

<%= link_to "log in", guest_login_path, class: "automatically_save_billing_info" %>.

jQuery的:

    $('.automatically_save_billing_info').on("click", function(e) {
        console.log("here"); // <-- notice console
        var data = new Object();
        $('form.billing_info_form input[type=text], form.billing_info_form select').each(function(){
            var param = $(this).attr("name");
            var value = $(this).val();
            data[param] = value;
        });
        console.log(data);
        jQuery.ajax({
            url: '/checkout/save_billing_address',
            type: 'POST',
            data: data,
            dataType: 'script'
        });
        console.log("!!!"); // <-- notice console
    });

在我的开发日志中,我可以看到它发出请求:

    Started POST "/checkout/save_billing_address" for 127.0.0.1 at 2014-04-10 12:21:27 -0400
    Processing by CheckoutController#save_billing_address as JS
    ...
    Started GET "/checkout/guest_login" for 127.0.0.1 at 2014-04-10 12:21:27 -0400
    Processing by CheckoutController#guest_login as HTML

但是,在我的暂存日志中,它会直接进入登录页面并跳过save_billing_address操作:

    Started GET "/checkout/guest_login" for 127.0.0.1 at 2014-04-10 12:21:27 -0400
    Processing by CheckoutController#guest_login as HTML

问题是,当我检查我在jQuery中打印的console.log以确保我的代码正在运行时,我会看到here!!!

现在奇怪的是,如果我将这些console.log更改为alert("here")alert("!!!");,我的代码可以正常运行......

2 个答案:

答案 0 :(得分:1)

看起来你有竞争条件。当用户点击链接时,您尝试进行ajax调用,然后重定向它们。由于ajax调用是异步事件,因此无法保证在重定向用户之前它将完成。通过插入警报,这会导致浏览器等待,这将允许ajax调用完成。

我的建议是不要为此使用ajax调用,而是将数据存储在本地或会话存储中。这是不需要存储在您的服务器上的数据,因为它将在实际完成订单后传输。

$('.automatically_save_billing_info').on("click", function(e) {
    var data = {};
    $('form.billing_info_form input[type=text], form.billing_info_form select').each(function(){
        var param = $(this).attr("name");
        var value = $(this).val();
        data[param] = value;
    });
    if(window.sessionStorage){
        sessionStorage.setItem('site.checkout.billingAddress',data);
    } //else save to a cookie
});

当页面重新加载时,您可以使用

从sessionStorage中提取它
sessionStorage.getItem('site.checkout.billingAddress')

将其保留在客户端上将为服务器节省不必要的工作并解决您所看到的问题。

您可以使用像localForace这样的库来减轻后退。

答案 1 :(得分:1)

在ajax完成之前,有可能会触发链接的默认操作。它与alert一起使用的原因也让我相信。

试试这个:

$('.automatically_save_billing_info').on("click", function(e) {
    console.log("here"); // <-- notice console
    var data = new Object();
    $('form.billing_info_form input[type=text], form.billing_info_form select').each(function(){
        var param = $(this).attr("name");
        var value = $(this).val();
        data[param] = value;
    });
    console.log(data);
    jQuery.ajax({
        url: '/checkout/save_billing_address',
        type: 'POST',
        data: data,
        dataType: 'script',
        complete: function(){
            window.location = $('.automatically_save_billing_info').attr("href");
        }
    });
    console.log("!!!"); // <-- notice console
    return false; // this will prevent the anchor redirect.
});