0

我正在使用 Dropzone js 处理多个文件上传。但是,文件不会传递给控制器​​。通过添加 CSRF 令牌的标头代码解决 419 发布错误后,出现 422 无法处理的实体错误。

根据网络日志的响应,它似乎影响了我之前工作正常的其他字段的验证。

{"message":"The given data was invalid.","errors":{"item-name.0":["The item-
name.0 field is required."],"item-quantity.0":["Please Enter Item 
Quantity."],"availableStartDate":["The available start date field is 
required."],"availableEndDate":["The available end date field is 
required."],"preferredTime":["The preferred time field is required."]}}

这是 Blade 文件顶部的 Javascript 代码。

 <script type="text/javascript">
    Dropzone.autoDiscover = false;
    $(document).ready(function () {
        new Dropzone('#fileInput', {
            autoProcessQueue: false,
            uploadMultiple: true,
            parallelUploads: 1000,
            maxFiles: 100,
            acceptedFiles: ".jpeg,.jpg,.png,.gif",
            url: '/make-a-donation',
            addRemoveLinks:true,
            headers: {
                'X-CSRFToken': $('meta[name="token"]').attr('content')
            },

            init: function () {

                var myDropzone = this;
                var wrapperThis = this;
                $("#submit-all").click(function (e) {
                    e.preventDefault();
                    myDropzone.processQueue();
                });

                //Removed sending and success functions respectively

            }
        });
    });
</script>

以下是 HTML 代码:

<form class="form-horizontal myForm" method="POST" files="true" action="{{ 
route('postdonation') }}"  enctype="multipart/form-data">
{{ csrf_field() }}

 <div class="col-md-12">

             <div id="fileInput" class="dropzone">
             <div class="fallback">
             <!--replaced files[] to file-->
             <input name="file" type="file" multiple="multiple" id="fileUpload"/>
             </div>
             </div>
</div>

....

<div class="form-group">
     <div class="col-md-6 col-md-offset-4">
           <button type="submit" id="submit-all" class="btn btn-primary">
               insert
            </button>
      </div>
 </div>
 ...
 </form>

在控制器处,

   public function store(CreateDonationDetailsRequest $r) {

   //Inserting other data in the form
   .....

  //Previously $r->file('files') as $file to
    foreach ($r->file('file') as $file) {
        $donationImages = new DonationImages();

        // Set the destination path
        $destination = '/donationImagesUpload/';
        // Get the orginal filname or create the filename of your choice
        $filename = $file->getClientOriginalName();

        // Copy the file to the destination folder
        $file->move(public_path($destination), $filename);

        //Insert file name to database
        $donationImages->donation_items_id = $donationItems->id;
        $donationImages->photoName = $filename;

        //Save images to database
        $donationItems->donationImages()->save($donationImages);

    }

    ..
}
4

1 回答 1

1

问题 1

您的提交处理程序选择器是#submit-all

$("#submit-all").click(function (e) {

但是您的按钮没有该 ID(也没有其他任何东西):

<button type="submit" class="btn btn-primary">

所以你的提交处理程序永远不会被触发,这意味着processQueue()永远不会被调用,所以实际上没有文件被发布。

问题 2

您尝试将文件附加到的下一个问题formData,但它们已经存在 - 就是processQueue()这样。您可以完全删除您的sending事件处理程序。

问题 3

接下来,来自 Dropzone 文档

可以像处理这样的 html 输入一样处理上传的文件: <input type="file" name="file" />

所以在你的控制器中,你应该寻找一个名为的输入file,而不是files

foreach ($r->file('file') as $file) {

问题 4

接下来,在您的success回调中,您尝试将 Javascript 事件访问为e,并且上传的事件file都没有在此处定义,因此会引发错误。 根据文档,POST 响应可用作第二个参数,但我不确定第一个是什么(控制台日志显示它是某种 Dropzone 对象)。

请注意,文档还说:

不要将它们作为配置选项覆盖,除非您知道自己在做什么。

我会success完全删除该回调。如果您想在成功上传后删除文件,文档会准确显示如何执行此操作

myDropzone.on("complete", function(file) {
  myDropzone.removeFile(file);
});

解决了这些问题中的每一个,我让您的代码在我的本地环境中正常工作。

另一件事,我不确定这是否只是 SO 上的一个错字,或者你的代码中是否真的有这个,但是你的后备文件输入中缺少一个空格multipleid这可能会在这种情况下搞砸需要时:

multiple="multiple"id="fileUpload"

更新回答新问题 5

对于您的新问题,419通常是因为您的 CSRF 令牌检查失败。这里有几个关于 SO 的解决方案示例:示例 1示例 2

对于我自己的一个项目,我使用 Dropzonesending回调在 POSTed 数据中包含其他表单输入:

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

更新回答新问题 6

对于您的新问题:

现在它导致另一个错误:422 unprocessable entity

对于未通过验证的 AJAX 请求, Laravel 返回 422

因此,听起来您 a) 表单中的字段比您显示的要多,并且 b) 对它们进行验证。目前,您只发布文件,没有其他内容,因此您的验证自然会失败。

在这种情况下,您需要在 POST 中包含其他字段。您可以通过将它们附加到 来做到这一点,如我在之前更新中包含formData的回调中所示。sending

于 2017-10-08T10:35:30.697 回答