如何在Sails.js中使用新版控制器动作格式上传文件
解决Sails.js控制器动作中使用(inputs, exits)格式上传文件的问题
你遇到的inputs.file不是函数错误,核心原因是Sails.js中处理文件上传的file()方法属于请求对象(req),而不是inputs对象。你错误地在inputs上调用了这个方法,这才导致报错。
接下来给你修正后的完整代码,我会详细解释关键改动:
module.exports = { friendlyName: 'Upload file recording', description: 'Upload a recording to AWS', inputs: { name: { required: true, type: 'string' }, mimeType: { required: true, type: 'string' }, // 注意:这里不需要定义recording为ref类型,文件通过req.file处理 }, exits: { noRecordings: { responseType: 'no recordings', description: `You don't have any recording for this event`, }, serverError: { responseType: 'server error', description: `Failed to upload the file`, } }, fn: async function (inputs, exits) { try { // 关键:通过this.req获取请求对象,调用file()方法 const filesUploaded = await new Promise((resolve, reject) => { this.req.file('recording').upload({ adapter: require('skipper-s3'), key: process.env.AWS_S3_KEY, secret: process.env.AWS_S3_SECRET, bucket: process.env.AWS_S3_BUCKETNAME }, function (err, files) { if (err) return reject(err); resolve(files); }); }); // 获取所有参数(包括inputs里的name、mimeType) const textParams = { ...inputs, ...this.req.allParams() }; return exits.success({ files: filesUploaded, textParams: textParams }); } catch (err) { return exits.serverError(err); } } };
关键改动说明:
- 获取请求对象:在Sails的控制器动作中,
this上下文包含当前请求的req对象,所以要用this.req.file('recording')来获取上传的文件字段,而不是inputs.file。 - Promise化上传回调:因为你的
fn是async函数,把原本的回调式upload操作包装成Promise,这样可以用await处理,避免回调地狱,也更符合async/await的编码风格。 - 移除无效的inputs定义:
inputs里的recording字段不需要定义为ref类型,因为文件上传的字段是通过req.file处理的,不是通过常规的参数解析。 - 整合参数:用
{ ...inputs, ...this.req.allParams() }来整合预验证过的inputs(name、mimeType)和其他请求参数,确保拿到完整的参数集合。
另外还要注意几个细节:
- 确保你已经正确安装了
skipper-s3依赖:npm install skipper-s3 --save - 确认AWS的密钥、Bucket名称等环境变量已经正确配置,并且拥有对应的S3上传权限。
内容的提问来源于stack exchange,提问作者agonza1
相关产品推荐
相关产品推荐

