上传时的 Dropzone 提交按钮

Posted

技术标签:

【中文标题】上传时的 Dropzone 提交按钮【英文标题】:Dropzone Submit Button on Upload 【发布时间】:2018-03-25 11:44:13 【问题描述】:

我想在我的 dropzone 文件上传器中添加一个按钮上传。目前它是在选择文件或将文件拖入放置区域后直接上传文件。我想做的是: 1.选择或拖放要上传的文件。 2. 验证 3. 点击或按下按钮上传上传文件。

注意:文件只有在按下按钮上传后才会上传。

这是我的表格

<form id='frmTarget' name='dropzone' action='upload_files.php' class='dropzone'>
   <div class='fallback'>
      <input name='file' type='file' multiple />
   </div>
   <input id='refCampaignID' name='refCampaignID' type='hidden' value=\ "$rowCampaign->CampaignID\" />
</form>

这是我的 JS

Dropzone.options.frmTarget = 
    
            url: 'upload_files.php',
            paramName: 'file',
            clickable: true,
            maxFilesize: 5,
            uploadMultiple: true, 
            maxFiles: 2,
            addRemoveLinks: true,
            acceptedFiles: '.png,.jpg,.pdf',
            dictDefaultMessage: 'Upload your files here',
            success: function(file, response)
            
                setTimeout(function() 
                    $('#insert_pic_div').hide();
                    $('#startEditingDiv').show();
                , 2000);
            
        ;

这是我的 php 发布请求

 foreach ($_FILES["file"] as $key => $arrDetail) 
   
      foreach ($arrDetail as $index => $detail) 
         //print_rr($_FILES["file"][$key][$index]);
         $targetDir = "project_images/";
         $fileName = $_FILES["file"]['name'][$index];
         $targetFile = $targetDir.$fileName;

         if(move_uploaded_file($_FILES["file"]['tmp_name'][$index],$targetFile))
         
            $db = new ZoriDatabase("tblTarget", $_REQUEST["TargetID"], null, 0);
            $db->Fields["refCampaignID"] = $_REQUEST["refCampaignID"];
            $db->Fields["strPicture"] = $fileName;
            $db->Fields["blnActive"] = 1;
            $db->Fields["strLastUser"] = $_SESSION[USER]->USERNAME;
            $result = $db->Save();

            if($result->Error == 1)
               return "Details not saved.";
            else
               return "Details saved.";
            
         else
            return "File not uploaded.";
         
      
   

【问题讨论】:

样本无效:ReferenceError: Can't find variable: Dropzone 【参考方案1】:

你需要:

    添加一个按钮:

    <button type="submit" id="button" class="btn btn-primary">Submit</button>
    

    告诉Dropzone 不要在您放置文件时自动上传文件,默认情况下会这样做。通过the autoProcessQueue config option 完成:

    autoProcessQueue: false
    

    由于 Dropzone 现在不会自动上传文件,因此您需要在单击按钮时手动告诉它这样做。因此,您需要一个用于该按钮单击的事件处理程序,它告诉 Dropzone 进行上传:

    $("#button").click(function (e) 
        e.preventDefault();
        myDropzone.processQueue();
    );
    

    这只会发布上传的文件,没有任何其他输入字段。您可能想要发布所有字段,例如您的refCampaignID、CSRF 令牌(如果有)等。为此,您需要在发送前将它们复制到 POST 中。 Dropzone 有一个sending event,在发送每个文件之前都会调用它,您可以在其中添加回调:

    this.on('sending', function(file, xhr, formData) 
        // Append all form inputs to the formData Dropzone will POST
        var data = $('form').serializeArray();
        $.each(data, function(key, el) 
            formData.append(el.name, el.value);
        );
    );
    

把它们放在一起:

Dropzone.options.frmTarget = 
    autoProcessQueue: false,
    url: 'upload_files.php',
    init: function () 

        var myDropzone = this;

        // Update selector to match your button
        $("#button").click(function (e) 
            e.preventDefault();
            myDropzone.processQueue();
        );

        this.on('sending', function(file, xhr, formData) 
            // Append all form inputs to the formData Dropzone will POST
            var data = $('#frmTarget').serializeArray();
            $.each(data, function(key, el) 
                formData.append(el.name, el.value);
            );
        );
    

【讨论】:

我怎样才能发送一个'csrf-token'? csrf-token 令牌问题在 autoProcessQueue 属性 headers: 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') , 之前添加标头后修复 @Udara 答案的第 4 步显示了代码,该代码将在 POSTed 数据的表单中包含所有输入。如果您的表单中有 CSRF 字段,它将被发送 - 无需将其添加为标题。 是的,这很完美,但是如果我们想要进行服务器端验证怎么办。如果出现验证错误,队列将为空 如何在myDropzone.processQueue();之前更新文件【参考方案2】:

我想我也会添加一个纯原生 JS 解决方案,没有 jQuery。

/* 'dropform' is a camelized version of your dropzone form's ID */
      Dropzone.options.dropform = 
        /* Add all your configuration here */
        autoProcessQueue: false,

        init: function()
        
          let myDropzone = this;
          /* 'submit-dropzone-btn' is the ID of the form submit button */
          document.getElementById('submit-dropzone-btn').addEventListener("click", function (e) 
              e.preventDefault();
              myDropzone.processQueue();
          );

          this.on('sending', function(file, xhr, formData) 
          
            /* OPTION 1 (not recommended): Construct key/value pairs from inputs in the form to be sent off via new FormData
               'dropform' is the ID of your dropzone form
               This method still works, but it's submitting a new form instance.  */
              formData = new FormData(document.getElementById('dropform'));

             /* OPTION 2: Append inputs to FormData */
              formData.append("input-name", document.getElementById('input-id').value);
          );
        
      ;

注意: 设置事件监听器,例如我们在这里所做的sending 应该放在init 函数中。如果您要将它们放在其他地方,例如:

init: function() 

    //...
,
sending: function(file, xhr, formData) 

  //... logic before each file send

这将覆盖为 sending 事件侦听器提供的默认逻辑 dropzone,并可能导致意外的副作用。仅当您知道自己在做什么时才应该这样做。

【讨论】:

以上是关于上传时的 Dropzone 提交按钮的主要内容,如果未能解决你的问题,请参考以下文章

手动添加文件时的Vue2-Dropzone流程表单

Krajee 文件输入在表单提交时提交文件

使用 Dropzone 和 Laravel 上传产品

单击提交输入时的单选按钮[关闭]

jQuery 文件上传:是不是可以使用提交按钮触发上传?

jQuery 文件上传:是不是可以使用提交按钮触发上传?