如何解决AdonisJS上传文件时request.file()返回null的问题
AdonisJS 上传图片 request.file() 返回 null 修复方案
问题根因
- 表单缺失
enctype="multipart/form-data"属性:上传文件的表单必须指定该编码类型,否则浏览器只会以普通表单格式传输参数,不会携带二进制文件内容,后端自然无法读取到文件 - 单/多文件处理逻辑不匹配:表单文件输入框加了
multiple属性支持多文件上传,但后端用了单文件读取方法request.file(),且单文件场景错用了仅适用于多文件的moveAll方法 - 控制器逻辑错误:直接用
request.only()返回的普通对象调用save()方法,该方法只有ORM模型实例才具备,会触发后续报错
修改方案
1. 修正表单代码
给form标签增加编码类型声明,若无需上传多个头像可删除multiple属性,修改后代码如下:
<form class="uk-grid-small" uk-grid method="post" action="{{ route('profiles.update', {id: user.id}) }}?_method=PUT" enctype="multipart/form-data"> <div class="uk-width-1-2@s"> <input class="uk-input" type="text" placeholder="Fullname" name="fullname"> </div> <div class="uk-width-3-4@s"> <label>Upload user avatar</label> <input type="file" name="avatar" class="form-control"> </div> <div class="uk-width-1-2@s"> <button class="uk-button uk-button-primary">Submit</button> </div> </form>
2. 修正控制器代码
先查询用户模型实例,调整文件操作方法,补充异常判断,修改后代码如下:
// 顶部先引入User模型和Application import User from 'App/Models/User' import Application from '@ioc:Adonis/Core/Application' public async update({response, request, params}) { // 先根据路由参数的id查询对应要更新的用户 const user = await User.findOrFail(params.id) const payload = request.only(["fullname"]); const coverImage = request.file('avatar', { size: '2mb', extnames: ['jpg', 'png', 'jpeg'], }) if (!coverImage) { return "Please upload File" } const imageName = new Date().getTime().toString()+ '.' + coverImage.subtype // 单文件用move方法,不要用moveAll await coverImage.move(Application.publicPath('images'),{ name: imageName }) // 判断文件是否移动成功 if (!coverImage.isMoveSuccessful) { return coverImage.errors() } // 合并更新字段 user.fullname = payload.fullname user.avatar = `images/${imageName}` await user.save() return response.redirect(`/users/${user.id}`) }
3. 可选检查项
- 确认项目
public/images目录存在,且运行Node服务的用户对该目录有读写权限 - 检查
config/bodyparser.ts配置中multipart相关限制是否放开,默认的文件大小、后缀限制是否拦截了你上传的文件
内容的提问来源于stack exchange,提问作者DMcC406
相关产品推荐
相关产品推荐

