无法将附件传递给控制器:422 Unprocessable Entity
Posted
技术标签:
【中文标题】无法将附件传递给控制器:422 Unprocessable Entity【英文标题】:Unable to pass attached files to controller: 422 Unprocessable Entity 【发布时间】:2018-03-19 14:46:43 【问题描述】:我正在使用 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);
..
【问题讨论】:
表格enctype
?
@skido 已经在表单标签处添加了 enctype="multipart/form-data"
@Enovyne 我的更新有帮助吗?
@Don't Panic 之类的。现在它导致另一个错误:422 unprocessable entity。
现在您只发布文件。如果您在此表单中有其他字段,并且它们是验证所必需的,则需要在您发布的数据中包含这些值。您可以使用我上次更新中包含的 sending
回调来做到这一点。
【参考方案1】:
问题 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:
可以像处理这样的 html 输入一样处理上传的文件:
<input type="file" name="file" />
因此,在您的控制器中,您应该寻找一个名为 file
的输入,而不是 files
:
foreach ($r->file('file') as $file)
问题 4
接下来,在您的success
回调中,您尝试以e
和上传的file
访问Javascript 事件,但它们都没有在那里定义,因此会引发错误。 According to the docs,POST 响应可用作第二个参数,但我不确定第一个是什么(控制台日志显示它是某种 Dropzone 对象)。
请注意,文档也说:
除非您知道自己在做什么,否则不要将它们覆盖为配置选项。
我会完全删除 success
回调。如果要上传成功后删除文件,the docs show exactly how to do that:
myDropzone.on("complete", function(file)
myDropzone.removeFile(file);
);
解决了这些问题,我让您的代码在我的本地环境中正常工作。
另一件事,我不确定这是否只是 SO 上的一个错字,或者你的代码中是否真的有这个,但你在multiple
和它的id
之间的后备文件输入中缺少一个空格,在需要的情况下可能会搞砸:
multiple="multiple"id="fileUpload"
更新以回答新问题 5
对于您的新问题,419
通常是因为您的 CSRF 令牌检查失败。 SO上有几个解决方案示例:example 1,example 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 unprocessable entity
Laravel returns 422 用于验证失败的 AJAX 请求。
所以听起来您 a) 表单中的字段比您显示的要多,并且 b) 对它们进行验证。目前,您只是发布文件,没有其他内容,因此您的验证自然会失败。
在这种情况下,您需要在 POST 中包含其他字段。您可以通过将它们附加到formData
来做到这一点,如上一次更新中包含的sending
回调所示。
【讨论】:
我无意中在提交按钮上省略了提交全部 ID。即使有 id,它也只是停留在页面上。加载资源失败:服务器响应状态为 419(未知状态) 有几个问题,我已经更新了我的答案来解决所有这些问题。 感谢您的意见@Don't Panic。我在这里更新了我当前的代码,因为我仍然面临同样的问题。 @Enovyne 您更新的代码对我有用,尽管我没有测试您的控制器代码,只是文件已正确发布并且服务器接收到预期的数据。"display argument supplied for foreach()"
不是我见过的错误信息,也没有出现在 Google 中。它真的是你所看到的,以及抛出它的东西,php 还是 JS?另外,您确定正在使用正确的控制器/方法吗?浏览器开发工具显示什么(检查网络和控制台)?
错误消息“为 foreach() 提供的参数不再显示。”那是针对PHP代码的。在控制台中,显示加载资源失败:服务器响应状态为 419(未知状态),这很奇怪。它只是停留在页面上。以上是关于无法将附件传递给控制器:422 Unprocessable Entity的主要内容,如果未能解决你的问题,请参考以下文章
无法将 iframe 元素从指令传递给 Angular 控制器
无法识别的选择器发送到实例...使用 segues 将字符串传递给另一个视图控制器