node.js实现图像文件上传

一、使用FormData和formidable实现二进制文件(图片)的上传

     1、FormData对象:能够处理页面中的表单数据,使用new关键字实例化FormData()构造函数来创建FormData对象。

var formData = new FormData(form);

         FormData()构造函数接受form表单对象作为参数。它表示将普通的form表单对象转换为FormData对象。

         FormData对象提供了处理表单数据的方法,不需要拼接表单数据字符串的繁琐工作,使用起来非常方便。

        (1)set('key', 'value'); 第1个参数表示FormData对象的属性名;第2个参数表示该属性名的属性值。

        (2)get('key'); 接收1个参数表示FormData对象的属性名。

        (3)append('key', 'value'); 第1个参数表示FormData对象的属性名;第2个参数表示该属性名的属性值

       (4)delete('key'); 接收1个参数表示FormData对象的属性名

    2、formidable表单解析对象:能够将FormData对象解析成表单数据。FormData对象可以作为POST请求参数直接传递给服务器端。服务器端使用formidable表单解析对象的parse()方法处理FormData对象,并将FormData对象数据的处理结果返回给客户端。

formidable是一个第三方模块,用于将FormData对象解析成表单数据,从而实现表单数据的处理和文件的上传。

        (1)安装:npm install formidable

        (2)使用:

              const formidable = require('formidable');

              const form = new formidable.IncomingForm();

        (3)常用属性:

             keepExtensions:用来设置上传的二进制文件是否保持原来文件的扩展名,默认值为false表示不保持。如果设置keepExtensions属性的值为true表示保持。

            uploadDir:用来设置上传文件存放的文件目录,默认是系统的临时目录。

     3、上传示例:

           (1)前端页面:       

<label>请选择文件:</label>
    <input type="file" id="file">
    <div id="box"></div>
   <script>
        $(function () {
           $('#file').change(function () {
            if($('#file').val().length){
                let fileName = $('#file').val();
                let extension = fileName.substring(fileName.lastIndexOf('.'),fileName.length).toLowerCase();
                if(extension == '.jpg' || extension =='.png'){
                    let formData = new FormData();// 创建空的formData表单对象
                    formData.append('upload',$('#file')[0].files[0]); //将用户选择的文件追加到formData表单对象中
   
                    $.ajax({
                        url: 'http://localhost:3000/users/upload',
                        type: 'post',
                        data: formData,
                        cache: false,
                        contentType: false, //不可缺参数
                        processData: false, //不可缺参数
                        success: function(result) {
                                let img = document.createElement('img');
                                img.style.width = 300+'px';
                                img.style.height = 200+'px'
                                img.src = result.path;
                                $('img').remove() //删除前一次的img元素
                                $('#box').append(img)   
                        },
                        error: function(err){
                            console.log(err)
                        }
                    })
                }else{
                    alert('只支持png和jpg格式图片')
                }
            }
           })
        })  
   </script>

          (2)后台接口:

var express = require('express');
var formidable = require('formidable')
var fs = require('fs');
var router = express.Router();
/*
  http://localhost:3000/users/upload
*/
router.post('/upload',(req, res) => {
  let cacheFolder = 'public/images/uploads'
  if(!fs.existsSync(cacheFolder)){
    fs.mkdirSync(cacheFolder)
  }
  let form = new formidable.IncomingForm();
  form.encoding = 'utf-8'; //设置编辑
  form.uploadDir = cacheFolder; //设置上传目录
  form.keepExtensions = true; //保留后缀
  form.maxFieldsSize = 2 * 1024 * 1024; //文件大小
  form.type = true;
  let displayUrl;
  form.parse(req,function (err,fields,files) {
    if(err){
      res.send(err);
      return;
    }
    let extName = ''
    switch (files.upload.mimetype) {
      case 'image/jpeg':
        extName = 'jpg';
        break;
      case 'image/jpg':
        extName = 'jpg';
        break;
      case 'image/png':
        extName = 'png';
        break;
    }
    console.log(extName)
    if (extName.length === 0){
      res.send({
        code: 202,
        msg: '只支持png和jpg格式图片'
      })
      return
    }else{
      let newPath = form.uploadDir + '/' + files.upload.originalFilename;
      displayUrl =  `http://localhost:3000/images/uploads/${files.upload.originalFilename}`
      console.log("====>",newPath);
      fs.renameSync(files.upload.filepath,newPath);
      res.send({
        code: 200,
        path: displayUrl
      })
    }
  })
})
module.exports = router;

二、通过form + connect-multiparty表单上传图片

      1、前端页面:

<form action="http://localhost:3000/users/upload_test" method="post" enctype="multipart/form-data">
        <input type="file" name="photo">
        <button type="submit">提交</button>
</form>

      2、后台接口:

//使用上传中间件,需要安装:npm install connect-multiparty
const multiparty = require('connect-multiparty');
const multipartMiddleware = multiparty();
/*
   http://localhost:3000/users/upload_test
*/
router.post('/upload_test',multipartMiddleware,(req,res)=>{
  console.log("上传文件名:",req.files.photo)
  //上传图片参数
  var file = req.files.photo;
  //定义上传文件的存放路径
  var des_file = path.join(__dirname,'../public/images/uploads')+"\\"+file.originalFilename
  console.log(des_file) //上传路径:des_file
  console.log(file.path) //临时文件路径:file.path
  //将文件存入本地服务器文件中
  fs.readFile(file.path,function (err,data){
    fs.writeFile(des_file,data,function(err){
      if(err){
        console.log(err)
        res.json({code:1});
        return
      }
    })
  })
  //网络访问时public目录不能出现,public是虚拟目录
  let imgpath = `http://localhost:8089/images/${file.originalFilename}`;
  //将图片存放的地址返回
  res.send( {
    code: 0,
    path: imgpath
  })
})

三、ajax + multiparty实现图片上传

      注意:在客户端提交的时候,html页面form 表单要加入 enctype="multipart/form-data"

但是 ajax 不需要加入

     1、前端页面

<input  type="file" name="images" onchange="fileUpload(this)">
    <button onclick="uploadPictures()">上传图片</button>
    <!--获取服务返回图片数据-->
    <div>
        <img class="img"   src="" alt="">
    </div>
    <script>
        var fileImg;
        //读取图片
        function fileUpload(_this) {
            var fileReader = new FileReader();//创建文件读取对象
            fileImg = _this.files[0];//获取file组件中的文件
        }
        //上传图片
        function uploadPictures() {
            var formData = new FormData();
            //图片
            if (fileImg != null) {
              formData.append("image", fileImg);
            }

            $.ajax({
                url: 'http://localhost:3000/users/uploading',
                type: 'post',
                data: formData,
                processData: false,
                contentType: false,
                success: function (res) {
                    $('.img').attr('src', res.path);
                },
                error: function (err) {
                    console.log(err);
                }
            });
        }
    </script>

        2、后台接口

/*
  http://localhost:3000/users/uploading
*/
router.post('/uploading',(req, res) => {
  var form = new multiparty.Form();
  form.uploadDir='public/images/uploads'; //上传图片保存的地址(目录必须存在)
  form.parse(req, function(err, fields, files) {// 1、fields:获取表单的数据 2、files:图片上传成功返回的信息
    let newPath = form.uploadDir + '/' + files.image[0].originalFilename;
    fs.renameSync(files.image[0].path,newPath);
    let imgUrl = 'http://localhost:3000/images/uploads/' + files.image[0].originalFilename;
    res.send({
      path: imgUrl
    })
  })
})

  • 5
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

上庸者-不服周

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值