前台使用ajax上传图片,后台 node.js 使用 formidable 进行图片接受并存于服务器静态文件夹中

相信现在很多小伙伴在使用node来搭建后台,那么前后台对接少不了的就是图片的上传,下面我将通过这篇文章来对图片上传问题进行详细的介绍:

本项目源码已经上传GitHub,https://github.com/crazyJiaLin/node-img-upload-demo

首先,我们需要一些准备:

  1. 通过node+express搭建后台服务器,并配置静态资源文件路径,具体配置方式网上有很多种解法,这里不再展示,如果不想自己搭建,可以从本人GitHub中检出直接使用;
  2. 搭建MVC(model+view+controller)目录结构如下图:
    目录结构
  3. 除express+ejs,我们还需要安装一些模块
    $ npm install formidable dateformat -S

    接着,我们建立上传图片的模块,即文件目录中的model/upload-model.js

var path = require('path');
var fs = require('fs');                     //文件系统
var formidable = require('formidable');     //引用formidable来解析请求,上传文件
var dateFormat = require('dateformat');     //生成时间对象,来重命名上传的图片,避免图片的重复

module.exports = {
    /**通过formdata上传图片
     * 参数1--req,express请求
     * 参数2--dirName,静态资源下的路径
     * 参数3--callback,回调函数,callback(err,fields,uploadPath),返回错误对象,表单字段和图片上传的地址
     */
    uploadPhoto : function(req,dirName,callback){
        //上传文件
        // parse a file upload
        var form = new formidable.IncomingForm();
        form.uploadDir = path.join(__dirname,'../static',dirName);
        //保留文件扩展名
        form.keepExtensions = true;
        form.encoding = 'utf-8';

        form.onPart = function(part) {
            if (part.filename != '') {
            // let formidable handle all non-file parts 
            form.handlePart(part);
            }
        };
        //通过formidable进行图片的上传
        form.parse(req, function(err, fields, files) {
            if(err) {
                callback && callback(err,null,null);
                return;
            }
            if(!files.userfile){    //前台上传表单的时候,文件使用的字段名是userfile,这里对文件是否为空进行判断
                var errMsg = {
                    errCode : -10,
                    errMsg : '文件为空'
                };
                callback && callback(errMsg,null,null);
                return;
            }

            //文件不为空的情况下,说明文件已经上传到我们的服务器中
            //这时,需要我们使用fs模块把我们已经上传的路径改为我们想要的位置
            //并且使用dateFormat来创建时间字符串,从而避免文件的重名
            var time = dateFormat(new Date(), "yyyymmddHHMMss");
            //files.userfile.path代表的是formidable为我们上传文件后绝对路径,通过path的extname来获取图片后缀
            var extName = path.extname(files.userfile.path);    
            var newName = time + '_' + Math.floor(Math.random()*9999) + extName;    //使用dateFormat+随机数+文件后缀生成新文件名

            var oldPath = files.userfile.path;
            var newPath = path.join(__dirname,'../static',dirName, newName);
            //修改文件的名字
            fs.renameSync(oldPath,newPath);
            var finalPath = path.join('/',dirName,newName).split('\\').join('/');   //将路径中的'\'替换为'/'
            callback && callback(null, fields, finalPath);  //回掉函数返回表单字段以及图片上传的相对路径
        }); 
    }
};

然后创建controller层img-upload.js文件,来接受请求,然后交接到model层

var express = require('express');
var router = express.Router();
var uploadModel = require('./../model/upload-model');//上传model


router.post('/imgUpload',function(req,res){
    /**设置响应头允许ajax跨域访问**/
    res.setHeader("Access-Control-Allow-Origin","*");
    uploadModel.uploadPhoto(req,'img',function(err,fields,uploadPath){
        if(err){
            return res.json({
                errCode : 0,
                errMsg : '上传图片错误'
            });
        }
        console.log(fields);    //表单中字段信息
        console.log(uploadPath);    //上传图片的相对路径
        res.json({
            errCode : 1,
            errMsg : '上传成功',
            fields :  fields,
            uploadPath : uploadPath
        });
    });
});

module.exports = router;

这里记得将我们的路由配置放置到server.js中,并使用node server.js 启动项目后台

//路由配置
var imgUploade = require('./controller/img-upload');
app.use(imgUploade);

然后,我们就可以在前台创建表单对象来提交请求了(index.html)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>图片上传demo</title>
</head>
<body>

    <input type="file" id="img-upload">
    <button id="submit-button">开始上传</button>

    <script src="./js/jquery-3.1.0.min.js"></script>
    <script>
        $('#submit-button').on('click',function(){
            var myPhoto = $('#img-upload')[0].files[0];
            var oMyForm = new FormData();
            oMyForm.append("name", 'crazyJiaLin');
            oMyForm.append("userfile", myPhoto);
            $.ajax({
                type : 'POST',
                url : '/imgUpload',
                cache : false,  //不需要缓存
                processData : false,    //不需要进行数据转换
                contentType : false, //默认数据传输方式是application,改为false,编程multipart
                data : oMyForm,
                dataType : 'json'
            }).done(function(data){
                console.log(data);
                alert(data.errMsg);
            }).fail(function(err){
                console.error(err);
            });
        });
    </script>
</body>
</html>

下面来展示一下上传效果:

  • 选择文件后,点击上传按钮,返回上传成功数据
    这里写图片描述

  • 后台返回数据以及文件中图片内容
    这里写图片描述
    这里写图片描述

感谢大家支持,源码已经上传GitHub,https://github.com/crazyJiaLin/node-img-upload-demo,望多多支持!

  • 6
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值