Node.js基于Express实现图片上传功能详解

作者:后端茶话

时间:2026-10-22

浏览:614

本文详细介绍如何在Node.js和Express环境下实现图片上传功能。内容涵盖前端自定义上传样式的CSS实现,利用HTML5 FormData进行Ajax异步上传,以及后端使用node-formidable插件处理文件保存、用户目录隔离、文件重命名及上传进度监听等关键步骤。

文章目录

Node.js基于Express实现图片上传功能详解

文件上传是网站开发中常见的功能。近期需要实现图片上传模块,主要解决两个核心问题:前端上传界面的样式美化以及服务端文件路径的保存。虽然功能逻辑简单,但实现过程涉及前后端配合,因此从页面上传样式的构建开始介绍。

前端页面样式设计

页面样式设计

浏览器默认的上传控件外观较为简陋,通常需要通过自定义背景图片来美化界面。具体做法是使用背景图片作为容器,并将实际的上传输入框隐藏或透明化,从而在视觉上呈现自定义的上传图片效果。

Node.js基于Express实现图片上传功能详解

上传图片的视觉效果


<div class="upload-container">

  <input type="file" name="fileToUpload" id="fileToUpload" class="fileupload" />

</div> 

相关的CSS样式代码如下:


.upload-container {

  background-image: url(../../images/rv/add.jpg);

  background-repeat: no-repeat;

  width: 180px;

  height: 200px;

  padding-bottom: 10px;

  display: inline-block;

  vertical-align: middle;

  .fileupload {

    opacity: 0;

    filter: alpha(opacity=0);

    width: 200px;

    height: 200px;

  }

} 

在HTML中,点击触发上传通常有两种常见方式:使用iframe或Ajax。本文采用Ajax方式,这是基于HTML5提出的XMLHttpRequest对象第二版(XHR2),通过FormData对象来传递文件数据,实现无刷新上传。


$('.fileupload').change(function(event) {

  /* Act on the event */

  if ($('.fileupload').val().length) {

    var fileName = $('.fileupload').val();

    var extension = fileName.substring(fileName.lastIndexOf('.'), fileName.length).toLowerCase();

    if (extension == ".jpg" || extension == ".png") {

        var data = new FormData();

        data.append('upload', $('#fileToUpload')[0].files[0]);

        $.ajax({

          url: 'apply/upload',

          type: 'POST',

          data: data,

          cache: false,

          contentType: false, //不可缺参数

          processData: false, //不可缺参数

          success: function(data) {

            console.log(data);

          },

          error: function() {

            console.log('error');

          }

        });

    } 

  }

}); 

服务端文件保存与处理

服务端文件保存逻辑

在Node.js服务端,保存上传文件需要使用第三方插件node-formidable。可以通过npm进行安装,安装命令如下:


npm install formidable@latest 

图片上传处理流程


var cacheFolder = 'public/images/uploadcache/';<br>exports.upload = function(req, res) {

  var currentUser = req.session.user;

  var userDirPath =cacheFolder+ currentUser.id;

  if (!fs.existsSync(userDirPath)) {

    fs.mkdirSync(userDirPath);

  }

  var form = new formidable.IncomingForm(); //创建上传表单

  form.encoding = 'utf-8'; //设置编辑

  form.uploadDir = userDirPath; //设置上传目录

  form.keepExtensions = true; //保留后缀

  form.maxFieldsSize = 2 * 1024 * 1024; //文件大小

  form.type = true;

  var displayUrl;

  form.parse(req, function(err, fields, files) {

    if (err) {

      res.send(err);

      return;

    }

    var extName = ''; //后缀名

    switch (files.upload.type) {

      case 'image/pjpeg':

        extName = 'jpg';

        break;

      case 'image/jpeg':

        extName = 'jpg';

        break;

      case 'image/png':

        extName = 'png';

        break;

      case 'image/x-png':

        extName = 'png';

        break;

    }

    if (extName.length === 0) {

      res.send({

        code: 202,

        msg: '只支持png和jpg格式图片'

      });

      return;

    } else {

      var avatarName = '/' + Date.now() + '.' + extName;

      var newPath = form.uploadDir + avatarName;

      displayUrl = UPLOAD_FOLDER + currentUser.id + avatarName;

      fs.renameSync(files.upload.path, newPath); //重命名

      res.send({

        code: 200,

        msg: displayUrl

      });

    }

  });

}; 

为了管理不同用户的文件,建议根据用户ID将图片放置在不同的目录中。当然,也可以为每张图片生成唯一的ID进行编号,这里推荐使用第三方uuid插件:https://github.com/broofa/node-uuid。

文件重命名处理


fs.renameSync(files.upload.path, newPath); //重命名 

监听文件上传进度


form.on('progress', function(bytesReceived, bytesExpected) {

}); 

node-formidable提供了丰富的官方API和多种配置选项。本文仅根据实际需求设置了部分关键参数,若有更复杂的额外需求,建议参考官方文档进行详细配置。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章