10. Node.js:上传文件

本文由清尘发表于2019-04-02 14:43最后修改于2019-05-02属于javascript分类

相关文章:

1.Node.js 起步
2.Node.js测试 Mocha框架
3.Express基础
4.MongoDB 基础
5.Node.js 与 MongoDB
6.Node.js:REST 接口
7. Socket.io
8. JWT:JSON Web Token
9. Node.js:基于 Token 的身份验证
10. Node.js:上传文件
===========================

Github:https://github.com/shine130/shine-node

Tgit私有仓库(file-upload分支):

HTTP: https://git.code.tencent.com/testpro/shine-node.git
SSH:git@git.code.tencent.com:testpro/shine-node.git

上传单个文件

处理文件的上传,可以用一个叫 multer 的包 … 它可以处理 multipart/form-data 类型的表单 .. 先为项目安装一下这个 package ..

npm install multer --save
const express = require('express')
const app = express()
const multer = require('multer')
const upload = multer({dest:'uploads/'})

app.post('/profile',upload.single('avatar'),(request,response,next) => {
    response.send(request.file)
})

app.listen(8080,() => {
    console.log('localhost:8080')
})

这个接口现在就可以用来处理上传文件了 .. 我们可以找个 REST 客户端去试一下 .. 比如 POSTMAN ..
配置一个请求 .. 方法是 POST .. 地址是 http://localhost:8080/profile
给请求添加一个主体 .. 类型是 form-data ..
添加一个字段 .. Key,名字应该是 avatar .. 它应该是在表单里的一个文件类型的 input 元素 .. 它的值是个文件 .. 选择文件 .. 在电脑上找一张图像 ..
然后发送一下这个请求 .. 接口会返回上传的文件相关的信息 …

fieldname 是上传文件用的字段的名字 .. originalname 是上传的文件的原名 .. encoding 是编码 .. mimetype 是文件的类型 ..
destination 是上传的文件存储的目录 .. filename 是文件上传以后的名字 … path 是文件上传以后的地址 .. size 是文件的大小 ..
然后打开我们的项目所在的目录 … 在 uploads 目录的下面,可以找到刚才上传上来的文件 ..

上传多个文件

上传多个文件接口 http://localhost:8080/photos/upload

const express = require('express')
const app = express()
const multer = require('multer')
const upload = multer({dest:'uploads/'})

app.post('/profile',upload.single('avatar'),(request,response,next) => {
    response.send(request.file)
})

app.post('/photos/upload',upload.array('photos',3),(request,response,next) => {
    response.send(request.files)
})

app.listen(8080,() => {
    console.log('localhost:8080')
})

文件上传过滤器

fileFilter 可以设置一下哪些文件可以上传,哪些文件不能上传 .. 在应用里添加一个函数 .. 名字可以随便起 .. 比如我们叫它 fileFilter .. 函数有三个参数 request .. file… 还有 callback ..

在函数里,我们可以判断一下文件的原始名 .. if !file.originalname .. 用一下 match .. 添加一个正则表达式 .. 它的意思就是,看一下文件的原始名的后缀是不是 .jpg 或者 .jpeg ,或者 .png 或者 .gif .. 如果不是这些后缀 ..

我们可以 return callback .. 一个 null ,一个 false .. 这样这个文件就不会被上传 ..

const express = require('express')
const app = express()
const multer = require('multer')

const fileFilter = (request,file,callback) => {
    if(!file.originalname.match(/\.(jpg|jpeg|png|gif)$/)){
        return callback(new Error('images only'),false)
    }
    callback(null,true)
}

const upload = multer({dest:'uploads/',fileFilter})

app.post('/profile',upload.single('avatar'),(request,response,next) => {
    response.send(request.file)
})

app.post('/photos/upload',upload.array('photos',3),(request,response,next) => {
    response.send(request.files)
})

app.use((error,request,response,next) => {
    response.status(500).send({
        message:error.message
    })
})

app.listen(8080,() => {
    console.log('localhost:8080')
})

Promise,async,await 应用案例:Loki 数据库

用一个简单的数据库记录一下上传的文件 .. 先给项目安装一个包 .. 名字是 lokijs .

npm install lokijs --save

回到项目 … 先导入 lokijs … 起个名字可以叫做 loki .. 创建一个数据库 .. 名字是 db ,新建一个 loki .. 先指定一下数据库的名字 .. 比如 uploads/uploads.json .. loki 数据库可以是一个文件 .. 再给它一个选项 .. 把 persistenceMethod ,存储的方法设置成 fs ..
loki 是文档类型的数据库,它里面可以包含一些 collection ,每个 collection 里面可以包含一些文档 .. 我们可以把上传的文件相关的信息存储在 loki 数据库的 collection 里面 ..

const express = require('express')
const app = express()
const multer = require('multer')
const loki = require('lokijs')

const db = new loki('uploads/uploads.json',{persistenceMethod:'fs'})

const loadCollection = (collectionName,db) => {
    return new Promise(resolve => {
        db.loadDatabase({},() => {
            const collection = db.getCollection(collectionName) || db.addCollection(collectionName)
            resolve(collection)
        })
    })
}

const fileFilter = (request,file,callback) => {
    if(!file.originalname.match(/\.(jpg|jpeg|png|gif)$/)){
        return callback(new Error('images only'),false)
    }
    callback(null,true)
}

const upload = multer({dest:'uploads/',fileFilter})

app.post('/profile',upload.single('avatar'),async (request,response,next) => {
    const collection = await loadCollection('uploads',db)
    const result = collection.insert(request.file)
    db.saveDatabase()
    response.send(result)
})

app.post('/photos/upload',upload.array('photos',3),(request,response,next) => {
    response.send(request.files)
})

app.use((error,request,response,next) => {
    response.status(500).send({
        message:error.message
    })
})

app.listen(8080,() => {
    console.log('localhost:8080')
})

找一个 REST 客户端 .. 配置一个请求 .. 方法是 POST .. 地址是 http://localhost:8080/profile 添加一个请求主体 .. 类型是 form-data .. 添加一个字段 .. 名字应该是 avatar … 对应的值是个文件 .. 选择文件 .. 找一张图像 ..
然后发送一下这个请求 …
成功地上传了文件,并且会把文件相关的信息存储在了数据库里 .. 注意这里返回的内容 .. 里面有个 meta 属性 .. revistion 是修订版本 .. created 是文档创建的日期 .. 还有个 version .. 这个 $loki ,是文档的 id 号 …
回到项目 ..
在 uploads 目录的下面,可以找到一个数据库文件 .. 就是这个 uploads.json …

请求上传的资源

定义一个可以返回上传资源的接口 http://localhost:8080/uploads/id号

const express = require('express')
const app = express()
const multer = require('multer')
const loki = require('lokijs')
const fs = require('fs')

const db = new loki('uploads/uploads.json',{persistenceMethod:'fs'})

const loadCollection = (collectionName,db) => {
    return new Promise(resolve => {
        db.loadDatabase({},() => {
            const collection = db.getCollection(collectionName) || db.addCollection(collectionName)
            resolve(collection)
        })
    })
}

const fileFilter = (request,file,callback) => {
    if(!file.originalname.match(/\.(jpg|jpeg|png|gif)$/)){
        return callback(new Error('images only'),false)
    }
    callback(null,true)
}

const upload = multer({dest:'uploads/',fileFilter})

app.post('/profile',upload.single('avatar'),async (request,response,next) => {
    const collection = await loadCollection('uploads',db)
    const result = collection.insert(request.file)
    db.saveDatabase()
    response.send(result)
})

app.post('/photos/upload',upload.array('photos',3),async (request,response,next) => {
    const collection = await loadCollection('uploads',db)
    const result = collection.insert(request.files)
    db.saveDatabase()
    response.send(result)
})

app.get('/uploads/:id',async (request,response) => {
    const collection = await loadCollection('uploads',db)
    const result = collection.get(request.params.id)
    response.setHeader('Content-Type',result.mimetype)
    fs.createReadStream(result.path).pipe(response)
})

app.use((error,request,response,next) => {
    response.status(500).send({
        message:error.message
    })
})

app.listen(8080,() => {
    console.log('localhost:8080')
})