草庐IT

javascript - jQuery AJAX 问题,间歇性地获取重复请求

coder 2025-01-14 原文

就在那时,我即将结束对 JavaScript 系统的重写,我们正在从 Prototype 转移到 jQuery。我们有大量 AJAX 请求在发生特定元素事件时触发,下面示例中的一个是日历上的新事件,但它也发生在其他地方。

我遇到的问题是当一个事件被触发时,有时会发出两个 AJAX 请求。第一个返回正确的值,但(如您所见)它仍然表示正在处理,它从不返回我的 JavaScript 所需的成功消息。第二个请求返回正确的结果并正确终止。

我遇到的问题是我们的 jQuery 屏幕拦截器设置为在繁重的 AJAX 请求期间防止用户输入,显然是因为 AJAX 请求仍然存在,屏幕永远不会解锁。如果我要刷新此屏幕,一切都会按预期工作。

任何人都可以解释为什么会发生这种行为。

alt text http://archive.ilmv.co.uk/images/jquery-duplicate-ajax-request.png

编辑

"requests that fire when a certain element events occur" - this is the key phrase, I think. Please provide some info on how you set your events. Maybe it fires twice because you have multiple handlers set? – Igor Zinov'yev



好的,问题是当我点击刷新时问题通常会自行解决,所以不确定这可能是处理程序问题,这是我们通常用于更改选择框的事件处理程序。
$("#my_select","#context").change(function(){
            // uz_ajax is a wrapper function, keeps most of the same functionality as $.ajax()
    uz_ajax({
        target:"#my_target",
        data:{
            module:'my_module',
            controller:'my_controller',
            action:'my_action',
            id:$(this).val(),
            ajax:''
        }
    });
});

我遇到的问题是我不知道如何复制问题,所以我不知道事件是否被多次触发或 AJAX 是否请求两次。

编辑 2

If you are reloading the elements that are bound then the change events could be triggered recursively... We really need to see more code (what do you do on success of the ajax call etc) – redsquare



感谢 redsquare,在成功的 AJAX 请求后,我通常会将响应(通常是 <option> 的 HTML)应用到目标。我从不触发触发 AJAX 的元素的更改,但有时我会触发目标元素的更改,以允许级联 AJAX 请求。如果这是问题所在,那么肯定会一直发生这种情况吗?我的包装函数 uz_ajax在下面:
var ajax_count = 0;
var ajax_response = null;

function uz_ajax(options) {

    // set default options
    var defaults = {
        async: true,
        type: "GET",
        data: {},
        url: "/",
        cache: false,
        force_change: true,
        highlight: true,
        action: "normal",
        dataType: "html",
        selected: {
            value: null,
            disabled: false
        }
    };

    // merge the passed options with the defaults
    var options = $.extend(defaults, options);

    // start the jQuery ajax method
    $.ajax({
        async: options.async,
        type: options.type,
        url: options.url,
        data: options.data,
        beforeSend: function() {
            // we only want to block the screen on the first pass
            if(++ajax_count==1) {
                $.blockUI({message:'Loading data, please wait'});
            } 
        },
        success: function(responseText) {           
            if(options.target!==undefined) {
                // if target isn't an array, make it one
                if(!$.isArray(options.target)) {
                    options.target = new Array(options.target);
                }

                var targets = options.target;

                for ( var i in targets ) {
                    console_info("uz_ajax() --> Applying contents to "+targets[i]);

                    switch(options.action) {
                        case "normal":
                            if($(targets[i]).is("input")) {
                                $(targets[i]).val(trim(responseText));
                            } else {
                                $(targets[i]).html(trim(responseText));
                            }
                            break;
                        case "selected":
                            // preserve the current target value (e.g. list of options), but 
                            // set the selected value to the ajax response
                            console_warn("Changing selected value of "+targets[i]+" to '"+responseText+"'");
                            // trim the response so we don't get any smarty induced errors such as '    7'
                            $(targets[i]).val(trim(responseText));
                            break;
                    }

                    // set selected value
                    if(options.selected.value!=null) {
                        $(targets[i]).val(options.selected.value);
                    }

                    // highlight the target
                    // we don't want to highlight the target if it's a hidden input, as this will force a .show(
                    if($(targets[i]).attr('type')!='hidden' && options.highlight===true) {
                        $(targets[i]).effect("highlight",{},2000);
                    }

                    // force the target to change
                    if(options.force_change===true) {
                        $(targets[i]).trigger("change");    
                    }

                    /* rebind certain elements that do not use conventional events */
                    /* We probably need to get all of these rebinds in a single function */
                    createDatePickers(targets[i]);
                }
            } else {
                ajax_response = responseText;
                console_warn("uz_ajax -> no targets specified");
                // Well... we have no element to target, we need to return the value instead
                // of course if we return here we're going
                // we probably also need to check the ajax count as this will be the last executed part before we return
            }
        },
        complete: function () {
            /* if all ajax requests have completed, unblock screen */
            if(--ajax_count===0) {
                $.unblockUI();
                /* could use this callBack to return a value *dun dun duuuuun* */
                if (options.ajaxComplete) {
                    options.ajaxComplete(ajax_response);
                }
            }
        },
        cache: options.cache,
        dataType: options.dataType
    });

}

another way to stop multiple ajax requests is to heck jQuery.active prior to the call. jQuery keeps an internal count of 'live' ajax requests using this property. – redsquare



我会调查一下。

编辑 3

所以这是 $('element').data() 的结果,但我不明白它想说什么,这是否意味着它有两个绑定(bind)。如果是这样,我如何找出这些绑定(bind)是什么以及为什么在触发事件时它们都不会触发。

alt text http://archive.ilmv.co.uk/images/firebug-jquery-data-events.png

编辑 4

这是问题的另一个屏幕截图,这次是在系统的不同位置。绿色箭头是触发三个 ajax 请求的元素,而不是在 Firebug 中如何有六个,并且它们配对并共享时间戳到毫秒?

前三名是未完成的,后三名已返回正确结果。

alt text http://archive.ilmv.co.uk/images/jquery-duplicate-ajax-request-v2.png

编辑 5

下图演示了更改选择框时会发生什么,它会触发 不同的ajax请求。

我已经设法进行了更多调试,我可以告诉您以下内容:
  • 无论初始元素调用多少 ajax 请求
  • 都会出现此问题
  • 无论使用什么插件都会出现问题
  • 这个事件肯定只被触发一次
  • 我的 uz_ajax 包装函数每个目标只被触发一次(参见 firebug 控制台,“第 29 行:uz_ajax()”。
  • 我已添加 console.info在每个 jquery $.ajax()回调以查看触发的内容和时间,注意唯一触发的回调是 beforeSend() .

  • alt text http://archive.ilmv.co.uk/images/jquery-duplicate-ajax-request-v3.png

    编辑 6

    就在那时,@redsquare 通过 Twitter 建议使用 console.trace()找出“第二个事件从哪里触发”,就像我一直坚持的那样,我确定没有两个事件触发,所以我将跟踪放在 $.ajax()方法,这就是发生的事情:

    alt text http://archive.ilmv.co.uk/images/jquery-duplicate-ajax-request-v4.png

    如您所见,即使 $.ajax() 出现重复的 ajax 请求问题方法只触发了一次,时间戳再次相同。我遇到过 jQuery 的错误吗?

    编辑 7

    它也发生在 StackOverflow 上!

    alt text http://archive.ilmv.co.uk/images/jquery-duplicate-ajax-request-v5.png

    最佳答案

    您是否尝试过使用 .click() 代替?我在 javascript 中使用 .change() 时遇到了不规则事件的问题。试试看。

    关于javascript - jQuery AJAX 问题,间歇性地获取重复请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3156111/

    有关javascript - jQuery AJAX 问题,间歇性地获取重复请求的更多相关文章

    1. ruby - 在 64 位 Snow Leopard 上使用 rvm、postgres 9.0、ruby 1.9.2-p136 安装 pg gem 时出现问题 - 2

      我想为Heroku构建一个Rails3应用程序。他们使用Postgres作为他们的数据库,所以我通过MacPorts安装了postgres9.0。现在我需要一个postgresgem并且共识是出于性能原因你想要pggem。但是我对我得到的错误感到非常困惑当我尝试在rvm下通过geminstall安装pg时。我已经非常明确地指定了所有postgres目录的位置可以找到但仍然无法完成安装:$envARCHFLAGS='-archx86_64'geminstallpg--\--with-pg-config=/opt/local/var/db/postgresql90/defaultdb/po

    2. ruby - 通过 rvm 升级 ruby​​gems 的问题 - 2

      尝试通过RVM将RubyGems升级到版本1.8.10并出现此错误:$rvmrubygemslatestRemovingoldRubygemsfiles...Installingrubygems-1.8.10forruby-1.9.2-p180...ERROR:Errorrunning'GEM_PATH="/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/ruby-1.9.2-p180@global:/Users/foo/.rvm/gems/ruby-1.9.2-p180:/Users/foo/.rvm/gems/rub

    3. ruby-on-rails - Rails HTML 请求渲染 JSON - 2

      在我的Controller中,我通过以下方式在我的index方法中支持HTML和JSON:respond_todo|format|format.htmlformat.json{renderjson:@user}end在浏览器中拉起它时,它会自然地以HTML呈现。但是,当我对/user资源进行内容类型为application/json的curl调用时(因为它是索引方法),我仍然将HTML作为响应。如何获取JSON作为响应?我还需要说明什么? 最佳答案 您应该将.json附加到请求的url,提供的格式在routes.rb的路径中定义。这

    4. ruby - 通过 RVM (OSX Mountain Lion) 安装 Ruby 2.0.0-p247 时遇到问题 - 2

      我的最终目标是安装当前版本的RubyonRails。我在OSXMountainLion上运行。到目前为止,这是我的过程:已安装的RVM$\curl-Lhttps://get.rvm.io|bash-sstable检查已知(我假设已批准)安装$rvmlistknown我看到当前的稳定版本可用[ruby-]2.0.0[-p247]输入命令安装$rvminstall2.0.0-p247注意:我也试过这些安装命令$rvminstallruby-2.0.0-p247$rvminstallruby=2.0.0-p247我很快就无处可去了。结果:$rvminstall2.0.0-p247Search

    5. ruby - Fast-stemmer 安装问题 - 2

      由于fast-stemmer的问题,我很难安装我想要的任何ruby​​gem。我把我得到的错误放在下面。Buildingnativeextensions.Thiscouldtakeawhile...ERROR:Errorinstallingfast-stemmer:ERROR:Failedtobuildgemnativeextension./System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/rubyextconf.rbcreatingMakefilemake"DESTDIR="cleanmake"DESTDIR=

    6. ruby - 简单获取法拉第超时 - 2

      有没有办法在这个简单的get方法中添加超时选项?我正在使用法拉第3.3。Faraday.get(url)四处寻找,我只能先发起连接后应用超时选项,然后应用超时选项。或者有什么简单的方法?这就是我现在正在做的:conn=Faraday.newresponse=conn.getdo|req|req.urlurlreq.options.timeout=2#2secondsend 最佳答案 试试这个:conn=Faraday.newdo|conn|conn.options.timeout=20endresponse=conn.get(url

    7. ruby - 安装 Ruby 时遇到问题(无法下载资源 "readline--patch") - 2

      当我尝试安装Ruby时遇到此错误。我试过查看this和this但无济于事➜~brewinstallrubyWarning:YouareusingOSX10.12.Wedonotprovidesupportforthispre-releaseversion.Youmayencounterbuildfailuresorotherbreakages.Pleasecreatepull-requestsinsteadoffilingissues.==>Installingdependenciesforruby:readline,libyaml,makedepend==>Installingrub

    8. ruby - 从 Ruby 中的主机名获取 IP 地址 - 2

      我有一个存储主机名的Ruby数组server_names。如果我打印出来,它看起来像这样:["hostname.abc.com","hostname2.abc.com","hostname3.abc.com"]相当标准。我想要做的是获取这些服务器的IP(可能将它们存储在另一个变量中)。看起来IPSocket类可以做到这一点,但我不确定如何使用IPSocket类遍历它。如果它只是尝试像这样打印出IP:server_names.eachdo|name|IPSocket::getaddress(name)pnameend它提示我没有提供服务器名称。这是语法问题还是我没有正确使用类?输出:ge

    9. ruby - 获取模块中定义的所有常量的值 - 2

      我想获取模块中定义的所有常量的值:moduleLettersA='apple'.freezeB='boy'.freezeendconstants给了我常量的名字:Letters.constants(false)#=>[:A,:B]如何获取它们的值的数组,即["apple","boy"]? 最佳答案 为了做到这一点,请使用mapLetters.constants(false).map&Letters.method(:const_get)这将返回["a","b"]第二种方式:Letters.constants(false).map{|c

    10. ruby-on-rails - 获取 inf-ruby 以使用 ruby​​ 版本管理器 (rvm) - 2

      我安装了ruby​​版本管理器,并将RVM安装的ruby​​实现设置为默认值,这样'哪个ruby'显示'~/.rvm/ruby-1.8.6-p383/bin/ruby'但是当我在emacs中打开inf-ruby缓冲区时,它使用安装在/usr/bin中的ruby​​。有没有办法让emacs像shell一样尊重ruby​​的路径?谢谢! 最佳答案 我创建了一个emacs扩展来将rvm集成到emacs中。如果您有兴趣,可以在这里获取:http://github.com/senny/rvm.el

    随机推荐