Laravel $request->file() returns null


Laravel $request->file() returns null

尝试在后端使用Laravel上传文件时遇到问题。

问题

Laravel $request->file()方法返回 null。

设置

我使用超级代理构建了一个 AJAX 请求,调试了请求,一切似乎都很好。Content-Length根据我添加的图像而变化,表示图像已添加到请求中。Content-Type也设置为 multipart/form-data

// request headers
Content-Length:978599
Content-Type:multipart/form-data; 
// request payload
Content-Disposition: form-data; name="files"; filename="item-keymoment.png"
Content-Type: image/png

但是我无法在拉拉维尔中获取文件。使用 $request->file('files') 返回 NULL ,但是如果我调试 $_FILES 数组,我注意到我的文件已上传。

dd($request->file('files'))
// NULL
dd($_FILES);
// array:1 [
//   "files" => array:5 [
//     "name" => "item-keymoment.png"
//     "type" => "image/png"
//     "tmp_name" => "/tmp/phpipbeeM"
//     "error" => 0
//     "size" => 978274
//   ]
// ]
dd($request->files->all())
// []

是什么原因导致Laravel忽略该文件?
输入文件未application/octet-stream Content-Type

下面回答了这个问题。

您应该添加到表单标签enctype="multipart/form-data"

例如:

<form method="POST" action="{{route('back.post.new')}}" enctype="multipart/form-data">
.............
</form>

添加它,您可以使用自定义请求。

我希望这能帮到你!

注意到我在控制器方法中收到的$request对象是 JsonRequest 的实例,它是一个扩展Illuminate'Http'Request的自定义类(暂时为空)。

它实现为:

<?php
namespace App'Http'Requests;
use Illuminate'Http'Request;
class JsonRequest extends Request {
}

但是如果我改变:

// from
use App'Http'Requests'JsonRequest;
public function add_background_image (JsonRequest $request) {
  dd($request->file('files'))
  // NULL
}
// to
use Illuminate'Http'Request;
public function add_background_image (Request $request) {
  dd($request->file('files'))
  // UploadedFile {#266
  //   -test: false
  //   -originalName: "item-keymoment.png"
  //   -mimeType: "image/png"
  //   -size: 978274
  //   -error: 0
  //   ...
  // }
}

我得到了所需的输入文件。现在切换$request的实例解决了我的问题

但我不明白为什么/如何用空类扩展Illuminate'Http'Request会破坏事情。
有人可以解释一下吗?

我对子类化Illuminate'Http'Request的目的是能够在$requests上附加方法,以便以统一的方式处理API请求的异常/错误。例如,在部署中显示异常消息,但在生产中返回固定消息时。
有没有不同/更好/更Laravel的方式来做到这一点?
我认为只会创建一个 JsonController 而不是扩展请求。

我只在服务器上遇到了这个问题。图像存储在 $_FILES 变量中,该变量指向 php.ini 文件中的物理目录。确保您具有此目录的正确权限。

PHP.ini:

upload_tmp_dir = /Applications/MAMP/tmp/php

检查您的php.ini设置:

  • file_uploads
  • upload_max_filesize
  • max_file_uploads

我把我的关了。我想这会让它悄悄地清除文件。

或者运行php -i | grep --color=always upload以检查当前设置。

我也遇到了这个问题,在表单中添加了enctype="multipart/form-data"部分,尝试了这里发布的所有解决方案......

但就我而言,问题出在javascript上。我正在从另一个输入动态地创建<输入类型"file">,并相互复制 props 文件对象,将其发布到 laravel,然后在 laravel 中$request->input 为空:

$('#take-picture').on('change', function (){
 let props = $(this).prop('files');
 ...
 let $input = $('<input type="file" class="d-none" />');
 $input.prop('name', 'image_one').prop('files', props);
 $(this).val(''); //This is the problem in my case
 ...
 $form.append($input);
 $form.submit();

问题出在这一行:

$(this).val('');

因为我正在获取 props 对象并将其分配给创建的输入,并将其设置为 null 以删除原始输入中的选定值。 但是这个对象是通过引用获得的,所以当我从原始输入中选择它时,我也从新创建的输入中删除了它,所以在发布表单时, 拉拉维尔得到了空。

所以解决方案只是获取 props 对象的克隆并使用它(我使用该解决方案克隆了此答案中发布的 FileList:是否可以更新文件列表?

let props = $(this).prop('files')
...
let cloneProps = new FileListItems(props);
$input.prop('name', 'image_' + image_index).prop('files', cloneProps)

希望它对某人有所帮助!