1

跟进前几天的问题,我遇到了另一件事,现在我已经花了太多时间来敲打我的头。

大多数情况下,我无法提交 SUCCESS 表单。我也试过这个:

jQuery表单提交

这是半功能小提琴中的代码:

http://jsfiddle.net/ZcgqV/

基本上发生的事情是这样的:

  1. 我通过 onSubmit 将方法绑定到表单的提交(而不是单击)
  2. 提交时,它通过 jQuery .ajax() 调用调用远程服务器
  3. 如果响应为“PENDING”,则每 1 秒重试 9 次
  4. 失败时,不要提交表单
  5. 成功后,提交表单

无论我尝试什么,我都无法让表单在我想要的时候提交而不进入循环,或者在它尝试远程服务器时不立即提交。

〜沮丧的尝试100件失败的事情是你的......

如果您不喜欢小提琴,这是直接的代码:

var retries = 0;
var success = false;
var token = "toki wartooth is not a bumblebee";

$(document).ready(function() {
    // Attach the action to the form
    $('#tehForm').attr('onSubmit', 'onsubmit_action(event)');
});

function async(fn) {
    setTimeout(fn, 1000);
}

function pollServer() {
    $.ajax({
        type: "POST",
        cache: "false",
        url: "/remoteCall",
        dataType: "json",
        data: {
            ref_token: token
        }
    }).done(function(data, code, jqXHR) {

        switch (data.status) {
        case "SUCCESS":
            alert("Success");
            success = true;

            // --> HERE IS WHERE I WANT THE FORM TO SUBMIT <--

            break;

        case "PENDING":
            if (retries < 9) {
                retries += 1;
                async(function() {
                    pollServer();
                });
            } else {
                alert("Failed after 9 tries");
            }
            break;

        case "ERROR":
            alert("Error");
            break;

        default:
            alert("Some kind of horrible error occurred");
            break;
        }

    }).fail(function(jqXHR, textStatus) {
        var statusCode = jqXHR.status;
        alert("Request failed: " + statusCode + " " + textStatus);
    });

}

function onsubmit_action(event) {
        pollServer();
        if (success === false) {
            // RETURN FALSE DIDN'T WORK, SO I FOUND THIS
            event.preventDefault();
        }
}​

编辑:

同样,这里真正的问题是我停止提交表单。成功后,我希望提交表单。目前,如果我在 SUCCESS 中使用 .submit(),则会再次调用 AJAX,重新开始该过程。我想要的是表单的操作仅在成功时触发。

4

3 回答 3

3

尝试尽可能多地使用原始代码;这是一个解决方案:

回发表单 http://jsfiddle.net/tpm7v/4/

通过 Ajax http://jsfiddle.net/tpm7v/5/发布表单

    var retries = 0,
    token = "toki wartooth is not a bumblebee",
    sendRequest,
    handelResponse,
    postFormToServer,
    $theForm = $('#tehForm');

$(document).ready(function() {
    // Attach the action to the form
    $theForm.bind('submit', onsubmit_action);
});

sendRequest = function() {
    $.ajax({
        type: "POST",
        cache: "false",
        url: "/remoteCall",
        dataType: "json",
        data: {
            ref_token: token
        },
        success: handelResponse
    });
};

postFormToServer = function() {
    $.ajax({
        type: "POST",
        cache: "false",
        url: "/remoteCallToTakFormData",
        dataType: "json",
        data: $form.serialize(),
        success: function() {
            alert('success!');
        }
    });
};

handelResponse = function(data, code, jqXHR) {
    switch (data.status) {
        case "SUCCESS":
            postFormToServer();
            break;

        case "PENDING":
            if (retries < 9) {
                retries += 1;
                setTimeout(sendRequest , 1000);
            } else {
                alert("Failed after 9 tries");
            }
            break;

        case "ERROR":
            alert("Error");
            break;

        default:
            alert("Some kind of horrible error occurred");
            break;
        }
};

function onsubmit_action(evt) {
    evt.preventDefault();
    sendRequest();
}
​
​

请记住,我将关闭您提供的代码。您应该能够将其移植到您的实际实现中。您可能还想尝试使用https://github.com/webadvanced/takeCommand之类的方法来帮助清理所有 Ajax 调用。

于 2012-08-16T23:44:51.137 回答
0

请参阅我上面的评论以获取更多信息,但我认为您在这里看到的问题是:

每次 pollServer() 触发时,它不仅会进行另一个 ajax 调用,而且会根据重试循环每秒进行 9 次可能的 ajax 调用。由于您随后使用 async() 方法设置了另一个 pollServer() 调用,因此您基本上使您的 ajax 调用失控。您想从重试循环中获取 ajax 调用,那么您至少应该每秒只收到 1 个请求,而不是 1、2、3 等。我可能读错了代码,但这是我最好的猜猜你看到了什么。

更新:我不确定我的解释是否清楚,所以我想我会添加一些额外的信息。基本上,每次调用 pollServer() 并获得 PENDING 响应时,它都会调用 async,它会注册一个 setTimeout()。setTimeout() 每秒运行一次,执行 pollServer(),然后调用 asynch,它注册另一个 setTimeout(),它也每秒运行一次。现在您有两个函数,然后每个函数调用 setTimeout(),假设它们仍然从服务器获得 PENDING 作为响应。因此,在 2 轮失败的调用之后,您有 4 个 setTimeout() 调用,每个调用每秒触发一个 ajax 调用(和一个新的 setTimeout)。

于 2012-08-16T23:29:20.817 回答
0

首先应该是:$('#tehForm').submit(onsubmit_action);$('#tehForm').on("submit",onsubmit_action);类似的东西。永远不要使用字符串形式来传递函数。它使用邪恶的 eval 语句。

接下来,在 POST 之后,数据已经提交。这就是发帖的全部原因。为什么你需要在 done 部分进行各种错误处理。Fail 应该处理错误处理。

如果你问如何在超时后重试,试试这个: Is it possible to check timeout on jQuery.post()?

我相信超时会失败。

所以试试这个:

var retries = 0,
    max_tries = 9,
    success = false,
    token = "toki wartooth is not a bumblebee";

$(document).ready(function() {
    // Attach the action to the form
    $('#tehForm').on("submit",submit_the_form);
});

function submit_the_form(e){
   var dfd = $.ajax({
       url : "sendTokenPolling", 
       data : {"token":token},
       timeout : 5000 //you may want 1000, but I really think that is too short
    });
   dfd.done(function(){
      //success, form posted
   });
   dfd.fail(function(){
      //did not work/timedout
      if (retries < max_tries){
         retries += 1;
         submit_the_form(e);
      }
   });
}
于 2012-08-16T23:39:30.983 回答