NodeJs之文件上传

一,介绍与需求

1.1,介绍

1,multer模块

multer用于处理文件上传的nodejs中间件,主要跟express框架搭配使用,只支持表单MIME编码为multipart/form-data类型的数据请求.

2,fs模块

fs模块用于对系统文件及目录进行读写操作。

1.2,需求

上传并操作文件与文件目录

二,配置实现

2.1,multer模块

第一步:安装multer模块

  1. cnpm install multer --save

第二步:引入multer模块,构造multer对象: multer(opt)

opt是个key-value对象,包含属性dest/storage,fileFilter,limits.分表表示文件的存储位置/方式,文件过滤,文件大小限制.如下:

  1. var moment = require("moment");
  2. var express = require("express");
  3. var multer = require('multer');
  4. var storage = multer.diskStorage({
  5. //文件存储路径
  6. destination: function (req, file, cb) {
  7. cb(null, path.join(__dirname, "/../uploads/temps"));
  8. },
  9. //修改上传文件的名字
  10. //file 是个文件对象 ,fieldname对应在客户端的name属性
  11. //存储的文件需要自己加上文件的后缀,multer并不会自动添加
  12. //这里直接忽略文件的后缀.
  13. filename: function (req, file, cb) {
  14. var date = new Date();
  15. cb(null, moment().format("YYYYMMDDhhmmss") + file.originalname);
  16. }
  17. });
  18. let objMulter = multer({storage : storage });

如果初始化multer时候没有指定dest或者storage,上传的文件将保存在内存中,永远不会写入到磁盘中,在storage中如果没有指定destination值,那么上传的文件将存储在系统默认的临时文件夹.

  1. multer关联的文件信息:
  2.  
  3. filedname : form表单中指定的name属性值
  4. orginalname : 原始文件名
  5. encoding : 文件编码方式
  6. mimetype : 多媒体类型
  7. size : 文件大小,单位b
  8. destination : 文件上传后存储在服务端的路径
  9. filename : 文件在服务端的命名
  10. path : 文件在服务端的完整路径
  11. buffer : 文件二进制数据
  12.  
  13. ps:其中destination,filenamepath只有在指定storage属性时候有效.而buffer只有文件在内存中存储时候有效.

multer同时提供了single/array/fields/any方法用于对接受文件数的控制.

  1. single(fieldname) 接收单个文件,通过req.file访问该文件
  2. array(fieldnaem,[maxcount]) 接收多个文件,通过req.files数组方法文件.maxcount指定接收文件最大数.
  3. fields(fields) 接受指定fieldname的文件,fieldname由客户端决定,通过req.files数组方法
  4. any 接收所有文件上传,通过req.files访问文件

2.2,fs模块

第一步:安装fs模块,也可直接引用,node默认集成

  1. cnpm install fs --save//项目目录安装
  2. var fs = require("fs");//直接引入文件系统模块

第二步:介绍fs模块的方法

  1. var fs = require('fs'); // 载入fs模块

1,删除指定文件:fs.unlink(path,callback)

path参数为该文件的绝对物理路径,callback回调参数当中只有一个错误信息参数err,一般在该文件不存在或者删除文件失败时触发调用。

  1. fs.unlink('/tmp/234.txt', function(err) {
  2. if (err) {
  3. throw err;
  4. }
  5. console.log('成功删除了 /tmp/234.txt');
  6. });

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回调参数当中有两个参数errdata,其中err为错误信息参数,一般在在文件不存在或者读取文件失败时触发调用,data为文件内容。

  1. 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参数可选,可以传入编码格式,若不传则默认为utf8callback回调参数当中只有一个错误信息参数err,一般在写入失败时触发调用。

  1. // 写入文件内容(如果文件不存在会创建一个文件)
  2. // 传递了追加参数 { 'flag': 'a' }
  3. fs.writeFile('./test2.txt', 'test test', { 'flag': 'a' }, function(err) {
  4. if (err) {
  5. throw err;
  6. }
  7.  
  8. console.log('Saved.');
  9.  
  10. // 写入成功后读取测试
  11. fs.readFile('./test2.txt', 'utf-8', function(err, data) {
  12. if (err) {
  13. throw err;
  14. }
  15. console.log(data);
  16. });
  17. });

flag传值,r代表读取文件,w代表写文件,a代表追加。

  1. // 追加写入
  2. fs.appendFile("2.txt","我是追加的字符",function (err) {
  3. if(err){
  4. return console.log(err);
  5. }else {
  6. console.log("追加成功");
  7. }
  8. })

4,检测文件是否存在:fs.exists(path,callback)

path参数传入该文件的绝对物理路径,该callback回调函数有个参数exists。exists为一个文件状态对象,是否存在。

  1. var dest_Dir = path.join(__dirname.replace("routes", ""), "uploads", destDir);
  2. fs.exists(dest_Dir, function (exists) {
  3. if (exists) {
  4. //存在
  5. }
  6. else {
  7.  
  8. }
  9. });

5,移动或重命名指定文件:fs.rename(oldPath,newPath,callback)

oldPath参数为该文件原来的路径,newPath参数为该文件移动或重命名之后的路径,这两个参数都必须能传入文件完整的绝对物理路径。callback回调参数当中只有一个错误信息参数,一般在oldPath当中指定的文件不存在或者该操作失败时触发调用。

  1. fs.rename(sourceFile, destPath, function (err) {
  2. res.status(200).json({
  3. httpCode: 200,
  4. message: '上传成功',
  5. data: {
  6. "fileurl": fileurl
  7. },
  8. });
  9. });

6,创建一个目录文件夹:fs.mkdir(path[,model],callback)

path为该目录的绝对物理路径,callback回调函数当中也只有一个错误信息参数,一般在目录创建失败时触发调用。

  1. fs.mkdir(dest_Dir, 0777, function (err) {
  2. if (err) {
  3. res.status(500).json({
  4.  
  5. } else {
  6. //创建目录成功,上传文件
  7. fs.rename(sourceFile, destPath, function (err) {
  8. res.status(200).json({
  9. httpCode: 200,
  10. message: '上传成功',
  11. data: {
  12. "fileurl": fileurl
  13. },
  14. });
  15. });
  16. }
  17. })

7,读取目录文件夹:fs.readdir(path,callback)

path为该目录的绝对物理路径,callback回调函数当中有两个参数errfileserr为错误信息参数,一般在该目录不存在或读取失败时触发调用,files为一个数组对象,包含该目录下的所有文件夹与文件的名字。(仅为文件夹的名字和文件名,不是路径形式)。

  1. fs.readdir('./newdir', function(err, files) {
  2. if (err) {
  3. throw err;
  4. }
  5. // files是一个数组
  6. // 每个元素是此目录下的文件或文件夹的名称
  7. console.log(files);
  8. });

8,删除一个空文件夹:fs.rmdir(path,callback)

path为该目录的绝对物理路径,callback回调函数当中也只有一个错误信息参数,一般在该目录不存在或者删除操作失败时触发调用。

  1. fs.rmdir('/tmp', function(err) {
  2. if (err) {
  3. throw err;
  4. }
  5. console.log('成功删除了 空文件夹 tmp');
  6. });

以上的实例均是异步操作,如果需同步操作在函数后面加Sync既可

  1. //同步 所有同步的函数都是函数后面加Sync;
  2. var res = fs.writeFileSync("1.txt","我是写入内容");

2.3,文件上传

1,单文件上传

  1. router.post('/upload', upload.single('file'), function (req, res, next) {
  2. var fileName = req.file.filename;
  3. var destDir = req.body.dir == undefined ? "default" : req.body.dir;
  4. var sourceFile = req.file.path;
  5. var destPath = path.join(__dirname.replace("routes", ""), "uploads", destDir, fileName);
  6. var dest_Dir = path.join(__dirname.replace("routes", ""), "uploads", destDir);
  7. var fileurl = uploadFileDomin + destPath.substr(destPath.indexOf("uploads"));
  8. fileurl = fileurl.replace(/\\/g, "/");
  9. fs.exists(dest_Dir, function (exists) {
  10. if (exists) {
  11. fs.rename(sourceFile, destPath, function (err) {
  12. res.status(200).json({
  13. httpCode: 200,
  14. message: '上传成功',
  15. data: {
  16. "fileurl": fileurl
  17. },
  18. });
  19. });
  20. }
  21. else {
  22. fs.mkdir(dest_Dir, 0777, function (err) {
  23. if (err) {
  24. res.status(500).json({
  25. httpCode: 500,
  26. message: err,
  27. data: [],
  28. });
  29. } else {
  30. fs.rename(sourceFile, destPath, function (err) {
  31. res.status(200).json({
  32. httpCode: 200,
  33. message: '上传成功',
  34. data: {
  35. "fileurl": fileurl
  36. },
  37. });
  38. });
  39. }
  40. })
  41. }
  42. });
  43.  
  44. });

2,多文件上传

  1. router.post('/uploads', upload.array('file', 8), function (req, res, next) {
  2. var paths = [];
  3. for (var i = 0; i < req.files.length; i++) {
  4. var path = req.files[i].path.replace(/\\/g, "/");
  5. var fileurl = uploadFileDomin + path.substr(path.indexOf("uploads")).replace('\\', '/');
  6. paths.push(fileurl);
  7. }
  8. res.status(200).json({
  9. httpCode: 200,
  10. message: '上传成功',
  11. "fileurls": paths,
  12. });
  13. });

最后抛出发送上传接口:

  1. app.use("/api", require("./fileUploadApi.js"));

三,前端调用

3.1,单文件上传调用

1,简单html

  1. <span>ajax upload</span>
  2. <div class="container">
  3. <label>file</label>
  4. <input type="file" name="file" id="file">
  5. <input type='button' value='上传' id="btn_upload" />
  6. </div>

2,js调用

  1. $("#btn_upload").click(function () {
  2. //创建一个FormDate
  3. var formData = new FormData();
  4. //将文件信息追加到其中
  5. formData.append('file', file.files[0]);
  6. formData.append('dir', 'attachment');
  7. //formData.append('name', file.files[0].name);
  8. $.ajax({
  9. url: "http://localhost:3000/api/" + 'upload',
  10. type: 'POST',
  11. data: formData,
  12. cache: false,
  13. contentType: false,
  14. processData: false,
  15. xhrFields: {
  16. withCredentials: true
  17. },
  18. crossDomain: true,
  19. success: function (data) {
  20. callBack(data);
  21. },
  22. error: function (response) {
  23. console.log("error is :" + response);
  24. }
  25. });

3,实现效果

3.2,多文件上传调用

1,简单html

  1. <span>ajax multi files upload</span>
  2. <div class="container">
  3. <label>file</label>
  4. <input type="file" name="file" id="files1">
  5. <input type="file" name="file" id="files2">
  6. <input type="file" name="file" id="files3">
  7. <input type='button' value='上传' id="btn_uploads" />
  8. </div>

2,js调用

  1. var files1 = $("#files1")[0];
  2. var files2 = $("#files2")[0];
  3. var files3 = $("#files3")[0];
  4. $("#btn_uploads").click(function () {
  5. //创建一个FormDate
  6. var formData = new FormData();
  7. //将文件信息追加到其中
  8. formData.append('file', files1.files[0]);
  9. formData.append('file', files2.files[0]);
  10. formData.append('file', files3.files[0]);
  11. $.ajax({
  12. url: 'http://localhost:3000/api/' + 'uploads',
  13. type: 'POST',
  14. data: formData,
  15. contentType: false,
  16. processData: false,
  17. async: false,
  18. xhrFields: {
  19. withCredentials: true
  20. },
  21. crossDomain: true,
  22. success: function (data) {
  23. callBack(data.fileurls);
  24. },
  25. error: function (response) {
  26. console.log("error is :" + response);
  27. }
  28. })
  29. })

3,实现效果

NodeJs之文件上传的更多相关文章

  1. Nodejs express 文件上传

    文件上传 以下我们创建一个用于上传文件的表单,使用 POST 方法,表单 enctype 属性设置为 multipart/form-data. index.htm 文件代码修改如下: <html ...

  2. nodejs实现文件上传

    在使用ant-design的upload上传文件时,前端很好实现,那么我们如何实现node服务端呢? 服务端文件上传实现 var express = require('express'); var f ...

  3. nodejs+multiparty 文件上传

    通过表单提交上传文件:     html代码 <form action="/uploadFile" method="post" enctype=" ...

  4. nodeJs实现文件上传,下载,删除

    转:https://blog.csdn.net/qq_36228442/article/details/81709272 一.简介 本文介绍了nodeJs+express框架下,用multer中间件实 ...

  5. nodejs应用:文件上传

    功能:上传文件到服务器,图片支持客户端本地预览. 服务端 //server.js 'use strict';const http = require('http');const url = requi ...

  6. 【nodejs】文件上传demo实现

    文件结构: index.js var server = require('./server.js'); var router = require('./router.js'); var request ...

  7. Html5+NodeJS——拖拽多个文件上传到服务器

    实现多文件拖拽上传的简易Node项目,可以在github上下载,你可以先下载下来:https://github.com/Johnharvy/upLoadFiles/. 解开下载下的zip格式包,建议用 ...

  8. Nodejs进阶:基于express+multer的文件上传

    关于作者 程序猿小卡,前腾讯IMWEB团队成员,阿里云栖社区专家博主.欢迎加入 Express前端交流群(197339705). 正在填坑:<Nodejs学习笔记> / <Expre ...

  9. nodejs学习之文件上传

    最近要做个图片上传的需求,因为服务端春节请假回家还没来,所以就我自己先折腾了一下,大概做出来个效果,后台就用了nodejs,刚开始做的时候想网上找一下资料,发现大部分资料都是用node-formida ...

随机推荐

  1. C#多线程之旅~上车吧?

    前言:前几天,写了一篇关于多线程使用的文章,[线程使用]用法得到不少博友的好评,博主这几天加班写文章,把剩下的高级使用给写完,期望可以得到博友的追赞吧,那么废话不多说,开始我们的C#高级用法之旅!! ...

  2. springboot~lombok使用总结

    @Getter & @Setter 生成getter和setter块 @Data注解 @Data相当于@Getter @Setter @RequiredArgsConstructor @ToS ...

  3. spring-boot-starter-actuator /info获取空信息

    用了spring-boot-starter-actuator,在监控页面对应服务中显示空值,下面是正常情况下有的值 pom配置了 <build> <plugins> <p ...

  4. Python:鲜为人知的功能特性(下)

    GitHub 上有一个名为<What the f*ck Python!>的项目,这个有趣的项目意在收集 Python 中那些难以理解和反人类直觉的例子以及鲜为人知的功能特性,并尝试讨论这些 ...

  5. SLAM+语音机器人DIY系列:(四)差分底盘设计——2.stm32主控软件设计

    摘要 运动底盘是移动机器人的重要组成部分,不像激光雷达.IMU.麦克风.音响.摄像头这些通用部件可以直接买到,很难买到通用的底盘.一方面是因为底盘的尺寸结构和参数是要与具体机器人匹配的:另一方面是因为 ...

  6. python基于函数替换的热更新原理介绍

    热更新即在不重启进程或者不离开Python interpreter的情况下使得被编辑之后的python源码能够直接生效并按照预期被执行新代码.平常开发中,热更能极大提高程序开发和调试的效率,在修复线上 ...

  7. python3-随机生成10位包含数字和字母的密码

    方法一: 知识点:random.sample(sequence, k) 从指定序列中随机获取指定长度的片断 import random,string num=string.ascii_letters+ ...

  8. GOF23种设计模式概括

    GOF23种设计模式分为三种: 创建型模式[工厂方法模式]结构型模式[(类)适配器模式]行为型模式[ 解释器模式,模板方法模式]   创建型模式Creational Patterns抽象工厂模式abs ...

  9. SpringAOP术语

    2019-03-10/21:12:31 参考博客:MiroKlose AOP术语 1.通知: 通知定义了切面要完成的工作内容和何时完成工作,就是什么时候去做辅助功能,功能具体是什么代码 五种类型 Be ...

  10. 复活广州.net俱乐部

    上个月张队长在深圳搞了一场活动,我们广州这边的.net粉丝也去了几个,我刚好有辆破车,于是我们一车会合后出发去深圳参加活动了,和大家在车上的交流使我感触良多.只说几点和本文相关的: .net在中国的生 ...