Laravel 5.5 AJAX文件上传异常:$_FILES可获取但$request->file()失效
解决Laravel 5.5中AJAX文件上传$request无法获取文件的问题
我之前也碰到过一模一样的情况,结合你的代码和返回结果来看,问题主要出在CSRF令牌缺失和Laravel文件获取方式不正确这两点上,下面一步步帮你搞定:
1. 为什么$_FILES能拿到但Laravel Request不行?
PHP原生的$_FILES是全局变量,只要请求是合法的multipart/form-data类型就能直接读取;但Laravel的Request对象会先经过中间件处理(比如CSRF验证),如果验证不通过或者请求数据没被正确解析,就会导致文件无法通过$request获取。你的返回结果里$request->all()的pic是空数组,大概率是因为请求没带CSRF令牌,导致Laravel没正确解析请求里的文件数据。
2. 解决方案步骤
步骤1:给AJAX请求添加CSRF令牌
Laravel默认开启CSRF保护,所有POST请求(包括AJAX)都得带CSRF令牌,你可以二选一添加:
方式一:在表单里直接加入CSRF字段
修改你的HTML表单,加上Laravel的CSRF字段:
<html> <form id="testForm"> {{ csrf_field() }} <!-- 新增这一行 --> <input type="file" id="pic" name="pic"> <button type="submit">upload</button> </form> </html>
这样new FormData($(this)[0])会自动把_token字段包含进去。
方式二:在AJAX里手动追加令牌
如果不想改表单,可以在构建FormData时手动加令牌:
<script type="text/javascript"> $(function () { $("#testForm").submit(function (event) { event.preventDefault(); var formData = new FormData($(this)[0]); formData.append('_token', '{{ csrf_token() }}'); // 手动追加CSRF令牌 $.ajax({ type: "post", url: "http://localhost/yhy-admin/public/index.php/admin_api/upload", data: formData, processData: false, contentType: false, cache: false, success: function (res) { console.log(res); } }); }); }); </script>
步骤2:用Laravel正确的方法获取文件
Laravel中获取上传文件得用$request->file('字段名')方法,不能直接用$request->pic(后者是用来拿普通文本输入的)。修改你的控制器代码:
public function upload(Request $request) { $data["content"]["pic"] = $request->file('pic'); // 使用file()方法获取文件 $data["content"]["pic_file"] = $_FILES; $data["content"]["all"] = $request->all(); // 还可以额外判断文件是否存在 if ($request->hasFile('pic')) { $data["content"]["file_exists"] = true; // 这里还能加文件验证,比如限制类型和大小 // $request->validate(['pic' => 'image|max:2048']); } else { $data["content"]["file_exists"] = false; } return $data; }
步骤3:检查路由中间件
确保你的路由所在的中间件组正确:
- 如果是后台管理路由,建议放在
web中间件组下(需要CSRF令牌); - 如果是API路由,放在
api中间件组下,但要注意api组默认无CSRF保护,不过得确保请求的Content-Type是对的。
验证结果
改完之后重新测试上传,你会发现$request->file('pic')能正确拿到上传的文件对象,$request->all()里的pic也不再是空数组了。
内容的提问来源于stack exchange,提问作者xin liang
相关产品推荐
相关产品推荐

