Node.js + Express 实现上传文件功能(felixge/node-formidable)
来源:互联网 发布:儿童摄影网络推广 编辑:程序博客网 时间:2024/04/28 11:41
Nodejs学习笔记(八)--- Node.js + Express 实现上传文件功能(felixge/node-formidable) - por...
前言
前面讲了一个构建网站的示例,这次在此基础上再说说web的常规功能----文件上传,示例以一个上传图片的功能为例子
上传功能命名用formidable实现,示例很简单!
PS:最近比较忙,距上一次更新已经比较久了^_^!
formidable简介
nodejs原生实现上传还是比较麻烦,有兴趣的自已去参考一下网上有网友写的代码
这里选择了formidable,也是github上同类功能模块人气比较高的
https://github.com/felixge/node-formidable
https://www.npmjs.org/package/formidable
优点:上传速度比较可观,占用内存也比较低,简单易用...
创建项目安装formidable
1.创建项目sampleUpload
cd 工作目录
express -e sampleUpload
2.修改package.json文件,添加formidable依赖项
{ "name": "application-name", "version": "0.0.1", "private": true, "scripts": { "start": "node ./bin/www" }, "dependencies": { "express": "~4.0.0", "static-favicon": "~1.0.0", "morgan": "~1.0.0", "cookie-parser": "~1.0.1", "body-parser": "~1.0.0", "debug": "~0.7.4", "ejs": "~0.8.5", "formidable" : "latest" }}
3.安装依赖项
cd sampleUpload && npm install
安装成功,一切准备就绪,开始完成这个功能!
实现上传功能
1.index.ejs文件中构建表单并实现前端验证 (样式使用和 http://www.cnblogs.com/zhongweiv/p/nodejs_express_webapp.html 一致)
<!DOCTYPE html><html> <head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"> <title><%= title %></title> <link rel="stylesheet" type="text/css" href="/stylesheets/bootstrap.min.css" /><link rel="stylesheet" type="text/css" href="/stylesheets/signin.css" /> </head> <body><div id="container" class="container"> <% if (locals.success) { %> <div id="alt_sucess" class="alert alert-success"> <%- success %> </div> <% } %> <% if (locals.error) { %> <div id="alt_warning" class="alert alert-warning"> <%= error %> </div> <% } %> <form class="form-signin" role="form" method="post" enctype='multipart/form-data'><h2 class="form-signin-heading">上传文件</h2><input id="fulAvatar" name="fulAvatar" type="file" class="form-control" /> <br/><button id="btnSub" class="btn btn-lg btn-primary" type="submit">上 传</button> </form></div> </body></html><script src="/javascripts/jquery-1.11.1.min.js" type="text/javascript"></script><script type="text/javascript"> String.prototype.format = function (args) {var result = this;if (arguments.length > 0) {if (arguments.length == 1 && typeof (args) == "object") {for (var key in args) {if (args[key] != undefined) {var reg = new RegExp("({" + key + "})", "g");result = result.replace(reg, args[key]);}}}else {for (var i = 0; i < arguments.length; i++) {if (arguments[i] != undefined) {var reg = new RegExp("({)" + i + "(})", "g");result = result.replace(reg, arguments[i]);}}}}return result;}$(function(){$('#btnSub').on('click',function(){ var fulAvatarVal = $('#fulAvatar').val(), errorTip = '<div id="errorTip" class="alert alert-warning">{0}</div> '; $("#errorTip,#alt_warning").remove();if(fulAvatarVal.length == 0){$("#container").prepend(errorTip.format('请选择要上传的文件'));return false;} var extName = fulAvatarVal.substring(fulAvatarVal.lastIndexOf('.'),fulAvatarVal.length).toLowerCase();if(extName != '.png' && extName != '.jpg'){ $("#container").prepend(errorTip.format('只支持png和jpg格式图片')); return false;}return true;})});</script>
这里一定要注意表单的 enctype 属性,这个就不多作解释了,如果是初次接触,看看 http://www.w3school.com.cn/tags/att_form_enctype.asp
2.实现index.js中上传逻辑
var express = require('express')router = express.Router(),formidable = require('formidable'), fs = require('fs'), TITLE = 'formidable上传示例',AVATAR_UPLOAD_FOLDER = '/avatar/'/* GET home page. */router.get('/', function(req, res) { res.render('index', { title: TITLE });});router.post('/', function(req, res) { var form = new formidable.IncomingForm(); //创建上传表单 form.encoding = 'utf-8';//设置编辑 form.uploadDir = 'public' + AVATAR_UPLOAD_FOLDER; //设置上传目录 form.keepExtensions = true; //保留后缀 form.maxFieldsSize = 2 * 1024 * 1024; //文件大小form.parse(req, function(err, fields, files) {if (err) { res.locals.error = err; res.render('index', { title: TITLE }); return;} var extName = ''; //后缀名switch (files.fulAvatar.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.locals.error = '只支持png和jpg格式图片'; res.render('index', { title: TITLE }); return; }var avatarName = Math.random() + '.' + extName;var newPath = form.uploadDir + avatarName;console.log(newPath);fs.renameSync(files.fulAvatar.path, newPath); //重命名});res.locals.success = '上传成功';res.render('index', { title: TITLE }); });module.exports = router;
注意:在public文件夹中创建avatar文件夹以供文件存放
运行结果
1.在app.js中添加8000端口的监听
2.cd到项目根目录,运行 node app
3.浏览器上访问 localhost:8000
4.上传图片
5.去上传文件夹中查看
大功告成!
部分疑惑解析
有一些在代码中有注释的我就不解释了
1.怎么没看到上传?
注意:form.parse 再看看formidable的解释
Automatically writing file uploads to disk
2.为什么需要fs.renameSync
原因和上一个问题有关,它会自动被上传到用户的临时目录(这个可以把files.fulAvatar.path输出来看一下便知) http://nodejs.org/docs/latest/api/fs.html#fs_fs_renamesync_oldpath_newpath
3.可不可以看到上传进度
可以, https://github.com/felixge/node-formidable#events (仔细看看events,可能有你要用的其它部分)
但是只是在控制台输出,想在前端去显示进度条是不行的(没有去研究,想想别的办法应该也可以)
4.文件名想命名UUID不重复,在nodejs中怎么办?
可以使用node-uuid,调用简单 https://github.com/broofa/node-uuid
...
其它的留言问吧^_^!
写在之后
功能比较简单,代码也是示例风格,大家主要关注一下使用
代码结构优化方向:
1.比如文件后缀这一类的方法可以放到一个pub.js中,此js专门用于这些公有方法
2.可以利于返回值的方式去返回数据,前端根据返回值做出相应的提示
3.可以利于jquer.form.js去提交表单,post中用res.json方法返回值,优化体验(同样引用这个js也会增大页面体积)
....
总之是个小例子,大家将就着看看吧^_^!
- Node.js + Express 实现上传文件功能(felixge/node-formidable)
- node.js利用express实现文件上传
- Node.js 使用formidable上传文件及接受POST数据
- 关于node.js使用formidable多文件上传解决方案
- node.js中关于使用formidable模块实现文件上传至指定目录的问题
- node.js 使用第三方模块formidable实现文件上传并修改文件名
- node文件上传插件formidable的使用
- node.js模块--formidable
- node.js+formidable
- node js Formidable中间件
- nodejs express+ejs+formidable实现文件上传
- Node.js与MySQL交互(felixge/node-mysql)
- node.js express框架文件上传路径
- node+express文件上传
- Node.js 上传文件formidable时使用fs.renameSync报错
- Node.js文件上传的时候控制台报Error: Cannot find module 'formidable'
- Node.js的formidable模块
- Node.js入门教程——如何实现文件上传功能
- 解决Python import “No module named ”问题
- Android 生成keystore jarsigner签名及解决找不到证书链的问题
- 【matlab】显示多张图
- 微信小程序数据存储与取值
- dubbo.xsd文件 找不到,配置文件报红色标志错误解决办法
- Node.js + Express 实现上传文件功能(felixge/node-formidable)
- 关于HTTP/1.1的小问题
- JavaScript执行环境及作用域
- 监听Home键
- HDU 1002 A + B Problem II (Java 之大整数)
- WHY YOU SHOULDN'T USE GETTERS AND SETTERS ON ANDROID
- React Native环境配置之Windows版本搭建
- HTML5 WebSocket构建实时应用
- 【VBA研究】解析JSON数据的几种方法