文件上传在一个项目中是相对于比较基础的功能,今天分享一下自己是如何在nodejs中使用中间件multiparty实现文件上传的。nodejs环境的搭建就不赘述了,直奔主题吧!
第一步:引入express等需要用到的模块express,jade等模块都需要自己手动使用npm命令在控制台安装,如npm install express。在这里用的是jade模板引擎。
(文件 demo.js)
var express = require("express");//导入express模块 var path = require('path');//路径配置模块 var bodyParser = require('body-parser')//页面传递参数解析 var mysql = require('mysql');//mysql模块 var multiparty = require('multiparty');//文件上传模块 var util = require('util'); var fs = require('fs'); var app = express(); var port = 3000;//端口号 app.set("views","views/pages/");//设置视图文件路径 app.set("view engine","jade");//设置模板引擎 app.use(express.static(path.join(__dirname,'bower_components')))//设置静态文件路径 app.use(bodyParser.urlencoded({extended: true,})) app.listen(port);//监听端口 console.log("start..."+port); console.log('连接开始'); app.get("/index",function (req,res) { res.send("hello") })
然后我们就可以在控制台启动服务 node demo,访问路径http://localhost:3000/index就可以看到结果了
开始编写html代码(因为使用的jade模板引擎,所以按照jade语法编写)主要是表单提交,关于样式代码就不解释了。代码和浏览器效果如下,其中代码有几个地方要解释一下,enctype="multipart/form-data"这一段代码必须要加上,用于表单里图片上传,action = "/demo"代表表单提交处理的路径。并把后台的get 请求代码附上
(文件demo.jade)
div.con form.loginForm(method = "post",enctype="multipart/form-data" ,action = '/demo') div.upload span 姓名: input.stuMsg.stu_name(type = "text",name = "name",placeholder = "姓名") div.upload span 学号: input.stuMsg.stu_number(type = "text",name = "number",placeholder = "学号") div.upload span 性别: input.stuMsg.stu_sex(type = "text",name = "sex",placeholder = "性别") div.upload span 年龄: input.stuMsg.stu_age(type = "text",name = "age",placeholder = "年龄") div.upload#containimg span 头像: input.stuMsg.stu_img(type = "file",name = "upfiles",multiple='mutiple') div.upload input.stuMsg.addmsg(type = "submit",value = "录入")
(文件app.js)
app.get("/demo",function (req,res) { res.render('demo',{}) })
接着开始连接数据库,我使用的市mysql,同样需要引入模块。数据库里面的字段有id name number sex age img
(文件demo.js)
//创建连接数据库 var conn = mysql.createConnection({ host: 'localhost', user: 'root', database:'stu_manage_system', port: 3306, }); conn.connect();//连接数据库
然后开始编写文件上传的核心代码:
(文件demo.js)
app.post("/demo",function(req,res){ var insertSQL = 'insert into student values(0,?,?,?,?,?)'; var insertSQL_params = []; var form = new multiparty.Form();//实例一个multiparty form.uploadDir = __dirname+"/bower_components/uploads/";//设置文件储存路径 //开始解析前台传过来的文件 form.parse(req, function(err, fields, files) { for (var item in fields){ insertSQL_params.push(fields[item][0]) console.log(fields[item][0]) } var filesTmp = JSON.stringify(files); var pr = JSON.parse(filesTmp) console.log(pr.upfiles.length) if(err){ console.log('parse error: ' + err); } else { for (var i = 0 ; i < pr.upfiles.length ; i++) { var inputFile = files.upfiles[i];//获取第一个文件 var finalname = inputFile.originalFilename; insertSQL_params.push(finalname) var new_name =__dirname+"/bower_components/uploads/"+finalname;//获取文件名 console.log(new_name) var old_name = inputFile.path;//获取文件路径 console.log(old_name) fs.renameSync(old_name,new_name); } } //添加数据到数据库 conn.query(insertSQL,insertSQL_params, function (err2, rows) { if (err2){ console.log(err2); }else{ console.log("成功") } }) res.send("成功") }) })
其中有些地方解释一下:
首先实例一个multiparty赋给form,
form.parse(req,callback)的回调函数三个参数,其中fields是一个对象,表示表单中非文件的数据
files参数也是一个对象,他包含了文件的所有信息
JSON.parse用于从一个字符串中解析出json对象JSON.stringify则相反
通过originalFilename获取文件的原始名,最后将文件信息存到数据库。
demo.jsd的完整代码如下
var express = require("express");//导入express模块 var path = require('path');//路径配置模块 var bodyParser = require('body-parser')//页面传递参数解析 var mysql = require('mysql');//mysql模块 var multiparty = require('multiparty');//文件上传模块 var util = require('util'); var fs = require('fs'); var app = express(); var port = 3000;//端口号 app.set("views","views/pages/");//设置视图文件路径 app.set("view engine","jade");//设置模板引擎 app.use(express.static(path.join(__dirname,'bower_components')))//设置静态文件路径 app.use(bodyParser.urlencoded({extended: true,})) app.listen(port);//监听端口 console.log("start..."+port); console.log('连接开始'); //创建连接数据库 var conn = mysql.createConnection({ host: 'localhost', user: 'root', database:'stu_manage_system', port: 3306, }); conn.connect();//连接数据库 app.get("/demo",function (req,res) { res.render('demo',{}) }) app.post("/demo",function(req,res){ var insertSQL = 'insert into student values(0,?,?,?,?,?)'; var insertSQL_params = []; var form = new multiparty.Form();//实例一个multiparty form.uploadDir = __dirname+"/bower_components/uploads/";//设置文件储存路径 //开始解析前台传过来的文件 form.parse(req, function(err, fields, files) { console.log(fields) for (var item in fields){ insertSQL_params.push(fields[item][0]) console.log(fields[item][0]) } console.log(files) var filesTmp = JSON.stringify(files); var pr = JSON.parse(filesTmp) console.log(pr.upfiles.length) if(err){ console.log('parse error: ' + err); } else { for (var i = 0 ; i < pr.upfiles.length ; i++) { var inputFile = files.upfiles[i];//获取第一个文件 var finalname = inputFile.originalFilename; insertSQL_params.push(finalname) var new_name =__dirname+"/bower_components/uploads/"+finalname;//获取文件名 console.log(new_name) var old_name = inputFile.path;//获取文件路径 console.log(old_name) fs.renameSync(old_name,new_name); } } //添加数据到数据库 conn.query(insertSQL,insertSQL_params, function (err2, rows) { if (err2){ console.log(err2); }else{ console.log("成功") } }) res.send("成功") }) })
如有错误、意见、建议,欢迎提出。