Laravel 5.1:将上传的文件保留为旧输入

时间:2015-10-15 20:51:48

标签: php laravel laravel-5

我正在使用Laravel 5.1中的表单发布一些文本并上传文件。它看起来像这样(简化版):

{!! Form::open(array('url' => 'foo/bar')) !!}
    {!! Form::text('image_name') !!}
    {!! Form::file('image') !!}
    {!! Form::submit('Submit!') !!}
{!! Form::close() !!}

文本字段是必需的,因此我在控制器中添加了$validator。如果验证失败,则会将用户重定向回表单。我使用withInput()方法重新填充表单,以便用户不必再次填写表单:

if ($validator->fails()) {
    return redirect()->back()->withInput();
}

这将为文本字段,下拉列表等返回旧输入。但是,如果用户上传了文件,则在验证失败时必须再次选择文件选择。 Laravel有没有办法记住文件选择作为旧输入?

谢谢!

3 个答案:

答案 0 :(得分:37)

不,Laravel或任何软件都无法预先填充file输入。您的网站(和任何网站)不会也不应该知道该文件的本地路径。如果他们这样做,想象一下安全隐患!您可以欺骗用户上传他们的SSH私钥或其他东西。

您需要做的是处理上传的文件,即使存在验证错误也是如此。

然后,您可以将其存储在具有pending状态的数据库中,或者为其分配一些唯一的hash,并在用户的会话中存储匹配的hash。关键是能够识别属于该特定用户的不完整上传。

然后,当您显示表单时,从会话或数据库中检索这些不完整的文件,并在文件上载旁边显示缩略图。这告诉用户他们不需要重新上传该文件。只要确保他们有办法将其删除,以防他们改变主意。

正确提交表单后,请清除会话hash或将数据库状态更新为complete;无论你需要做什么。

答案 1 :(得分:6)

对于同一问题似乎存在很多问题(Form::file: How to repopulate with Input::old After Validation Errors and/or on Update?),并且每个有明显知识的人都说这是不可能的。

我会提出一个涵盖以下目标的解决方法

  • 在Laravel验证失败的情况下保留表单数据和文件输入
  • 仅使用服务器端验证。你不需要不应该使用javascript验证。

这一切的关键字是 AJAX 。我会做以下事情:

2017年12月更新:通过单个AJAX POST

发送所有字段和附件
  1. 创建一个AJAX表单(方法 GET POST ),其中包含 包括文件输入之外的所有内容。请记住,它需要发送 Laravel CSRF令牌
  2. 在控制器验证中,您需要做出响应(失败或成功)以生成JSON输出,因此您的AJAX发送代码可以在任何情况下获得响应,然后您可以在浏览器中显示它
  3. 这样可以避免服务器中的文件处于任何时态状态。

    此过程的一个更复杂但改进的版本,如果您担心使用的带宽并且您希望输入字段中出现错误将非常常见,您可能会做两个(或更多)AJAX POST验证:第一个仅包含输入字段,如果没问题,则发送所有字段(再次输入字段,现在包括附加文件)以再次尝试验证,并在成功时对所有数据执行操作。

答案 2 :(得分:1)

如果文件是图像,则可以创建隐藏的输入,并在用户上传图像时在其中输入 base64 字符串

{!! Form::open(array('url' => 'foo/bar')) !!}
{!! Form::text('image_name') !!}
{!! Form::hidden('base64_image') !!}
{!! Form::file('image') !!}
{!! Form::submit('Submit!') !!}
{!! Form::close() !!}