You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 06:43:57