Я использую 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);
}
..
}
Проблема 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
обратный звонок я включил в мое предыдущее обновление.
Других решений пока нет …