1

我正在开发的服务器是 Open-SUSE 上的 Django 1.4 开发服务器。

我的问题

我的 jquery ajax 请求被触发,但是直到我用浏览器停止页面后才运行成功函数。

我试过的

我已经在各处设置了标志来跟踪 ajax 函数的进度。一切正常,但在我停止页面之前,成功功能不会运行。这是我的 JS:

var submitted = '';
var freq =3000; // freqency of update in ms
var counter = 0;

$('#webfileuploadform').submit(function(){

    $(document).ajaxSend(function(){
        console.log("Triggered ajaxsend handler.")
    });

    if(submitted == 'submitted') return false; // prevents multiple submits
    var progress_url = '/upload_progress/' + $('#id_progress_id').val(); // ajax view serving progress info
    var progress_guid = $('#id_progress_id').val();
    this.action += (this.action.indexOf('?') == -1 ? '?' : '&') + 'X-Progress-ID=' + progress_guid;

    var $progress = $('<div id="upload-progress" class="upload-progress"></div>').appendTo($('#webfileuploadform')).append('<div class="progress-container"><div class="progress-info">uploading 0%</div><div class="progress-bar"></div></div>');

    function update_progress_bar(){
        console.log("update_progress_bar() was hit");
        $progress.show();
        $.ajax({
            dataType:"json",
            url: progress_url,
            beforeSend: function(){
                console.log('before send');
            },
            success: function(data){
                //debugger;
                if(data.status == "uploading"){
                    var total_progress = parseInt(data.uploaded) / parseInt(data.length);
                    var width = $progress.find('.progress-container').width();
                    var progress_width = width * total_progress;
                    $progress.find('.progress-bar').width(progress_width);
                    $progress.find('.progress-info').text('uploading ' + parseInt(total_progress*100) + '%');
                    counter++;
                    console.log("status: " + data.status + counter);
                    //console.log("data.length " + data.length);
                    //console.log("data.uploaded " + data.uploaded);
                    //console.log("progress_width " + progress_width + '\n');
                } else if (data.status == "not-found") {
                    clearTimeout(progress_bar_updater);
                    console.log("status = not-found");
                } else {
                    clearTimeout(progress_bar_updater);
                    console.log("data.status = " + data.status);
                }
            },
            error: function(textStatus){
                console.log("ERROR: " + textStatus);
            },
            complete: function(jqXHR, textStatus){
                console.log(textStatus);
            }
        });
        var progress_bar_updater = setTimeout(function(){update_progress_bar()}, freq);
    }

    window.setTimeout(function(){update_progress_bar()}, freq);

    submitted = 'submitted'; // marks form as submitted

});

你可以看到我所有的旗帜。我使用表单选择要上传的文件,提交表单,控制台显示如下:

update_progress_bar() was hit
before send
Triggered ajaxsend handler.

所以这意味着我的包含 ajax 调用的函数正在被触发,ajax 请求也是如此,因为 beforeSend 和 ajaxSend 函数都输出它们的内容。另请注意,错误函数没有输出任何内容,因此没有问题。现在奇怪的部分。我按下 Chrome 中的停止按钮,控制台输出现在返回:

update_progress_bar() was hit
before send
Triggered ajaxsend handler.
status: uploading1
success

所以现在,页面停止后,整个ajax函数运行没有错误。成功函数输出到控制台,完整函数也是如此。错误函数仍然没有输出。

由于我在函数内部调用了 setTimeout,它会迭代直到我刷新页面(或者,取决于我在浏览器中按下提交然后按下停止的时间长短,它已经从 django 文件上传处理程序中读取了所有临时数据) 每次输出到控制台,直到它最终输出“未找到”(这是文件的结尾)。

我想要完成的事情

我的表单是供用户将大文件上传到服务器。我想要一个进度条来防止用户认为浏览器冻结然后重新加载文件。停止页面后,进度条工作得很好。背景和“上传 0%”都应该增加。但直到我停止页面。

它应该随着服务器读取文件而增加。为什么不是?

4

1 回答 1

0

在 ajax 函数中,我将异步设置设置为 false:

$.ajax({
    async: false,
    ...
});

这解决了这个问题。我不知道怎么做。据我了解,此设置强制 ajax 请求等到所有其他 http 请求完成后才允许它继续。在这种情况下,我不知道这是如何工作的。我将不再回答我自己的问题,以防有人知道为什么会这样……

于 2013-05-16T19:19:50.370 回答