文件上传在一个项目中是相对于比较基础的功能,今天分享一下自己是如何在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("成功")
})
})
如有错误、意见、建议,欢迎提出。