【问题标题】:Method POST, Status (canceled) error message方法 POST,状态(已取消)错误消息
【发布时间】:2012-03-29 15:29:07
【问题描述】:

我有以下代码给我一个Method POST, Status (canceled) 错误消息:

$(document).ready(function() {
    var xhr = false;

    get_default();

    $('#txt1').keyup( function() {
        if(xhr && xhr.readyState != 4){
            alert("abort");
            xhr.abort();
        }

        if ($("#txt1").val().length >= 2) {
            get_data( $("#txt1").val() );
        } else {
            get_default();
        }
    });

    function get_data( phrase ) {
        xhr = $.ajax({
            type: 'POST',
            url: 'http://intranet/webservices.asmx/GetData',
            data: '{phrase: "' + phrase + '"}',
            contentType: 'application/json; charset=utf-8',
            dataType: 'json',
            success: function( results ) {
                $("#div1").empty();

                if( results.d[0] ) {
                    $.each( results.d, function( index, result ) {
                        $("#div1").append( result.Col1 + ' ' + result.Col2 + '<br />' );
                    });
                } else {
                    alert( "no data available message goes here" );
                }
            },
            error: function(xhr, status, error) {
                 var err = eval("(" + xhr.responseText + ")");
                 alert(err.Message) ;
            }
        });
    }

    function get_default() {
        $('#div1').empty().append("default content goes here.");
    }

});

只要每个 ajax 请求完成,代码实际上就可以工作,但是如果我快速输入 txt1,即在前一个请求完成之前输入下一个字符,我会收到错误消息 Method POST, Status (canceled)。

有人知道为什么会发生这种情况以及如何纠正错误吗?

【问题讨论】:

  • 这可能有用,看看stackoverflow.com/questions/6678467
  • Oleg 可能在这里给出了最好的答案。他的修复应该可以帮助您进一步了解脚本。但是:在阅读您的代码时,我发现您没有为这个问题创建理想的代码。我会为你创建一个答案。

标签: javascript ajax jquery readystate


【解决方案1】:

我想这个问题很简单。如果你调用xhr.abort();,那么$.ajax 的error 回调将被调用等待请求。所以你应该忽略error回调中的这种情况。所以error处理程序可以修改为

error: function(jqXHR, textStatus, errorThrown) {
    var err;
    if (textStatus !== "abort" && errorThrown !== "abort") {
        try {
            err = $.parseJSON(jqXHR.responseText);
            alert(err.Message);
        } catch(e) {
            alert("ERROR:\n" + jqXHR.responseText);
        }
    }
    // aborted requests should be just ignored and no error message be displayed
}

附:可能我的另一个old answer 上关闭的问题也可能对您感兴趣。

【讨论】:

    【解决方案2】:

    那是因为您正在调用 abort 方法,该方法可能会触发带有适当错误消息的错误处理程序。

    您可以等待上一个 ajax 请求完成后再进行下一次调用。

    【讨论】:

    • 如果需要在该位置启动另一个进程,我应该如何中止尚未完成的进程?
    【解决方案3】:

    为了解决您的问题并节省 Ajax 调用的数量,我编写了以下示例。本示例允许您处理以下两种情况:

    情况1:

    The user types slow enough (lets say about one key every 200+ miliseconds
    

    情况2:

    The user types fast (my average is about 20 to 50 miliseconds per key)
    

    在下面的示例中,无需中止或忽略 Ajax 调用,您不会向 Ajax 调用发送垃圾邮件,而是使用对象来处理您的工作。 (我什至jsFiddled给你)

    var Handler = {
    
        /**
         * Time in ms from the last event
         */
        lastEvent: 0,
    
        /**
         * The last keystroke must be at least this amount of ms ago
         * to allow our ajax call to run
         */
        cooldownPeriod: 200,
    
        /**
         * This is our timer
         */
        timer: null,
    
        /**
         * This should run when the keyup event is triggered
         */
        up: function( event )
        {
            var d = new Date(),
                now = d.getTime();
    
            if( ( now - Handler.lastEvent ) < Handler.cooldownPeriod ) {
               // We do not want to run the Ajax call
                // We (re)set our timer
                Handler.setTimer();
            } else {
                // We do not care about our timer and just do the Ajax call
                Handler.resetTimer();
                Handler.ajaxCall();
            }
    
            Handler.lastEvent = now;
        },
    
        /**
         * Function for setting our timer
         */
        setTimer: function()
        {
            this.resetTimer();
            this.timer = setTimeout( function(){ Handler.ajaxCall() }, this.cooldownPeriod );
        },
    
        /**
         * Function for resetting our timer
         */
        resetTimer: function()
        {
            clearTimeout( this.timer );
        },
    
        /**
         * The ajax call
         */
        ajaxCall: function()
        {
            // do ajax call
        }
    
    };
    
    jQuery( function(){
    
        var field = jQuery( '#field' );
    
        field.on( 'keyup', Handler.up );
    
    });
    

    希望这会有所帮助。

    【讨论】:

      【解决方案4】:

      您正在使用keyup 事件,这似乎是问题所在。

      如果有的话,您需要在输入一个字符后等待才能采取行动。

      更好的解决方案可能是遵循与JQuery AutoComplete COmponent 相同的策略。

      【讨论】:

        【解决方案5】:

        Ajax 是一种异步类型,不建议您在每个 keyup 事件上发送请求,尝试...

        async: false
        

        在 post 方法中...它会暂停后续的帖子,直到当前请求完成其回调

        【讨论】:

        • 不建议使用async: false,因为它会在请求完成并响应之前停止浏览器。
        • 我同意。使用此解决方案,您在键入时破坏了动态添加内容的全部可能性。
        【解决方案6】:

        实际上,您需要一个 setTimeout 方法来防止触发多余的 ajax 调用。

        clearTimeout(timer);
        
        if($("#txt1").val().length >= 2){
            timer = setTimeout(function(){
                get_data($("#txt1").val());
            }, 400);
        }else{
            get_default();
        }
        

        这应该可以解决您的问题。

        【讨论】:

        • 这个答案怎么没用?
        猜你喜欢
        • 2017-10-01
        • 2021-07-21
        • 1970-01-01
        • 2017-07-13
        • 2018-12-12
        • 1970-01-01
        • 2014-09-14
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多