Azure中Node.js函数实现文件上传报错求助
解决Azure Functions Node.js文件上传的
req.on is not a function错误 这个错误的核心原因很明确:你传入formidable的request对象不是标准的Node.js IncomingMessage请求对象。Azure Functions对HTTP请求做了封装,这个封装后的对象没有formidable依赖的on事件监听方法,所以会抛出TypeError。
另外,你原代码还有一个隐藏问题:把context.done()放在了form.parse的异步回调外面,这会导致函数在文件解析完成前就提前终止,即使没有报错也无法正确返回结果。
下面给你两种可行的解决方案:
方案一:使用Azure Functions内置的文件上传处理(推荐)
Azure Functions已经内置了对multipart/form-data请求的解析,不需要额外依赖formidable。你可以直接通过req.files访问上传的文件:
module.exports = function (context, req) { context.log('JavaScript HTTP trigger function processed a request.'); // 检查是否有上传的文件 if (req.files && Object.keys(req.files).length > 0) { // 获取第一个上传的文件(如果有多个文件可以遍历处理) const [fileKey] = Object.keys(req.files); const uploadedFile = req.files[fileKey]; // 这里可以处理文件内容,比如读取buffer // const fileContent = uploadedFile.buffer; context.res = { body: `文件 ${uploadedFile.name} 上传成功,大小:${uploadedFile.size} bytes` }; } else { context.res = { status: 400, body: "请上传至少一个文件" }; } context.done(); };
方案二:强制使用formidable(适配Azure的请求对象)
如果你一定要用formidable,需要把Azure封装的请求对象转换成它能识别的可读流。我们可以利用req.rawBody(请求原始内容的Buffer)创建一个可读流,再手动传入请求头让formidable解析边界:
var formidable = require("formidable"); const { Readable } = require('stream'); module.exports = function (context, req) { context.log('JavaScript HTTP trigger function processed a request.'); // 将rawBody转换为可读流 const requestStream = new Readable(); requestStream.push(req.rawBody); requestStream.push(null); // 标记流结束 const form = new formidable.IncomingForm(); // 传入流和请求头,让formidable正确解析multipart数据 form.parse(requestStream, { headers: req.headers }, function (err, fields, files) { if (err) { context.res = { status: 500, body: `文件解析失败:${err.message}` }; } else { context.res = { body: `上传成功!\n字段信息:${JSON.stringify(fields)}\n文件信息:${JSON.stringify(files)}` }; } // 必须在异步回调内调用context.done(),确保函数在处理完成后再终止 context.done(); }); };
关键注意事项
- 永远不要在异步操作(比如
form.parse)的回调外面调用context.done(),否则Azure会提前终止函数,导致异步逻辑无法完成。 - 方案一的代码更简洁,也更符合Azure Functions的设计理念,优先推荐使用。
内容的提问来源于stack exchange,提问作者Prashant Ambardekar
相关产品推荐
相关产品推荐

