javascript — Невозможно передать вложенные файлы в контроллер: 422 Unprocessable Entity

Я использую Dropzone JS для обработки нескольких загрузок файлов. Однако файлы не передаются в контроллер. После устранения ошибки 419 после добавления кода заголовка для токена CSRF появилась ошибка 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."]}}

Вот коды Javascript в верхней части файла Blade.

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

}

..
}

0

Решение

Проблема 1

Ваш селектор обработчика отправки #submit-all:

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

Но у вашей кнопки нет этого идентификатора (и ничего другого):

<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 доступен как 2-й параметр, но я не уверен, что 1-й является (консольный журнал показывает, что это какой-то объект Dropzone).

Обратите внимание, что документы также говорят:

Не перезаписывайте их как параметры конфигурации, если вы не знаете, что делаете.

Я бы убрал это success Обратный звонок полностью. Если вы хотите удалить файл после успешной загрузки, документы показывают, как именно это сделать:

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

Исправляя каждую из этих проблем, я получил ваш код, работающий правильно в моей локальной среде.

Другое дело, я не уверен, является ли это просто опечаткой здесь, на SO, или если вы действительно имеете это в своем коде, но вам не хватает пробела во входном файле резервной копии между multiple И его idчто, вероятно, испортило бы это в случае, когда это необходимо:

multiple="multiple"id="fileUpload"

ОБНОВЛЕНИЕ, чтобы ответить на новую проблему 5

Для вашей новой проблемы, 419 как правило, bcs проверка вашего токена CSRF не удалась. Есть несколько примеров с решениями здесь на SO: пример 1, пример 2

Для одного из моих собственных проектов я использую Dropzone sending обратный вызов для включения других входных данных формы в данные POST:

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 необработанного объекта

Laravel возвращает 422 для запроса AJAX, который не проходит проверку.

Похоже, у вас есть а) больше полей в форме, чем вы показали, и б) проверка на них. В настоящее время вы только отправляете файл, ничего больше, поэтому, естественно, ваша проверка не удастся.

В этом случае вам нужно будет включить другие поля в ваш POST. Вы можете сделать это, добавив их к formDataкак показано выше в sending обратный звонок я включил в мое предыдущее обновление.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]