NodeJS教程:基于OnceIO框架实现文件上传和验证


发布者 ourjs  发布时间 1480464960067
关键字 JS学习  Node.JS 

OnceIOOnceDoc企业内容(网盘)的底层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>

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

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

建立服务器接收文件逻辑

服务器文件 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' 开头但时间戳不同的文件:

5  cache_workflow

 

 

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

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





回复 (4)
微信扫码 立即评论




 热门文章 - 分享最多
  1. 在 2016 年学 JavaScript 是一种什么样的体验?
  2. 2016年收入最高的5个编程语言,JavaScript最流行,Java和C没在前5
  3. 传言GITHUB正在寻求第二轮融资,或面临估值下降、清算或被微软收购
  4. NodeJS中的客户端缓存、浏览器缓存、304缓存和OnceIO的缓存控制
  5. Java 之父求职被嫌年纪大,硅谷公司现在喜欢“小鲜肉”,不爱“老古董”
  6. NodeJS中的Middleware是什么?在OnceIO中创建和使用中间件
  7. OnceIO(NodeJS)中的服务器端缓存、模板预加载和静态资源文件的缓存和Gzip压缩机制
  8. OnceIO(Node.JS)中的模板引擎是什么及MVC设计模式的使用与实现
  9. OnceIO(Node.JS)的静态文件路由(app.static)
  10. OnceIO(Node.JS)的网页(模板)的引用与嵌套

 相关阅读
  1. 在Debian(Raspberry Pi)树莓派上安装NodeJS
  2. OnceIO(Node.JS)服务器端Cookie设置、添加、删除、显示及其实现原理
  3. OnceIO(Node.JS)的网页(模板)的引用与嵌套
  4. OnceIO(NodeJS)中的服务器端缓存、模板预加载和静态资源文件的缓存和Gzip压缩机制
  5. NodeJS中的客户端缓存、浏览器缓存、304缓存和OnceIO的缓存控制
  6. OnceIO(Node.JS)的路由(Routing)、路由方法和路由变量
  7. Node.JS的表单提交及OnceIO中接受GET/POST数据的三种方法
  8. OnceIO(Node.JS)中安装、使用和更换doT、EJS、pug等模板引擎
  9. OnceIO(Node.JS)中的模板引擎是什么及MVC设计模式的使用与实现
  10. NodeJS中的Middleware是什么?在OnceIO中创建和使用中间件

  开源的 OurJS
OurJS开源博客已经迁移到 OnceOA 平台。

  关注我们
扫一扫即可关注我们:
OnceJS

OnceOA