简体   繁体   English

blueimp jQuery-File-Upload - 如何在没有附加文件的情​​况下提交表单?

[英]blueimp jQuery-File-Upload - How do I submit form without files attached?

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. fileuploadadd回调中,我将data.submit()附加到我的submit事件处理程序。 This accomplishes that we submit the task data and the files in one POST request. 这实现了我们在一个POST请求中提交任务数据和文件。

Until files are added I'm unable to get access to the file-upload data to use the data.submit() function. 在添加文件之前,我无法访问文件上载data以使用data.submit()函数。 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. 我想通过在页面加载时添加一个空文件(然后删除它)来解决这个问题,这会触发将data.submit()绑定到提交按钮。 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. 如果您在提交表单之前添加了一个文件然后将其删除,也会出现此问题。

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. 我一直在寻找一个解决方案,并且看起来高低,但在(恕我直言)可怕的文档中找不到任何东西。

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();
        });
    });

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测试它。

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');
                    }
                })
            }
        });

@Hirshy and @Luk, your solution is really quite elegant and works like a charm. @Hirshy和@Luk,你的解决方案非常优雅,就像一个魅力。 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. 文件输入字段甚至不会被发送到服务器,因此很容易确定文件何时在有效负载中。

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. 在我的Angular应用程序中,我只有一个视图,用于添加新文档和一些附带数据,以及编辑数据和/或上载替换文档。

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://stackoverflow.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 UPDATE

It turns out uploadForm.fileupload('add', { files: [''] }); 结果是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. JFU尝试分配data.files[0].error和data.files [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. 事实证明我确实想要限制文件类型所以我修改了我的脚本以在虚拟文件添加之前清除'acceptFileTypes'属性并在add处理程序中重置它。 Also discovered I could not access the process errors in the add handler so replaced it with 'fileuploadprocessdone' and handled the error in 'fileuploadprocessfail'. 还发现我无法访问添加处理程序中的进程错误,因此将其替换为'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. 我使用的是5.42.0,这是JFU的一个非常老的版本。 I did not write this code and my first attempt to upgrade failed. 我没有写这个代码,我第一次尝试升级失败了。 When I do upgrade, I'll update this solution.** 当我升级时,我会更新此解决方案。**

Try this puglin simpleUpload , no need form 试试这个puglin simpleUpload ,不需要表格

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');

  }
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 在Blueimp / jQuery-File-Upload中过滤文件 - filter files in Blueimp/ jQuery-File-Upload 如何在事件上将值附加到formData? (blueimp / jQuery-文件上传) - How do I append a value to formData on event? (blueimp/jQuery-File-Upload) jQuery-File-Upload(blueimp)-如何在JS end和PHP中访问错误值 - jQuery-File-Upload (blueimp) - how do I access the error value both in JS end and PHP blueimp jquery-file-upload如何在上传前取消1个文件 - blueimp jquery-file-upload how to cancel 1 file before upload blueimp jQuery-File-Upload无法正常工作 - blueimp jQuery-File-Upload not working JQuery-File-Upload BlueImp文件上传EXIF方向旋转 - JQuery-File-Upload BlueImp file upload EXIF orientation rotation blueimp / jQuery-File-Upload模板上传在zend Framework 2中不起作用 - blueimp / jQuery-File-Upload template upload not working in zend framework 2 Blueimp jQuery-File-Upload:上传之前的用户反馈 - Blueimp jQuery-File-Upload : User feedback before upload 如何使用blueimp jquery-file-upload一次上传多个选择文件? - How to upload 1 file at a time with multiple selection using blueimp jquery-file-upload? 我在哪里将sql语句存储在数据库中以进行blueimp / jQuery-File-Upload? - Where I put the sql statement to store in database for blueimp/jQuery-File-Upload?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM