Node.js开发教程之基于OnceIO框架实现文件上传和验证功能


Posted in Javascript onNovember 30, 2016

OnceIO 是 OnceDoc 企业内容(网盘)的底层Web框架,它可以实现模板文件、静态文件的全缓存,运行起来完全不需要I/O操作,并且支持客户端缓存优化,GZIP压缩等(只在第一次压缩),拥有非常好的性能,为您节约服务器成本。它的模块化功能,可以让你的Web进行分布式存储,即一个扩展包里即包含前端、后端和数据库定义,只需通过添加/删除目录的方式就可实现功能删减,实现真正的模块化扩展。这里是介绍如何使用OnceIO的一系列文章。

在这一章节中,我们将为大家演示如何使用 OnceIO 实现文件上传功能。

在网页文件中构建表单

以一个只有文件上传功能的简单网页 file.html 为例:

<!DOCTYPE html>
<html>
<body>
<form method="post" enctype="multipart/form-data" action="/file/upload">
<input type="file" name="file" /><br>
<input type="submit" value="Upload" />
</form>
</body>
</html>

浏览器显示效果是这样的:

Node.js开发教程之基于OnceIO框架实现文件上传和验证功能 

点击空白长条或“浏览…”按钮可以打开文件浏览窗口选择需要上传的文件:

Node.js开发教程之基于OnceIO框架实现文件上传和验证功能 

建立服务器接收文件逻辑

服务器文件 websvr.js 代码是这样的:

var fs = require('fs')
var path = require('path')
var onceio = require('../onceio/onceio')
var app = onceio()
app.get('/', function(req, res){
res.render('file.html')
})
app.file('/file/upload', function(req, res) {
var fileInfo = req.files.file || {}
fs.link(fileInfo.path, path.join('./fileStore', fileInfo.name))
res.send('File Uploaded Successfully')
}).before(function(req, res) {
var contentLength = req.headers['content-length'] || 0
if (contentLength > 1048576) {
res.send({ error: 'Error: File Size Limit (1 MB) Exceeded' })
} else {
return true
}
})

var fs = require('fs') 和 var path = require('path') 分别导入了 Node.js 提供的用于操作文件的文件系统(fs)模块和用于处理文件路径的 path 模块。

app.file(path, callback).before(callback) 相当于 app.use(path, callback, {file: true}).before(callback) ,是一个处理上传的文件的中间件。

文件被上传后,它的大小、存放地址、名称、格式和修改时间五项信息会被放在 req.files 的 file 属性里(名称是 type 为 'file' 的 input 标签中 name 的值),它的尺寸信息会被放在 req.headers 的 content-length 属性里。

before函数

before是OnceIO与其它Web框架的主要区别之一。它可以在文件接收之前就对文件进行一些基本验证,如大小、类型等,以求获得最侍性能。return true 表示验证通并开始接收文件,否则就关闭连接,取消上传。在 before 中,req.session对象是不可用的,因为session可能存在文件或数据库redis中,取得session是一个异步过程需要时间。而before函数需要立刻对文件合法性做出判断。

在这个例子中before回调函数根据 req.headers 中的 content-length 判断上传的文件是否超出了尺寸限制(开发人员可以通过修改 if 语句中的常数改变文件上传尺寸上限,content-length 单位为 byte,1024 * 1024 即代表 1 MB),如果超出了,文件不会被上传,服务器返回错误信息;如果没有超出,函数返回值为 true,服务器继续执行 app.file 中的回调函数,将文件从临时地址转移到指定存储地址,文件上传到这里就完成了。

解决文件重名问题

我们目前的服务器程序是无法解决文件重名问题的。如果用户上传了重名的文件,服务器将会返回文件已经存在的错误。为了解决这个问题,我们可以在文件的主文件名和拓展名之间加入一个时间戳,进行这个处理的函数代码如下:

var timestampName = function(fileName){
// get filename extension
var extName = path.extname(fileName) 
// get base name of the file
var baseName = path.basename(fileName, extName)
// insert timestamp between base name and filename extension
// the plus sign ('+') before new Date() converts it into a number
return baseName + +new Date() + extName
}

再把 fs.link 语句里的 fileInfo.name 替换为 timestampName(fileInfo.name):

fs.link(fileInfo.path, path.join('./fileStore', timestampName(fileInfo.name)))

改进后的服务器程序就能允许用户上传重名文件了,以上传 5 次名为 'cache_workflow.png' 的文件为例,服务器的文件存储地址中会出现 5 个名称都以 'cache_workflow' 开头但时间戳不同的文件:

Node.js开发教程之基于OnceIO框架实现文件上传和验证功能 

OnceIO地址: https://github.com/OnceDoc/onceio

示例源码: https://github.com/OnceDoc/OnceAcademy/tree/master/Lesson14

以上所述是小编给大家介绍的Node.js开发教程之基于OnceIO框架实现文件上传和验证,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
jQuery图片切换插件jquery.cycle.js使用示例
Jun 16 Javascript
js中window.open打开一个新的页面
Aug 10 Javascript
node.js中的fs.truncate方法使用说明
Dec 15 Javascript
jQuery 重复加载错误以及修复方法
Dec 16 Javascript
jQuery实现自动滚动到页面顶端的方法
May 22 Javascript
js实现的奥运倒计时时钟效果代码
Dec 09 Javascript
javascript数组去重小结
Mar 07 Javascript
JS简单实现数组去重的方法示例
Mar 27 Javascript
vue2.0实现倒计时的插件(时间戳 刷新 跳转 都不影响)
Mar 30 Javascript
JavaScript实现获取用户单击body中所有A标签内容的方法
Jun 05 Javascript
JavaScript实现的仿新浪微博原生态输入字数即时检查功能【兼容IE6】
Sep 26 Javascript
mpvue+vant app搭建微信小程序的方法步骤
Feb 11 Javascript
浅析JavaScript中break、continue和return的区别
Nov 30 #Javascript
JavaScript的变量声明提升问题浅析(Hoisting)
Nov 30 #Javascript
浅析script标签中的defer与async属性
Nov 30 #Javascript
JavaScript 字符串常用操作小结(非常实用)
Nov 30 #Javascript
js实现表单提交后不重新刷新当前页面
Nov 30 #Javascript
html判断当前页面是否在iframe中的实例
Nov 30 #Javascript
vue.js实现表格合并示例代码
Nov 30 #Javascript
You might like
php函数的常用方法及注意之处小结
2011/07/10 PHP
php多种形式发送邮件(mail qmail邮件系统 phpmailer类)
2014/01/22 PHP
什么情况下可以不写PHP的闭合标签“?&gt;”
2014/08/28 PHP
Firefox/Chrome/Safari的中可直接使用$/$$函数进行调试
2012/02/13 Javascript
document.addEventListener使用介绍
2014/03/07 Javascript
js创建表单元素并使用submit进行提交
2014/08/14 Javascript
javascript简单实现滑动菜单效果的方法
2015/07/27 Javascript
jQuery解析json数据实例分析
2015/11/24 Javascript
jquery日历插件datepicker用法分析
2016/01/22 Javascript
ES6新特性之数组、Math和扩展操作符用法示例
2017/04/01 Javascript
如何理解Vue的作用域插槽的实现原理
2017/08/19 Javascript
JS switch判断 三目运算 while 及 属性操作代码
2017/09/03 Javascript
vue.js,ajax渲染页面的实例
2018/02/11 Javascript
详解vuex中action何时完成以及如何正确调用dispatch的思考
2019/01/21 Javascript
vue实现拖拽效果
2019/12/23 Javascript
各个系统下的Python解释器相关安装方法
2015/10/12 Python
简单了解Python下用于监视文件系统的pyinotify包
2015/11/13 Python
R语言 vs Python对比:数据分析哪家强?
2017/11/17 Python
使用Django和Python创建Json response的方法
2018/03/26 Python
ubuntu 18.04搭建python环境(pycharm+anaconda)
2019/06/14 Python
Docker部署Python爬虫项目的方法步骤
2020/01/19 Python
python中的垃圾回收(GC)机制
2020/09/21 Python
CSS3 倾斜的网页图片库实例教程
2009/11/14 HTML / CSS
CSS3中:nth-child和:nth-of-type的区别深入理解
2014/03/10 HTML / CSS
AOP的定义以及作用
2013/09/08 面试题
物理教师自荐信范文
2013/12/28 职场文书
运动会的口号
2014/06/09 职场文书
2014个人年终工作总结范文
2014/12/15 职场文书
汽车4S店前台接待岗位职责
2015/04/03 职场文书
2019年七夕情人节浪漫祝福语大全!
2019/08/08 职场文书
教你如何使用Python开发一个钉钉群应答机器人
2021/06/21 Python
Django+Celery实现定时任务的示例
2021/06/23 Python
go语言使用Casbin实现角色的权限控制
2021/06/26 Golang
Python Pandas 删除列操作
2022/03/16 Python
解决springboot druid数据库连接失败后一直重连的方法
2022/04/19 Java/Android
在虚拟机中安装windows server 2008的图文教程
2022/06/28 Servers