node中multiparty模块使用form.parse解析上传文件时回调函数参数files获取为空对象

发布于 2022-09-11 14:36:01 字数 5318 浏览 7 评论 0

问题描述

我创建了一个简单的文件上传提交项目,server端使用node,前端使用formdata整合上传表单数据,JQuery的ajax向后端提交请求。
在node端,使用multiparty模块的form.parse解析上传文件,但在打印它的回调files,出现了files是空对象的情况,但文件上传到本地指定目录已经成功了,求大神帮帮忙!!

相关代码

// 请把代码文本粘贴到下方(请勿用图片代替代码)
html 表单:

<form action="" method="POST" enctype="multipart/form-data" id="form1">
            <p class="diskName">
                请输入中文名称:<input type="text" name="diskName-CH"value=""></br>
            </p>
            <p class="l1">请选择所需生成图片端:</p>
            <select name="port" id="port">
                <option value="android">Android</option>
                <option value="pc">PC</option>
                <option value="mac">Mac</option>
                <option value="iphone">Iphone</option>
                <option value="ipad">Ipad</option>
            </select>
            <p class="l2">
                请上传图片white.png:<input type="file" id="white" name="white" value="请上传图片" />
                请上传图片 gray.png:<input type="file" id="gray" name="gray" value="请上传图片" />
                请上传图片 1024.png:<input type="file" id="1024" name="1024" value="请上传图片" />
            </p>
            <input type="button" value="提交" id="subPic">
</form>

JS部分:

var $box=$("#box"),
        $cloudName=$box.find(".diskName input"),//获取表单对象
        $select=$box.find("select"),//获取select选择图片输出端
        $pic=$box.find("form .l2 input"),//获取上传的三张图片
        $subPic=$box.find("#subPic");//提交按钮
    



    $subPic.on('click',function(){

        //获取名称等表单信息
        $name=$cloudName.val(),
        $port=$select.val();

        var pic1 = $pic.eq(0)[0].files[0],//获取white.png路径名
        pic2 = $pic.eq(1)[0].files[0],//获取gray.png路径名
        pic3 = $pic.eq(2)[0].files[0];//获取1024.png路径名



        //如果三个文件均未上传则提示未选择任何文件
        if(!pic1&&!pic2&&!pic3){//如果未选择任何文件,则获取到的pic为undefined
            alert("您未选择任何图片文件上传!请选择");
            return ;
        }


        //如果三个文件中任一文件扩展名非.png则提示并结束回调
        //获取上传文件的扩展名
        var isPng=[];//创建数组isPng
        for(var i=0;i<$pic.length;i++)
        {
            if($pic.eq(i)[0].files[0]){
                var index=$pic[i].value.lastIndexOf('.');
                isPng.push($pic[i].value.substring(index));
            }
        }
        console.log(isPng);
        for(var key in isPng){
            if(isPng[key]!='.png'){
                alert("上传的图片中存在非png格式图片!!请重新选择");
                return ;
            }
        }

        var formData = new FormData();//开始添加数据
        formData.append('name',$name);
        formData.append('port',$port);
        formData.append('file[]',pic1);
        formData.append('file[]',pic2);
        formData.append('file[]',pic3);//叠加成数组,传给server

        //ajax传输数据到node server
        $.ajax({
            type: 'POST',
            url: "http://127.0.0.1:8080/uploadimgs",
            data:formData, 
            dataType: "json", //声明成功使用json数据类型回调
            //如果传递的是FormData数据类型,那么下来的三个参数是必须的,否则会报错
            cache:false,  //默认是true,但是一般不做缓存
            processData:false, //用于对data参数进行序列化处理,这里必须false;如果是true,就会将FormData转换为String类型
            contentType:false,  //一些文件上传http协议的关系,如果上传的有文件,那么只能设置为false
            success: function(msg){
                console.log(msg);
                console.log('文件上传成功');
                //alert('文件上传成功');
                },
            error:function(){
                console.log('ajax请求失败!');
            }
            });
    });

server获取files部分:

//这里参数files获取是空对象,而fields成功获取(即ajax传输的$name和$port)
form.parse(ctx.req,function(err,fields,files){
                if(err){
                    send_json={
                        exception:"解析失败",
                        err:false
                    };
                    resolve(send_json);
                    // return send_json;
                }else{
                
                
                   //files.file是undefined
                    console.log("files.file:"+files.file);
                    if(files!==undefined&&files!=={}&&files.file!==undefined){
                        console.log("files.upload.path:"+files.upload.path);
                        if(files.file.length>0){
                            let filename = files.file[0].path;
                            let filetype = files.file[0].headers['content-type'];
                            let realname = files.file[0].originalFilename;
                             console.log("filename = "+filename);
                             console.log("filetype = "+filetype);
                             console.log("realname = "+realname); 
                        }
                    }else{
                    }
                }
            });

你期待的结果是什么?实际看到的错误信息又是什么?

在获取form.parse的回调函数files参数后,打印类型是Object,但使用for in打印其内容时,显示是一个空对象,所以我打印files.file是undefined,而form.parse的参数fields却成功获取。可文件明明已经上传成功了啊,为什么获取不到files呢?求大佬告知如何解决。
另外,能有人告诉我怎样才能上传时修改传到本地目录中的图片文件名字也行(萌新瑟瑟发抖~~~~嘤嘤嘤)下附上传到目录中的图片情况:
图片描述

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

Spring初心 2022-09-18 14:36:01

不知道为什么,使用multiparty上传图片虽然能上传成功,但是当再次上传其他图片的时候,会把之前已成功保存的图片替换(也可能是清除了),两图之间名字也没有相同,你们有遇到过这样吗

停顿的约定 2022-09-18 14:36:01

问题好像解决了,查询了很多资料,终于发现了原因:当使用FormDaata组织表单数据时,如果不是一次性组织而是分多次append向其对象中添加数据,则node的multiparty模块的form.parse方法提供的回调函数参数files获取的是一个空对象。至于如何在上传时修改文件名而不是在上传后修改文件名很简单,使用模块自带的文件上传监听即可:

form.on('file',(name,file)=>{
    fs.rename(oldPath,newPath,(err)=>{
        if(err){
            throw err;
        }
    })
});
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文