javascript - 无法将附加文件传递到 Controller : 422 Unprocessable Entity

标签 javascript php laravel laravel-5 dropzone

我正在使用 Dropzone js 来处理多个文件上传。但是,文件不会传递到 Controller 。通过添加 CSRF token 的 header 代码解决 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>

在 Controller 处,

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

    }

    ..
}

最佳答案

问题1

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

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

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

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

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

问题2

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

问题3

下一步,from the Dropzone docs :

The uploaded files can be handled just as if there would have been a html input like this: <input type="file" name="file" />

因此,在您的 Controller 中,您应该寻找名为 file 的输入,不是files :

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

问题4

接下来,在您的 success 中回调,您正在尝试访问 Javascript 事件 e ,以及上传的file但这些都没有定义,所以会抛出错误。 According to the docs ,POST 响应可用作第二个参数,但我不确定第一个参数是什么(控制台日志显示它是某种 Dropzone 对象)。

请注意,文档还说:

Do not overwrite those as configuration options, unless you know what you're doing.

我会删除 success回调完全。如果您想在上传成功后删除文件,the docs show exactly how to do that :

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

解决了所有这些问题后,我就让您的代码在我的本地环境中正常工作了。

另一件事,我不确定这是否只是这里的拼写错误,或者您的代码中是否确实有这个,但您的后备文件输入中缺少 multiple 之间的空格。及其 id ,这可能会在需要时弄乱它:

multiple="multiple"id="fileUpload"

更新以回答新问题 5

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

对于我自己的项目之一,我使用 Dropzone sending回调以在 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

对于您的新问题:

Now it leads to another error: 422 unprocessable entity

Laravel returns 422对于验证失败的 AJAX 请求。

所以听起来您 a) 表单中的字段比您显示的要多,并且 b) 对它们进行了验证。目前,您只是发布文件,没有其他任何操作,所以您的验证自然会失败。

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

关于javascript - 无法将附加文件传递到 Controller : 422 Unprocessable Entity,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46628705/

相关文章:

javascript - Route.post() 需要一个回调函数,但得到一个 [object String]

php - Oauth API 客户端出现错误

php - 使用 eloquent ORM 在 Laravel 中进行批量插入

php - 获取消息的 MIME 版本会导致 "405 Method Not Allowed"- 错误

mysql - PHP SQLSTATE[42000] 语法错误或访问冲突 : 1064 in query

laravel - 使用Laravel计算页面浏览量

javascript - 这些不同样式的 "pop up"框的正确术语是什么以及如何实现它们?

javascript - 谷歌地图在 IE7 中不工作

javascript - 添加验证以在用户忘记某个值并收到第二个和第三个值为空的错误时通知用户

php - Getting L_ERRORCODE0=10001&超时处理请求