blueimp jqueryfile - upload -如何提交表单而不附带文件?

时间:2022-11-24 11:24:24

I have found solutions on how to add additional form data when submitting the file upload form. This question is how to upload the additional data if there is no file to upload.

我找到了在提交文件上传表单时如何添加额外表单数据的解决方案。这个问题是,如果没有要上传的文件,如何上传附加的数据。

I am using blueimp jquery-file-upload in a task management app in order to drag and drop files and attach them to a task.

我在任务管理应用程序中使用blueimp jquery-file-upload来拖放文件并将它们附加到任务上。

The script is initialized and setup to not automatically upload when files are attached. On the fileuploadadd callback I attach data.submit() to my submit event handler. This accomplishes that we submit the task data and the files in one POST request.

初始化脚本并设置为在文件被附加时不自动上传。在fileuploadadd回调中,我将data.submit()附加到提交事件处理程序。这实现了我们在一个POST请求中提交任务数据和文件。

Until files are added I'm unable to get access to the file-upload data to use the data.submit() function. I came up with a work around by adding an empty file (and then removing it) on page load which would trigger the binding data.submit() to the submit button. The problem is that the plugin is returning an error while trying to loop through an empty array of files. This problem would also occur if you added a file and then removed it before submitting the form.

在添加文件之前,我无法访问文件上传数据以使用data.submit()函数。我在页面加载中添加了一个空文件(然后删除它),这将触发binding data.submit()到submit按钮。问题是插件在试图循环遍历一个空的文件数组时返回了一个错误。如果您添加了一个文件,然后在提交表单之前删除它,也会出现这个问题。

I have been looking for a solution to this for a while and have looked high and low but couldn't find anything in the (IMHO) terrible documentation.

我已经寻找了一段时间的解决方案,一直在寻找,但在(IMHO)糟糕的文档中找不到任何东西。

Have a look at my code below:

看看我的代码如下:

    $('#post_task').fileupload({
        autoUpload: false,
        singleFileUploads: false,
        disableImagePreview: true,
    }).on('fileuploadadd', function (e, data) {
        $.each(data.files, function (index, file) {
            var filename = file.name,
                filesize = bytesToSize(file.size) 
                ext = filename.substr(filename.lastIndexOf('.')+1,5),
                icon = '<i class="sprite_file sprite_file-file_extension_'+ext+'"></i>',
                node = $('<li/>').append($('<span/>').html(icon + filename + ' ' + filesize + '<a href="#">&times</a>')).attr('data-index',index);

            node.find('a').click(function(e){
                e.preventDefault();
                var $self = $(this),
                    $listItem = $self.parents('li'),
                    listIndex = $listItem.attr('data-index');
                $listItem.remove();
                $('#files li').attr('data-index',function(index){return index;});
                data.files.splice(listIndex,listIndex);
                console.log(data);
                vardata = data;
            });
            $('#files').append(node);
        });
        $('#post_task').unbind('submit').submit(function(ev){
            ev.preventDefault();
            data.submit();
        });
    });

4 个解决方案

#1


3  

I faced the same problem and I ended up adding an empty file prior to submitting if there is no file.

我遇到了同样的问题,最后在没有文件提交之前添加了一个空文件。

$("#fileupload").fileupload('add', {
    files: ['']
});

This works perfectly in my situation and the backend receives the POST while the submitted file is null.

这在我的情况下非常有效,后端在提交的文件为空时接收POST。

With most browsers (tested Chrome and FF) my Backend will receive no file (null) but with IE8 there is one with size 0. I haven't tested it with any other IE.

在大多数浏览器(测试过的Chrome和FF)中,我的后端不会收到任何文件(null),但是在IE8中有一个文件的大小为0。我还没有用别的IE测试过。

#2


1  

I just made two separate handlers like so:

我做了两个独立的处理器

$('#avatar').fileupload({
            singleFileUploads: true,
            multipart        : true,
            dataType         : 'json',
            autoUpload       : false,
            url              : config.settings.api + 'services/user/updateByActivationKey',
            type             : 'POST',
            add              : function (e, data) {

                submitbtn.on("click", function () {
                    console.log('submitting with image');
                    data.submit();
                });
            },
            done             : function (result) {

                console.log(result);
                if (!result.error) {
                    $('#modal-account-activated-success').modal('show');
                    $("#submitbtn").removeAttr('disabled');
                    $('#mercname').html('');
                    window.setTimeout(function () {
                        window.location.href = config.settings.user_url;
                    }, 3000);

                } else {
                    //analytics.track('completeProfileError', {
                    //  error        : JSON.parse(result.responseText).error,
                    //  activationKey: sessionStorage.getItem("activationkey")
                    //});
                    $('#modal-account-activated-error').modal('show');
                    $('#submitloader').html('');
                    $("#submitbtn").removeAttr('disabled');
                }
            }
            ,
            fail             : function (e) {
                //analytics.track('completeProfileError', {
                //  error        : e,
                //  activationKey: sessionStorage.getItem("activationkey")
                //});
                $('#errormessage').html(JSON.parse(e.responseText).error.messages[0]);
                $('#modal-account-activated-error').modal('show');
                $('#submitloader').html('');
                $("#submitbtn").removeAttr('disabled');

            }
        });

        //if no image was uploaded
        submitbtn.on("click", function () {
            if ($('#preview').html().length < 1) {
                console.log('submitting without image');

                $.ajax({
                    url       : config.settings.api + 'services/user/updateByActivationKey',
                    type      : 'POST',
                    data      : JSON.stringify({
                        'email'                     : $("#email").val(),
                        'activationKey'             : $("#activationKey").val(),
                        'firstName'                 : $("#firstname").val(),
                        'lastName'                  : $("#name").val(),
                        'password'                  : $("#password").val(),
                        'gender'                    : $("#gender").val(),
                        'birthdate'                 : $("#birthdate").val(),
                        'acceptedTermsAndConditions': $("#checkbox-accept-terms").val(),
                        'allowsDirectMarketing'     : $("#checkbox-allow-marketing").val()

                    }),
                    beforeSend: function (xhr) {
                        xhr.setRequestHeader("Content-Type", "application/json");
                    },
                    success   : function (result) {
                        console.log(result);
                        if (!result.error) {
                            $('#modal-account-activated-success').modal('show');
                            $("#submitbtn").removeAttr('disabled');
                            $('#mercname').html('');
                            window.setTimeout(function () {
                                window.location.href = config.settings.user_url;
                            }, 3000);

                        } else {
                            //analytics.track('completeProfileError', {
                            //  error        : JSON.parse(result.responseText).error,
                            //  activationKey: sessionStorage.getItem("activationkey")
                            //});
                            $('#modal-account-activated-error').modal('show');
                            $('#submitloader').html('');
                            $("#submitbtn").removeAttr('disabled');
                        }
                    },
                    error     : function (e) {
                        //analytics.track('completeProfileError', {
                        //  error        : e,
                        //  activationKey: sessionStorage.getItem("activationkey")
                        //});
                        $('#errormessage').html(JSON.parse(e.responseText).error.messages[0]);
                        $('#modal-account-activated-error').modal('show');
                        $('#submitloader').html('');
                        $("#submitbtn").removeAttr('disabled');
                    }
                })
            }
        });

#3


1  

@Hirshy and @Luk, your solution is really quite elegant and works like a charm. The files input field does not even get sent to the server so it's easy to determine when a file is in the payload.

@Hirshy和@Luk,你的解决方案真的很优雅,而且很有魅力。文件输入字段甚至不会被发送到服务器,因此很容易确定文件何时在有效负载中。

In my Angular app, I have a single view for both adding a new document and some attendant data and for editing the data and/or uploading a replacement document.

在我的角度应用程序中,我有一个视图,用于添加新文档和一些相关数据,以及编辑数据和/或上传替换文档。

Here is my solution:

这是我的解决方案:

/*------------------------------------------------------------------------*/
/* Prepare file uploader.                                                 */
/*                                                                        */
/* jQuery-File-Upload does not submit a form unless a file has been       */
/* selected. To allow this, we manually add an empty file to be uploaded, */
/* which makes the submit handler available, and we replace the submit    */
/* handler with one that will submit the form without a selected file.    */
/*                                                                        */
/* see: http://*.com/q/21760757/2245849.                      */
/*------------------------------------------------------------------------*/
var uploadForm = $('#DocumentForm');
var fileInput  = $('#DocumentForm input:file');

$scope.uploadOptions = 
  {
  url:              Services.Documents.uploadRoute,
  autoUpload:       false,
  dropZone:         uploadForm,
  fileInput:        fileInput,
  replaceFileInput: false
  };

/*---------------------------------------------------------------*/
/* Initialize the uploader. This must be done with the options   */
/* or an error will be thrown when an empty file is added below. */
/* It is also necessary to initialize with the options here as   */
/* well as in the element html or the results are unpredictable. */
/*---------------------------------------------------------------*/
uploadForm.fileupload($scope.uploadOptions);

/*--------------------------------------------------------------------*/
/* File processing is called in the default add handler and this      */
/* handler is called after a successful add. It displays the file     */
/* name in the drop zone, sets the document name for a new document,  */
/* and sets the submit handler to submit the form with file and data. */
/*                                                                    */
/* If editing a document, a dummy empty file object is manually       */
/* added to make the submit handler available so the user can make    */
/* data changes without uploading a new document.                     */
/*--------------------------------------------------------------------*/
uploadForm.bind("fileuploadprocessdone", function(e, data) 
  {
  /*------------------------------------------------------------*/
  /* Get the user selected file object and display the name.    */
  /* Set the document name to the file name if not already set. */
  /*------------------------------------------------------------*/
  if (data.files[0].name)
    {
    $scope.document.file = data.files[0];
    if (!$scope.document.name)
      $scope.document.name = $scope.document.file.name;
    MessageService.clear();
    }

  /*--------------------------------------*/
  /* If this is the dummy file add, reset */
  /* 'acceptFileTypes' to global config.  */
  /*--------------------------------------*/
  else  
    delete $scope.uploadOptions.acceptFileTypes;

  /*------------------------------------------------------------*/
  /* Set the submit handler. We have to do this every time a    */
  /* file is added because 'data' is not passed to the handler. */
  /*------------------------------------------------------------*/
  uploadForm.unbind('submit').submit(function(e)
    {
    e.preventDefault();
    data.submit();
    });
  });

/*---------------------------------------------------------------------------*/
/* If we get here, the file could not be added to the process queue most     */
/* likely because it is too large or not an allowed type. This is dispatched */
/* after the add event so clear the current file and show the error message. */
/*---------------------------------------------------------------------------*/
uploadForm.bind("fileuploadprocessfail", function(e, data) 
  { 
  $scope.document.file = null;
  MessageService.notice(data.files[data.index].error);
  });

/*-----------------------------------------------------------------*/
/* Add a dummy empty file if not a new document so the submit      */
/* handler is set and the user does not have to upload a document. */
/*-----------------------------------------------------------------*/
if (!$scope.new_document)
  {
  $scope.uploadOptions.acceptFileTypes = null;
  uploadForm.fileupload('add', { files: [{}] });
  }

UPDATE

更新

It turns out uploadForm.fileupload('add', { files: [''] }); will result in an exception being thrown in the browser if the server returns a failed status. JFU tries to assign data.files[0].error and data.files[0] doesn't exist.

原来uploadForm。文件上传('add', {files: ["]});如果服务器返回失败的状态,将导致在浏览器中抛出异常。JFU尝试分配data.files[0]。错误和数据。文件不存在[0]。

The problem is handled nicely by assigning an empty array instead of an empty string: uploadForm.fileupload('add', { files: [[]] });

通过分配空数组而不是空字符串uploadForm,可以很好地解决这个问题。fileupload('add', {files: []});

I have updated the example above.

我已经更新了上面的例子。

UPDATE 2/29/16

更新2/29/16

It turned out I did want to restrict the file types after all so I modified my script to clear 'acceptFileTypes' property before the dummy file add and reset it in the add handler. Also discovered I could not access the process errors in the add handler so replaced it with 'fileuploadprocessdone' and handled the error in 'fileuploadprocessfail'.

原来我确实想限制文件类型,所以我修改了我的脚本,在虚拟文件添加和重置之前清除“acceptFileTypes”属性。还发现我无法访问add handler中的进程错误,所以用“fileuploadprocessdone”替换它,并处理“fileuploadprocessfail”中的错误。

I have updated the example above but we're still using JFU 5.42.0.

我已经更新了上面的示例,但是我们仍然使用JFU 5.42.0。

IMPORTANT

重要的

I am using 5.42.0 which is a very old version of JFU. I did not write this code and my first attempt to upgrade failed. When I do upgrade, I'll update this solution.**

我使用的是5.42.0,这是一个非常古老的JFU版本。我没有写这段代码,我第一次尝试升级失败。当我升级时,我会更新这个解决方案。**

#4


-1  

Try this puglin simpleUpload, no need form

试试这个puglin simpleUpload, no need form

Html:

Html:

<input type="file" name="arquivo" id="simpleUpload" multiple >
<button type="button" id="enviar">Enviar</button>

Javascript:

Javascript:

$('#simpleUpload').simpleUpload({
  url: 'upload.php',
  trigger: '#enviar',
  success: function(data){
    alert('Envio com sucesso');

  }
});

#1


3  

I faced the same problem and I ended up adding an empty file prior to submitting if there is no file.

我遇到了同样的问题,最后在没有文件提交之前添加了一个空文件。

$("#fileupload").fileupload('add', {
    files: ['']
});

This works perfectly in my situation and the backend receives the POST while the submitted file is null.

这在我的情况下非常有效,后端在提交的文件为空时接收POST。

With most browsers (tested Chrome and FF) my Backend will receive no file (null) but with IE8 there is one with size 0. I haven't tested it with any other IE.

在大多数浏览器(测试过的Chrome和FF)中,我的后端不会收到任何文件(null),但是在IE8中有一个文件的大小为0。我还没有用别的IE测试过。

#2


1  

I just made two separate handlers like so:

我做了两个独立的处理器

$('#avatar').fileupload({
            singleFileUploads: true,
            multipart        : true,
            dataType         : 'json',
            autoUpload       : false,
            url              : config.settings.api + 'services/user/updateByActivationKey',
            type             : 'POST',
            add              : function (e, data) {

                submitbtn.on("click", function () {
                    console.log('submitting with image');
                    data.submit();
                });
            },
            done             : function (result) {

                console.log(result);
                if (!result.error) {
                    $('#modal-account-activated-success').modal('show');
                    $("#submitbtn").removeAttr('disabled');
                    $('#mercname').html('');
                    window.setTimeout(function () {
                        window.location.href = config.settings.user_url;
                    }, 3000);

                } else {
                    //analytics.track('completeProfileError', {
                    //  error        : JSON.parse(result.responseText).error,
                    //  activationKey: sessionStorage.getItem("activationkey")
                    //});
                    $('#modal-account-activated-error').modal('show');
                    $('#submitloader').html('');
                    $("#submitbtn").removeAttr('disabled');
                }
            }
            ,
            fail             : function (e) {
                //analytics.track('completeProfileError', {
                //  error        : e,
                //  activationKey: sessionStorage.getItem("activationkey")
                //});
                $('#errormessage').html(JSON.parse(e.responseText).error.messages[0]);
                $('#modal-account-activated-error').modal('show');
                $('#submitloader').html('');
                $("#submitbtn").removeAttr('disabled');

            }
        });

        //if no image was uploaded
        submitbtn.on("click", function () {
            if ($('#preview').html().length < 1) {
                console.log('submitting without image');

                $.ajax({
                    url       : config.settings.api + 'services/user/updateByActivationKey',
                    type      : 'POST',
                    data      : JSON.stringify({
                        'email'                     : $("#email").val(),
                        'activationKey'             : $("#activationKey").val(),
                        'firstName'                 : $("#firstname").val(),
                        'lastName'                  : $("#name").val(),
                        'password'                  : $("#password").val(),
                        'gender'                    : $("#gender").val(),
                        'birthdate'                 : $("#birthdate").val(),
                        'acceptedTermsAndConditions': $("#checkbox-accept-terms").val(),
                        'allowsDirectMarketing'     : $("#checkbox-allow-marketing").val()

                    }),
                    beforeSend: function (xhr) {
                        xhr.setRequestHeader("Content-Type", "application/json");
                    },
                    success   : function (result) {
                        console.log(result);
                        if (!result.error) {
                            $('#modal-account-activated-success').modal('show');
                            $("#submitbtn").removeAttr('disabled');
                            $('#mercname').html('');
                            window.setTimeout(function () {
                                window.location.href = config.settings.user_url;
                            }, 3000);

                        } else {
                            //analytics.track('completeProfileError', {
                            //  error        : JSON.parse(result.responseText).error,
                            //  activationKey: sessionStorage.getItem("activationkey")
                            //});
                            $('#modal-account-activated-error').modal('show');
                            $('#submitloader').html('');
                            $("#submitbtn").removeAttr('disabled');
                        }
                    },
                    error     : function (e) {
                        //analytics.track('completeProfileError', {
                        //  error        : e,
                        //  activationKey: sessionStorage.getItem("activationkey")
                        //});
                        $('#errormessage').html(JSON.parse(e.responseText).error.messages[0]);
                        $('#modal-account-activated-error').modal('show');
                        $('#submitloader').html('');
                        $("#submitbtn").removeAttr('disabled');
                    }
                })
            }
        });

#3


1  

@Hirshy and @Luk, your solution is really quite elegant and works like a charm. The files input field does not even get sent to the server so it's easy to determine when a file is in the payload.

@Hirshy和@Luk,你的解决方案真的很优雅,而且很有魅力。文件输入字段甚至不会被发送到服务器,因此很容易确定文件何时在有效负载中。

In my Angular app, I have a single view for both adding a new document and some attendant data and for editing the data and/or uploading a replacement document.

在我的角度应用程序中,我有一个视图,用于添加新文档和一些相关数据,以及编辑数据和/或上传替换文档。

Here is my solution:

这是我的解决方案:

/*------------------------------------------------------------------------*/
/* Prepare file uploader.                                                 */
/*                                                                        */
/* jQuery-File-Upload does not submit a form unless a file has been       */
/* selected. To allow this, we manually add an empty file to be uploaded, */
/* which makes the submit handler available, and we replace the submit    */
/* handler with one that will submit the form without a selected file.    */
/*                                                                        */
/* see: http://*.com/q/21760757/2245849.                      */
/*------------------------------------------------------------------------*/
var uploadForm = $('#DocumentForm');
var fileInput  = $('#DocumentForm input:file');

$scope.uploadOptions = 
  {
  url:              Services.Documents.uploadRoute,
  autoUpload:       false,
  dropZone:         uploadForm,
  fileInput:        fileInput,
  replaceFileInput: false
  };

/*---------------------------------------------------------------*/
/* Initialize the uploader. This must be done with the options   */
/* or an error will be thrown when an empty file is added below. */
/* It is also necessary to initialize with the options here as   */
/* well as in the element html or the results are unpredictable. */
/*---------------------------------------------------------------*/
uploadForm.fileupload($scope.uploadOptions);

/*--------------------------------------------------------------------*/
/* File processing is called in the default add handler and this      */
/* handler is called after a successful add. It displays the file     */
/* name in the drop zone, sets the document name for a new document,  */
/* and sets the submit handler to submit the form with file and data. */
/*                                                                    */
/* If editing a document, a dummy empty file object is manually       */
/* added to make the submit handler available so the user can make    */
/* data changes without uploading a new document.                     */
/*--------------------------------------------------------------------*/
uploadForm.bind("fileuploadprocessdone", function(e, data) 
  {
  /*------------------------------------------------------------*/
  /* Get the user selected file object and display the name.    */
  /* Set the document name to the file name if not already set. */
  /*------------------------------------------------------------*/
  if (data.files[0].name)
    {
    $scope.document.file = data.files[0];
    if (!$scope.document.name)
      $scope.document.name = $scope.document.file.name;
    MessageService.clear();
    }

  /*--------------------------------------*/
  /* If this is the dummy file add, reset */
  /* 'acceptFileTypes' to global config.  */
  /*--------------------------------------*/
  else  
    delete $scope.uploadOptions.acceptFileTypes;

  /*------------------------------------------------------------*/
  /* Set the submit handler. We have to do this every time a    */
  /* file is added because 'data' is not passed to the handler. */
  /*------------------------------------------------------------*/
  uploadForm.unbind('submit').submit(function(e)
    {
    e.preventDefault();
    data.submit();
    });
  });

/*---------------------------------------------------------------------------*/
/* If we get here, the file could not be added to the process queue most     */
/* likely because it is too large or not an allowed type. This is dispatched */
/* after the add event so clear the current file and show the error message. */
/*---------------------------------------------------------------------------*/
uploadForm.bind("fileuploadprocessfail", function(e, data) 
  { 
  $scope.document.file = null;
  MessageService.notice(data.files[data.index].error);
  });

/*-----------------------------------------------------------------*/
/* Add a dummy empty file if not a new document so the submit      */
/* handler is set and the user does not have to upload a document. */
/*-----------------------------------------------------------------*/
if (!$scope.new_document)
  {
  $scope.uploadOptions.acceptFileTypes = null;
  uploadForm.fileupload('add', { files: [{}] });
  }

UPDATE

更新

It turns out uploadForm.fileupload('add', { files: [''] }); will result in an exception being thrown in the browser if the server returns a failed status. JFU tries to assign data.files[0].error and data.files[0] doesn't exist.

原来uploadForm。文件上传('add', {files: ["]});如果服务器返回失败的状态,将导致在浏览器中抛出异常。JFU尝试分配data.files[0]。错误和数据。文件不存在[0]。

The problem is handled nicely by assigning an empty array instead of an empty string: uploadForm.fileupload('add', { files: [[]] });

通过分配空数组而不是空字符串uploadForm,可以很好地解决这个问题。fileupload('add', {files: []});

I have updated the example above.

我已经更新了上面的例子。

UPDATE 2/29/16

更新2/29/16

It turned out I did want to restrict the file types after all so I modified my script to clear 'acceptFileTypes' property before the dummy file add and reset it in the add handler. Also discovered I could not access the process errors in the add handler so replaced it with 'fileuploadprocessdone' and handled the error in 'fileuploadprocessfail'.

原来我确实想限制文件类型,所以我修改了我的脚本,在虚拟文件添加和重置之前清除“acceptFileTypes”属性。还发现我无法访问add handler中的进程错误,所以用“fileuploadprocessdone”替换它,并处理“fileuploadprocessfail”中的错误。

I have updated the example above but we're still using JFU 5.42.0.

我已经更新了上面的示例,但是我们仍然使用JFU 5.42.0。

IMPORTANT

重要的

I am using 5.42.0 which is a very old version of JFU. I did not write this code and my first attempt to upgrade failed. When I do upgrade, I'll update this solution.**

我使用的是5.42.0,这是一个非常古老的JFU版本。我没有写这段代码,我第一次尝试升级失败。当我升级时,我会更新这个解决方案。**

#4


-1  

Try this puglin simpleUpload, no need form

试试这个puglin simpleUpload, no need form

Html:

Html:

<input type="file" name="arquivo" id="simpleUpload" multiple >
<button type="button" id="enviar">Enviar</button>

Javascript:

Javascript:

$('#simpleUpload').simpleUpload({
  url: 'upload.php',
  trigger: '#enviar',
  success: function(data){
    alert('Envio com sucesso');

  }
});