无法将附加文件传递给控制器:422 无法处理的实体
Unable to pass attached files to controller: 422 Unprocessable Entity
我正在使用 Dropzone js 处理多个文件上传。但是,文件不会传递给控制器。通过为 CSRF 令牌添加 header 代码解决 419 post 错误后,出现 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);
}
..
}
问题 1
您的提交处理程序选择器是 #submit-all
:
$("#submit-all").click(function (e) {
但您的按钮没有该 ID(其他任何东西也没有):
<button type="submit" class="btn btn-primary">
所以您的提交处理程序永远不会被触发,这意味着 processQueue()
永远不会被调用,所以实际上没有文件被 POSTed。
问题2
您尝试将文件附加到 formData
的下一个问题,但它们已经存在 - 这就是 processQueue()
所做的。您可以完全删除 sending
事件处理程序。
问题3
The uploaded files can be handled just as if there would have been a html input like this: <input type="file" name="file" />
所以在你的控制器中,你应该寻找一个名为 file
的输入,而不是 files
:
foreach ($r->file('file') as $file) {
问题4
接下来,在您的 success
回调中,您正尝试以 e
的身份访问 Javascript 事件和上传的 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);
});
解决了这些问题中的每一个,我让您的代码在我的本地环境中正常工作。
另一件事,我不确定它是否只是这里的错字,或者你的代码中是否真的有这个,但是你在 [=28] 之间的后备文件输入中缺少 space =] 及其 id
,这可能会在需要时将其搞乱:
multiple="multiple"id="fileUpload"
更新以回答新问题 5
对于您的新问题,419
通常是因为您的 CSRF 令牌检查失败。 SO 上有几个带有解决方案的示例: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 正在处理文件,没有别的,所以您的验证自然会失败。
在这种情况下,您需要在 POST 中包含其他字段。您可以通过将它们附加到 formData
来实现,如上次更新中包含的 sending
回调所示。
我正在使用 Dropzone js 处理多个文件上传。但是,文件不会传递给控制器。通过为 CSRF 令牌添加 header 代码解决 419 post 错误后,出现 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);
}
..
}
问题 1
您的提交处理程序选择器是 #submit-all
:
$("#submit-all").click(function (e) {
但您的按钮没有该 ID(其他任何东西也没有):
<button type="submit" class="btn btn-primary">
所以您的提交处理程序永远不会被触发,这意味着 processQueue()
永远不会被调用,所以实际上没有文件被 POSTed。
问题2
您尝试将文件附加到 formData
的下一个问题,但它们已经存在 - 这就是 processQueue()
所做的。您可以完全删除 sending
事件处理程序。
问题3
The uploaded files can be handled just as if there would have been a html input like this:
<input type="file" name="file" />
所以在你的控制器中,你应该寻找一个名为 file
的输入,而不是 files
:
foreach ($r->file('file') as $file) {
问题4
接下来,在您的 success
回调中,您正尝试以 e
的身份访问 Javascript 事件和上传的 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);
});
解决了这些问题中的每一个,我让您的代码在我的本地环境中正常工作。
另一件事,我不确定它是否只是这里的错字,或者你的代码中是否真的有这个,但是你在 [=28] 之间的后备文件输入中缺少 space =] 及其 id
,这可能会在需要时将其搞乱:
multiple="multiple"id="fileUpload"
更新以回答新问题 5
对于您的新问题,419
通常是因为您的 CSRF 令牌检查失败。 SO 上有几个带有解决方案的示例: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 正在处理文件,没有别的,所以您的验证自然会失败。
在这种情况下,您需要在 POST 中包含其他字段。您可以通过将它们附加到 formData
来实现,如上次更新中包含的 sending
回调所示。