jQuery文件上传不触发“完成”事件

22

我使用jQuery-File-Upload插件。 我编写了一个简单的代码来测试它 - 它能够工作,但是存在一些问题。 即使文件上传完成并且进度条到达末尾,它也无法触发done

这是代码:

$('#file_file').fileupload({
    dataType: 'json',
    autoUpload: true,
    add: function (e, data) {
        data.context = $('<p/>').text('Uploading...').appendTo(document.body);
        data.submit();
    },
    progressall: function (e, data) {
        var progress = parseInt(data.loaded / data.total * 100, 10);
        $('#progress .bar').css(
            'width',
            progress + '%'
        );
    },
    done: function (e, data) {
        alert('Done');
    }
});

我的输入就是这么简单:

<input type="file" id="file_file" name="file[file]" />
8个回答

31

如果您的服务器没有返回JSON,请尝试移除以下内容:

dataType: 'json'
否则,您可能会遇到一个失败事件,可以轻松进行测试:
fail: function(e, data) {
  alert('Fail!');
}

1
呵呵...这解决了我的问题。如果JSON输出有问题,done回调就不会被触发。听起来不错,但在检查JSON之前我一直在寻找为什么回调没有被触发。 - Kevin Labécot

10

我更改了一些东西,现在它可以工作了。这里是:

$('#file_file').fileupload({
    autoUpload: true,
    add: function (e, data) {
        $('body').append('<p class="upl">Uploading...</p>')
        data.submit();
    },
    progressall: function (e, data) {
        var progress = parseInt(data.loaded / data.total * 100, 10);
        $('#progress .bar').css(
            'width',
            progress + '%'
        );
    },
    done: function (e, data) {
        $('.upl').remove();
        $.each(data.files, function (index, file) {
            /**/
        });
    }
});

2
可以了。请注意,您需要将"data.result.files"更改为"data.files"。 - joan16v
在IE < 10中推送文件的解决方案完全取决于add回调函数中的"data.submit();"。 - Wagner Leonardi
1
"data.results.files" 包含更多的内容,例如缩略图网址,而 "name" 是服务器上文件的实际文件名,而不是 data.files 的名称,后者提供的是用户为文件设置的名称。 - Ian

6

我使用了autoUpload: true进行修复,看起来当未设置autoUpload属性时(即使上传按预期工作),done事件也不会触发。


2

今天进行了实验!如果你正在使用PHP,请确保你的uploadhanler PHP文件不显示错误或警告。这会创建一个错误的JSON输出,当上传文件时,插件无法发送正确的JSON缓冲区以完成事件。

为了跟踪PHP文件上的错误,最好编写一个日志文件,而不是在此类脚本上显示错误。你可以使用:

error_reporting(0)

不要忘记在日志文件中添加错误跟踪。当然!


我将一个200 OK响应更改为一个简单的JSON编码字符串,然后它就起作用了。 - Edza

1
尝试按照文档中描述的 此回调选项 进行操作:
$('#fileupload').bind('fileuploaddone', function (e, data) {
    alert('Done');
});

对我来说肯定有效。


这对我有用过。这个函数适用于旧版本。 - Kashif Hanif

1

我猜这个话题已经不再是热门话题了,但我刚刚通过使用 always 回调而不是 done 回调来解决了这个问题。这个回调在 这里 描述。

现在代码的相关部分看起来像这样:

$('#fileupload').fileupload({
        dataType: 'json',
        autoUpload: true,
        url: 'transit/',
        always: function (e, data) {
        moveFile();
    },
    
    progressall: function (e, data) {
    var progress = parseInt(data.loaded / data.total * 100, 10);
    $('#progress .progress-bar').css('width', progress + '%'
    );
  }
         
});

这个答案不够有用,请添加一些细节。 - Sfili_81
我希望现在有足够的细节来满足Sfill_81的需求。 - user3680973

0
我正在使用multer, multer-azure-storage和blueimp-file-upload,它们都由unpkg.com提供服务。以下是一个带有完成触发器的多文件上传代码,截至2017年10月22日仍在工作中。
js文件:
  <script src="https://unpkg.com/jquery@3.2.1/dist/jquery.min.js"></script>
  <script src="https://unpkg.com/blueimp-file-upload@9.19.1/js/vendor/jquery.ui.widget.js"></script>
  <script src="https://unpkg.com/blueimp-file-upload@9.19.1/js/jquery.iframe-transport.js"></script>
  <script src="https://unpkg.com/blueimp-file-upload@9.19.1/js/jquery.fileupload.js"></script>

从Express服务的页面HTML:

      $('#fileupload').fileupload({
          url: 'https://domainwhatevs/my-listings/edit/[property id]/gallery',
          paramName: '_file',
          dataType: 'json',
          type: 'POST',
          autoUpload: true,
          add: function (e, data) {
              console.log('uploading:', data)
              data.submit();
          },
          done: function (e, data) {
              console.log('done triggered');
              console.log(data._response.result.result[0].originalname, 'uploaded at', data._response.result.result[0].url);
              $.each(data.files, function (index, file) {
                // console.log(file.name, 'uploaded.')
                // console.log('done');
                // console.log(index);
                // console.log(file);
              });
              console.log(data);
          }
      });

// GET /my-listings/edit/[property id]/gallery

,这段内容与编程有关。
app.get(
    [
        '/my-listings/edit/:_id/gallery'
    ],
    (req, res) => {
        console.log('image gallery:', req.params._id);
        res.render('my-listings--edit--gallery', {
            _id: req.params._id,
            session: req.session
        });
    }
);

// POST /my-listings/edit/[property id]/gallery

的意思是“提交/我的列表/编辑/[物业ID]/画廊”。
 app.post(
    [
        '/my-listings/edit/:_id/gallery'
    ],
    upload.array('_file'),
    (req, res, next) => {
        console.log(req.files);
        res.setHeader('Content-Type', 'application/json');
        res.send({result: req.files});
        next();
    }
);

-1
 $(input).fileupload(

       url      : '...'

      ,dataType : 'json'
      ,sequentialUploads : true

       ,add      : function (e,data) {


           $.each(data.files,function(i,file){

                file.jqXHR = data.submit()
                           .success(function (result, textStatus, jqXHR) {/* ... */})
                           .error(function (jqXHR, textStatus, errorThrown) {
                             })
                           .complete(function (result, textStatus, jqXHR) { 
                               //...                   
                                     });

                 });
       }


       ,done: function (e, data) {
         console.log(data);

       }


   });

对我来说完美无缺;

区别在于

  • URL已设置(希望您只是忘记在代码片段中放置它);

  • 我添加文件到下载队列的方式

  • 顺序上传 (?)

编辑:

jQuery文件上传插件利用jQuery.ajax()进行文件上传请求。即使是没有XHR支持的浏览器,也要感谢Iframe Transport插件。

为文件上传设置的选项传递给jQuery.ajax(),允许定义任何ajax设置或回调。 ajax选项processData、contentType和cache被设置为false,以使文件上传正常工作,并且不应更改。

https://github.com/blueimp/jQuery-File-Upload/wiki/Options

在你的代码中,你可能也改变了那些ajax设置;无论如何,这意味着如果你的设置正确,因为它使用了$.ajax,done就不会被触发。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接