Dropzone.JS 在同一个请求中发送文件和表单数据

Posted

技术标签:

【中文标题】Dropzone.JS 在同一个请求中发送文件和表单数据【英文标题】:Dropzone.JS send files and form data in the same request 【发布时间】:2018-02-19 13:34:28 【问题描述】:

我在现有表单中使用 dropzone.js 来存储图像,我可以在保存表单的同时存储图像吗?我的意思是,按照与表单相同的请求发送放置在 dropzone 上的图像?

      Form::open(array('method'=>'post','class'=> 'ajaxaddevent','url' => 
'/savenewevent', 'enctype' => 'multipart/form-data')) 
            <div class="form-group">
                    <label for="name">Título do Evento</label>
                    <input type="text" id="name" name="name" class="form-
control" />
                </div>

                <div class="form-group">
                    <label for="eventtype">Tipo</label>
                    <select class="form-control selecttype" name="eventtype" id="eventtype">
                        @foreach ($eventtypes as $eventtype)
                            <option value=" $eventtype->id " >  $eventtype->name  </option>
                        @endforeach
                    </select>
                </div>

                <div class="form-group">
                    <label for="eventsubtype">Sub-tipo</label>
                    <select class="form-control selectsubtypes" name="eventsubtype" id="eventsubtype">
                        @foreach ($eventsubtypes as $eventsubtype)
                            <option value=" $eventsubtype->id " >  $eventsubtype->name  </option>
                        @endforeach
                    </select>
                </div>

                <div class="form-group">
                    <label for="eventsubtype">Temas</label>
                    <span class="interest_text">podes escolher mais que um</span>
                    <div class="interests_list submit_event">
                            @foreach ($themes as $theme)                    
                                <div>
                                    <input type="checkbox" id="theme $theme->id " name="themes[]" value=" $theme->id "/>
                                    <label for="theme $theme->id "><span></span> $theme->name </label>
                                </div>   
                            @endforeach  
                    </div>
                </div>

                <div class="row">
                    <div class="form-group col-md-6">
                        <label for="startdate">Data</label>
                        <input type="date" id="startdate" name="startdate" class="form-control" data-country="PT" placeholder="Início">
                    </div>
                    <div class="form-group col-md-6">
                        <label for="enddate">&nbsp;</label>
                        <input type="date" id="enddate" name="enddate" class="form-control" data-country="PT" placeholder="Fim">
                        <span id="adddata" class="adddata">Adicionar mais horas</span>
                    </div>
                </div>

                <div class="row">
                    <div class="form-group col-md-6">
                        <label for="schedule_start">Horário</label>
                        <input type="date" id="schedule_start" name="schedule_start" class="form-control" data-country="PT" placeholder="Início">
                    </div>
                    <div class="form-group col-md-6">
                        <label for="schedule_end">&nbsp;</label>
                        <input type="date" id="schedule_end" name="schedule_end" class="form-control" data-country="PT" placeholder="Fim">
                        <span id="addschedule" class="addschedule">Adicionar mais horas</span>
                    </div>
                </div>

                <div class="form-group">
                    <label for="duration">Duração</label>
                    <input type="text" id="duration" name="duration" class="form-control" placeholder="Escreve apenas números" />
                    <div class="duration_tips">
                        <input type="radio" id="duration_tips_hours" name="duration_tips[]" value="hours" /><label for="duration_tips_hours"><span></span>Horas</label>
                        <input type="radio" id="duration_tips_weeks" name="duration_tips[]" value="weeks" /><label for="duration_tips_weeks"><span></span>Semanas</label>
                        <input type="radio" id="duration_tips_days" name="duration_tips[]" value="days" /><label for="duration_tips_days"><span></span>Dias</label>
                        <input type="radio" id="duration_tips_months" name="duration_tips[]" value="months" /><label for="duration_tips_months"><span></span>Meses</label>
                    </div>
                </div>

                <div class="form-group">
                    <label for="available">Número de vagas</label>
                    <input type="text" id="available" name="available" class="form-control" placeholder="Escreve apenas números" />
                </div>

                <div class="form-group">
                    <label for="price">Preço</label>
                    <input type="text" id="price" name="price" class="form-control" placeholder="Escreve apenas números" />
                </div>


                <div class="form-group">
                    <label for="email">E-mail</label>
                    <input type="email" id="email" class="form-control" />
                </div>

                <div class="form-group">
                    <label for="telemovel">Telemóvel</label>
                    <input type="text" id="telemovel" class="form-control" />
                </div>

                <div class="form-group">
                    <label for="distrito">Distrito / região</label>
                    <select class="form-control selectdistrict" name="districtID" id="districtID">
                        @foreach ($districts as $district)
                            <option value=" $district->id " >  $district->name  </option>
                        @endforeach
                    </select>
                </div>

                <div class="form-group">
                    <label for="concelho">Concelho</label>
                    <select class="form-control selectcounties" name="countyID" id="countyID">
                        @foreach ($counties as $county)
                            <option value=" $county->id " >  $county->name  </option>
                        @endforeach
                    </select>
                </div>

                <div class="form-group">
                    <label for="morada">Morada</label>
                    <input type="text" id="morada" class="form-control" />
                </div>
                <div class="row">
                    <div class="form-group col-md-6">
                        <label for="freguesia">Freguesia</label>
                        <input type="text" name="parish" id="parish" class="form-control" />
                    </div>

                    <div class="form-group col-md-6">
                        <label for="cod_postal">Código Postal</label>
                        <input type="text" id="cod_postal" class="form-control" />
                    </div>
                </div>

                <div class="form-group">
                    <label for="website">Website</label>
                    <input type="text" id="website" class="form-control" />
                </div>

                <div class="form-group">
                    <label for="facebook">Facebook</label>
                    <input type="text" name="facebooklink" id="facebook" class="form-control" placeholder="www.facebook.com/" />
                </div>

                <div class="form-group">
                    <label for="descricao">Descrição</label>
                    <textarea id="description" name="description" class="form-control descricao_anunciante" placeholder="(quem és, o que fazes ou o que representas, temas e tipos de eventos)"></textarea>
                </div>

                <div class="dropzone" id="myDropzone"> </div>

                <button type="submit" id="submit" class="btn btn-primary">GUARDAR DADOS</button>
                Form::close()

JS

Dropzone.options.myDropzone= 
        url: '/savenewevent',
        autoProcessQueue: false,
        uploadMultiple: true,
        parallelUploads: 5,
        maxFiles: 5,
        maxFilesize: 1,
        acceptedFiles: 'image/*',
        addRemoveLinks: true,
        init: function() 
            dzClosure = this; // Makes sure that 'this' is understood inside the functions below.

            // for Dropzone to process the queue (instead of default form behavior):
            document.getElementById("submit").addEventListener("click", function(e) 
                // Make sure that the form isn't actually being sent.
                e.preventDefault();
                e.stopPropagation();
                dzClosure.processQueue();
            );

            this.on("sendingmultiple", function(data, xhr, formData) 
                formData.append("name", jQuery("#name").val());
                formData.append("eventtype", jQuery("#eventtype").val());
                formData.append("eventtype", jQuery("#eventtype").val());
                formData.append("eventsubtype", jQuery("#eventsubtype").val());
                formData.append("startdate", jQuery("#startdate").val());
                formData.append("enddate", jQuery("#enddate").val());
                formData.append("schedule_start", jQuery("#schedule_start").val());
                formData.append("schedule_end", jQuery("#schedule_end").val());
                formData.append("available", jQuery("#available").val());
                formData.append("price", jQuery("#price").val());
                formData.append("email", jQuery("#email").val());
                formData.append("telemovel", jQuery("#telemovel").val());
                formData.append("districtID", jQuery("#districtID").val());
                formData.append("morada", jQuery("#morada").val());
                formData.append("cod_postal", jQuery("#cod_postal").val());
                formData.append("website", jQuery("#website").val());
                formData.append("facebook", jQuery("#facebook").val());
                formData.append("description", jQuery("#description").val());
            );
        
在同一个请求中发送图像/文件(当我单击提交时我做了一个 var_dump 并且来自 dropzone 的文件不在那里),我该如何实现?

我的目标是在数据库中存储一个带有文件名的序列化数组,所以如果有其他替代方法可以这样做。

谢谢。

【问题讨论】:

var_dump 是什么意思?你在服务器端使用什么? Laravel 5.4, php 据我所见,一切似乎都是正确的,文件和表单数据应该出现在服务器端都在同一个请求中,我不知道 laravel 是如何工作的,但对于纯 php文件应该在$_FILES,表单数据在$_POST 如果我做 print_r($_FILES);它显示了一个空数组。 提交表单时页面是否会重新加载?如果是,尝试一件简单的事情,将 dropzone div 和按钮移到表单外,看看现在文件和数据是否出现在请求中。 【参考方案1】:

要实现这一点,您可以将 dropzone autoProcessQueue 设置为 true,然后在上传文件名后返回文件名作为响应并将其存储在表单输入中。

this.on("success", function (file, response) 
    $('#hidden_input_id').val(response);

当您提交表单时,您将从 #hidden_​​input_id 的名称中获取文件名并将该名称存储到数据库中。

注意:Dropzone ajax/图片上传url和表单提交url应该不同。

示例代码看起来像, html

 Form::open(array('method'=>'post','class'=> 'ajaxaddevent','url' => 
'/savenewevent', 'enctype' => 'multipart/form-data')) 

<input id="hidden_image_name" name="hidden_image_name"

<div class="dropzone" id="myDropzone"> </div>

<button type="submit" id="submit" class="btn btn-primary">GUARDAR DADOS</button>
Form::close()

和脚本之类的,

Dropzone.options.myDropzone= 
    url: '/uploadimage',
    autoProcessQueue: true,
    uploadMultiple: true,
    parallelUploads: 5,
    maxFiles: 5,
    maxFilesize: 1,
    acceptedFiles: 'image/*',
    addRemoveLinks: true,
    init: function() 
        dzClosure = this; // Makes sure that 'this' is understood inside the functions below.

        // for Dropzone to process the queue (instead of default form behavior):
        document.getElementById("submit").addEventListener("click", function(e) 
            // Make sure that the form isn't actually being sent.
            e.preventDefault();
            e.stopPropagation();
            dzClosure.processQueue();
        );

        this.on("success", function (file, response) 
            $('#hidden_image_name').val(response);
        

    
;

/uploadimage 路由应该返回上传的图片文件的名称。

/savenewevent 路由中,您可以检查发布的参数,如果 hidden_​​image_name 不为空,则将该图像名称映射到该事件。

【讨论】:

谢谢,我明白了。但我不知道“注意”部分如何,我如何使用两个不同的网址?可以举个例子吗?

以上是关于Dropzone.JS 在同一个请求中发送文件和表单数据的主要内容,如果未能解决你的问题,请参考以下文章

autoProcessQueue = false在dropzone.js中不起作用

如何限制上传的 dropzone.js 文件的数量?

如何仅使 Dropzone.js 预览 Div 可点击而不是整个表单

使用 NodeJS 进行多部分文件上传

重命名文件选项在 dropzone.js 中不起作用

如何限制 dropzone.js 中的最大“总”文件大小?