NodeJs之文件上传
NodeJs之文件上传
一,介绍与需求
1.1,介绍
1,multer模块
multer用于处理文件上传的nodejs中间件,主要跟express框架搭配使用,只支持表单MIME编码为multipart/form-data类型的数据请求.
2,fs模块
fs模块用于对系统文件及目录进行读写操作。
1.2,需求
上传并操作文件与文件目录
二,配置实现
2.1,multer模块
第一步:安装multer模块
cnpm install multer --save
第二步:引入multer模块,构造multer对象: multer(opt)
opt是个key-value对象,包含属性dest/storage,fileFilter,limits.分表表示文件的存储位置/方式,文件过滤,文件大小限制.如下:
var moment = require("moment");
var express = require("express");
var multer = require('multer');
var storage = multer.diskStorage({
//文件存储路径
destination: function (req, file, cb) {
cb(null, path.join(__dirname, "/../uploads/temps"));
},
//修改上传文件的名字
//file 是个文件对象 ,fieldname对应在客户端的name属性
//存储的文件需要自己加上文件的后缀,multer并不会自动添加
//这里直接忽略文件的后缀.
filename: function (req, file, cb) {
var date = new Date();
cb(null, moment().format("YYYYMMDDhhmmss") + file.originalname);
}
});
let objMulter = multer({storage : storage });
如果初始化multer时候没有指定dest或者storage,上传的文件将保存在内存中,永远不会写入到磁盘中,在storage中如果没有指定destination值,那么上传的文件将存储在系统默认的临时文件夹.
multer关联的文件信息: filedname : 在form表单中指定的name属性值
orginalname : 原始文件名
encoding : 文件编码方式
mimetype : 多媒体类型
size : 文件大小,单位b
destination : 文件上传后存储在服务端的路径
filename : 文件在服务端的命名
path : 文件在服务端的完整路径
buffer : 文件二进制数据 ps:其中destination,filename和path只有在指定storage属性时候有效.而buffer只有文件在内存中存储时候有效.
multer同时提供了single/array/fields/any方法用于对接受文件数的控制.
- single(fieldname) 接收单个文件,通过req.file访问该文件
- array(fieldnaem,[maxcount]) 接收多个文件,通过req.files数组方法文件.maxcount指定接收文件最大数.
- fields(fields) 接受指定fieldname的文件,fieldname由客户端决定,通过req.files数组方法
- any 接收所有文件上传,通过req.files访问文件
2.2,fs模块
第一步:安装fs模块,也可直接引用,node默认集成
cnpm install fs --save//项目目录安装
var fs = require("fs");//直接引入文件系统模块
第二步:介绍fs模块的方法
var fs = require('fs'); // 载入fs模块
1,删除指定文件:fs.unlink(path,callback)
path参数为该文件的绝对物理路径,callback回调参数当中只有一个错误信息参数err,一般在该文件不存在或者删除文件失败时触发调用。
fs.unlink('/tmp/234.txt', function(err) {
if (err) {
throw err;
}
console.log('成功删除了 /tmp/234.txt');
});
2,读取文件:fs.readFile(filename,[option],callback)
参数说明:
- filename String 文件名
- option Object
- encoding String |null default=null
- flag String default='r'
- callback Function
path参数为该文件的绝对物理路径,其中options参数可选,可以传入编码格式,如读取文本文件时,可传入'utf8',若不指定编码格式,则默认输出读取的文件内容为Buffer形式,故一般都会传入该参数。callback回调参数当中有两个参数err和data,其中err为错误信息参数,一般在在文件不存在或者读取文件失败时触发调用,data为文件内容。
fs.readFile('./tmp/test.txt','utf-8'function(err, data) {
// 读取文件失败/错误
if (err) {
throw err;
}
// 读取文件成功
console.log(data);
});
3,写入文件:fs.writeFile(filename,data,[options],callback),追加写入:fs.appendFile(filename,data[,options],callback)
filename参数为该文件的绝对物理路径,data为需要写入该文件当中的数据内容,其中options参数可选,可以传入编码格式,若不传则默认为utf8。callback回调参数当中只有一个错误信息参数err,一般在写入失败时触发调用。
// 写入文件内容(如果文件不存在会创建一个文件)
// 传递了追加参数 { 'flag': 'a' }
fs.writeFile('./test2.txt', 'test test', { 'flag': 'a' }, function(err) {
if (err) {
throw err;
} console.log('Saved.'); // 写入成功后读取测试
fs.readFile('./test2.txt', 'utf-8', function(err, data) {
if (err) {
throw err;
}
console.log(data);
});
});
flag传值,r代表读取文件,w代表写文件,a代表追加。
// 追加写入
fs.appendFile("2.txt","我是追加的字符",function (err) {
if(err){
return console.log(err);
}else {
console.log("追加成功");
}
})
4,检测文件是否存在:fs.exists(path,callback)
path参数传入该文件的绝对物理路径,该callback回调函数有个参数exists。exists为一个文件状态对象,是否存在。
var dest_Dir = path.join(__dirname.replace("routes", ""), "uploads", destDir);
fs.exists(dest_Dir, function (exists) {
if (exists) {
//存在
}
else {
}
});
5,移动或重命名指定文件:fs.rename(oldPath,newPath,callback)
oldPath参数为该文件原来的路径,newPath参数为该文件移动或重命名之后的路径,这两个参数都必须能传入文件完整的绝对物理路径。callback回调参数当中只有一个错误信息参数,一般在oldPath当中指定的文件不存在或者该操作失败时触发调用。
fs.rename(sourceFile, destPath, function (err) {
res.status(200).json({
httpCode: 200,
message: '上传成功',
data: {
"fileurl": fileurl
},
});
});
6,创建一个目录文件夹:fs.mkdir(path[,model],callback)
path为该目录的绝对物理路径,callback回调函数当中也只有一个错误信息参数,一般在目录创建失败时触发调用。
fs.mkdir(dest_Dir, 0777, function (err) {
if (err) {
res.status(500).json({
} else {
//创建目录成功,上传文件
fs.rename(sourceFile, destPath, function (err) {
res.status(200).json({
httpCode: 200,
message: '上传成功',
data: {
"fileurl": fileurl
},
});
});
}
})
7,读取目录文件夹:fs.readdir(path,callback)
path为该目录的绝对物理路径,callback回调函数当中有两个参数err和files,err为错误信息参数,一般在该目录不存在或读取失败时触发调用,files为一个数组对象,包含该目录下的所有文件夹与文件的名字。(仅为文件夹的名字和文件名,不是路径形式)。
fs.readdir('./newdir', function(err, files) {
if (err) {
throw err;
}
// files是一个数组
// 每个元素是此目录下的文件或文件夹的名称
console.log(files);
});
8,删除一个空文件夹:fs.rmdir(path,callback)
path为该目录的绝对物理路径,callback回调函数当中也只有一个错误信息参数,一般在该目录不存在或者删除操作失败时触发调用。
fs.rmdir('/tmp', function(err) {
if (err) {
throw err;
}
console.log('成功删除了 空文件夹 tmp');
});
以上的实例均是异步操作,如果需同步操作在函数后面加Sync既可
//同步 所有同步的函数都是函数后面加Sync;
var res = fs.writeFileSync("1.txt","我是写入内容");
2.3,文件上传
1,单文件上传
router.post('/upload', upload.single('file'), function (req, res, next) {
var fileName = req.file.filename;
var destDir = req.body.dir == undefined ? "default" : req.body.dir;
var sourceFile = req.file.path;
var destPath = path.join(__dirname.replace("routes", ""), "uploads", destDir, fileName);
var dest_Dir = path.join(__dirname.replace("routes", ""), "uploads", destDir);
var fileurl = uploadFileDomin + destPath.substr(destPath.indexOf("uploads"));
fileurl = fileurl.replace(/\\/g, "/");
fs.exists(dest_Dir, function (exists) {
if (exists) {
fs.rename(sourceFile, destPath, function (err) {
res.status(200).json({
httpCode: 200,
message: '上传成功',
data: {
"fileurl": fileurl
},
});
});
}
else {
fs.mkdir(dest_Dir, 0777, function (err) {
if (err) {
res.status(500).json({
httpCode: 500,
message: err,
data: [],
});
} else {
fs.rename(sourceFile, destPath, function (err) {
res.status(200).json({
httpCode: 200,
message: '上传成功',
data: {
"fileurl": fileurl
},
});
});
}
})
}
});
});
2,多文件上传
router.post('/uploads', upload.array('file', 8), function (req, res, next) {
var paths = [];
for (var i = 0; i < req.files.length; i++) {
var path = req.files[i].path.replace(/\\/g, "/");
var fileurl = uploadFileDomin + path.substr(path.indexOf("uploads")).replace('\\', '/');
paths.push(fileurl);
}
res.status(200).json({
httpCode: 200,
message: '上传成功',
"fileurls": paths,
});
});
最后抛出发送上传接口:
app.use("/api", require("./fileUploadApi.js"));
三,前端调用
3.1,单文件上传调用
1,简单html
<span>ajax upload</span>
<div class="container">
<label>file</label>
<input type="file" name="file" id="file">
<input type='button' value='上传' id="btn_upload" />
</div>
2,js调用
$("#btn_upload").click(function () {
//创建一个FormDate
var formData = new FormData();
//将文件信息追加到其中
formData.append('file', file.files[0]);
formData.append('dir', 'attachment');
//formData.append('name', file.files[0].name);
$.ajax({
url: "http://localhost:3000/api/" + 'upload',
type: 'POST',
data: formData,
cache: false,
contentType: false,
processData: false,
xhrFields: {
withCredentials: true
},
crossDomain: true,
success: function (data) {
callBack(data);
},
error: function (response) {
console.log("error is :" + response);
}
});
3,实现效果


3.2,多文件上传调用
1,简单html
<span>ajax multi files upload</span>
<div class="container">
<label>file</label>
<input type="file" name="file" id="files1">
<input type="file" name="file" id="files2">
<input type="file" name="file" id="files3">
<input type='button' value='上传' id="btn_uploads" />
</div>
2,js调用
var files1 = $("#files1")[0];
var files2 = $("#files2")[0];
var files3 = $("#files3")[0];
$("#btn_uploads").click(function () {
//创建一个FormDate
var formData = new FormData();
//将文件信息追加到其中
formData.append('file', files1.files[0]);
formData.append('file', files2.files[0]);
formData.append('file', files3.files[0]);
$.ajax({
url: 'http://localhost:3000/api/' + 'uploads',
type: 'POST',
data: formData,
contentType: false,
processData: false,
async: false,
xhrFields: {
withCredentials: true
},
crossDomain: true,
success: function (data) {
callBack(data.fileurls);
},
error: function (response) {
console.log("error is :" + response);
}
})
})
3,实现效果


NodeJs之文件上传的更多相关文章
- Nodejs express 文件上传
文件上传 以下我们创建一个用于上传文件的表单,使用 POST 方法,表单 enctype 属性设置为 multipart/form-data. index.htm 文件代码修改如下: <html ...
- nodejs实现文件上传
在使用ant-design的upload上传文件时,前端很好实现,那么我们如何实现node服务端呢? 服务端文件上传实现 var express = require('express'); var f ...
- nodejs+multiparty 文件上传
通过表单提交上传文件: html代码 <form action="/uploadFile" method="post" enctype=" ...
- nodeJs实现文件上传,下载,删除
转:https://blog.csdn.net/qq_36228442/article/details/81709272 一.简介 本文介绍了nodeJs+express框架下,用multer中间件实 ...
- nodejs应用:文件上传
功能:上传文件到服务器,图片支持客户端本地预览. 服务端 //server.js 'use strict';const http = require('http');const url = requi ...
- 【nodejs】文件上传demo实现
文件结构: index.js var server = require('./server.js'); var router = require('./router.js'); var request ...
- Html5+NodeJS——拖拽多个文件上传到服务器
实现多文件拖拽上传的简易Node项目,可以在github上下载,你可以先下载下来:https://github.com/Johnharvy/upLoadFiles/. 解开下载下的zip格式包,建议用 ...
- Nodejs进阶:基于express+multer的文件上传
关于作者 程序猿小卡,前腾讯IMWEB团队成员,阿里云栖社区专家博主.欢迎加入 Express前端交流群(197339705). 正在填坑:<Nodejs学习笔记> / <Expre ...
- nodejs学习之文件上传
最近要做个图片上传的需求,因为服务端春节请假回家还没来,所以就我自己先折腾了一下,大概做出来个效果,后台就用了nodejs,刚开始做的时候想网上找一下资料,发现大部分资料都是用node-formida ...
随机推荐
- 《前端之路》之四 JavaScript 的闭包、作用域、作用域链
04:JavaScript 的闭包 一.定义: 常规定义: 闭包的定义: 有权利访问外部函数作用域的函数. 通俗定义: 1.函数内部包含了函数.然后内部函数可以访问外部函数的作用域. 2.内部函数可以 ...
- LVS(五)LVS的持久连接
什么是持久链接 把某个客户端的请求始终定向到同一应用服务器上.对于LVS来说持久连接和算法没有关系.也就是使用任何算法LVS都可以实现同一客户端的请求转发到之前选定的应用服务器,以保持会话.而且还能实 ...
- RabbitMQ消息队列(一)-RabbitMQ的优劣势及产生背景
本篇并没有直接讲到技术,例如没有先写个Helloword.我想在选择了解或者学习一门技术之前先要明白为什么要现在这个技术而不是其他的,以免到最后发现自己学错了.同时如果已经确定就是他,最好先要了解下技 ...
- 深入理解Linux内核 学习笔记(1)
1.用户和用户组 每个用户是一个或多个用户组的一名成员,组由唯一的用户组标识符(user group ID)标识.每个文件的相关权限也恰好与一个组相对应. root为超级用户, 2.模块 为了达到微内 ...
- 并发系列(4)之 AbstractQueuedSynchronizer 源码分析
本文将主要讲述 AbstractQueuedSynchronizer 的内部结构和实现逻辑,在看本文之前最好先了解一下 CLH 队列锁,AbstractQueuedSynchronizer 就是根据 ...
- 基于vue.js的简单用户管理
功能描述:添加.修改.搜索过滤 效果图: <!DOCTYPE html> <html lang="en"> <head> <title&g ...
- MySQL 笔记整理(16) --“order by”是怎么工作的?
笔记记录自林晓斌(丁奇)老师的<MySQL实战45讲> (本篇内图片均来自丁奇老师的讲解,如有侵权,请联系我删除) 16) --“order by”是怎么工作的? 在林老师的课程中,第15 ...
- asp.net mvc前台显示带htm标签的解决办法(Razor —@Html.Raw())
数据是从后台富文本编辑后丢在数据库后取出的,不加Html.Raw(),前台就会把Html标签一同显示
- ThinkPHP 5.0/5.1 自定义404界面的配置
★ 背景还要啥背景,就是觉得不可能用框架自带的 404 界面呗.可能跟之前的版本配置方法有点区别,在此做一下简单的笔记 框架:ThinkPHP 5.1,ThinkPHP5.0.20 ★ 配置过程♩. ...
- SAP MM A工厂下的PR可以转成B工厂下的PO?
SAP MM A工厂下的PR可以转成B工厂下的PO? 答案是可能的,这也是SAP标准行为之一. 如下图采购申请单据, PR中的Plant是GENL.该PR 已经转成了PO,如上图. 看这个PO,工厂代 ...