node.js使用express-fileupload中间件实现文件上传


Posted in Javascript onJuly 16, 2021

本文使用express作为服务端,使用express-fileupload库提供的中间件函数来接受从客户端传来的图片,并将图片作为文件存储在服务端。客户端使用create-react-app框架,bootstrap UI,axios发送http请求和提供进度条当前进度的值,上传成功后,根据图片在服务端上的位置,并显示图片。

初始化项目

mkdir react-file-upload    // 创建项目根目录
cd react-file-upload
npm init -y                // 初始化 npm 创建 package.json

安装一些必要依赖(dependencies)

npm i express express-fileupload
npm i -D nodemon concurrently    // 可以并行同时运行客户端和服务端(在本机进行测试)

更改 react-file-upload/package.json 中的 scripts 脚本

{
  "main": "server.js",
  "script" : {
    "start": "node server.js", 
    "server": "nodemon server.js",
    "client": "npm start --prefix client",  
    "dev": " concurrently \"npm run server\" \"npm run client\" "
  }
}
  • main 改为 server.js
  • start 使用 node 启动 express
  • server 使用 nodemon 启动 express ,nodemon会监视server.js文件是否有变动 (ctrl+S) 若有变动 重新启动服务器 而node启动则不会,需要手动重启服务(ctrl+C 且改动文件后重新运行 node server.js)
  • client 启动客户端 随后我们会创建 client 文件夹 编写 react 组件
  • dev 使用 concurrently 同时启动服务端与客户端

编写服务器

下面来编写 server.js 文件

const express = require('express');
const fileUpload = require('express-fileupload');

const app = express();
// 使用 express-fileupload 中间件
app.use( fileUpload() );

// 处理由 /upload 页面发送过来的post请求
app.post('/upload', (req, res) => {
  // req 中的 files 属性由 express-fileupload 中间件添加!? (疑问暂存)
  // 判断 files 属性是否存在 和 是否有文件传来 若无返回400
  if(req.files === null){
    return res.status(400).json({msg:'no file uploaded'});
  }
  // 否则 获取文件
  // file 由后文中 formData.append('file', file) 的第一个参数定义 可自定义为其他名称
  const file = req.files.file;
  // 移动文件到第一参数指定位置 若有错误 返回500
  file.mv(`${__dirname}/client/public/uploads/${file.name}`, err => {
    if(err){
      console.error(err);
      return res.status(500).send(err);
    }
    // 若无错误 返回一个 json 
    // 我们计划上传文件后 根据文件在服务器上的路径 显示上传后的文件
    // 随后我们会在 react 组件中实现
    // 在客户端中的 public 文件夹下创建 uploads 文件夹 用于保存上传的文件
    res.json({fileName: file.name, filePath: `uploads/${file.name}`});
  });
});

app.listen(5000,() => {console.log('Server started...')});

现在运行一遍 server.js 保证无错误 会在控制台看到 Server started...

npm run server

node.js使用express-fileupload中间件实现文件上传

初始化客户端

然后我们创建客户端 我们使用 create-react-app 脚手架初始化项目

npx create-react-app client

初始化完成后 我们可以先选择性的删除一些不必要的文件

  • serviceWorker.js
  • logo.svg
  • index.css    // 之后我们会用link标签从cdn引入bootstrap的
  • App.test.js  // 只是个小demo

我们删除 src / index.js 文件中引入的 index.css,在 public 文件夹中的 index.html 模板文件中,直接引入bootstrap 的 css 和 js

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico" rel="external nofollow"  />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta name="theme-color" content="#000000" />
    <!-- 引入css -->
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="external nofollow"  integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
    <link rel="manifest" href="%PUBLIC_URL%/manifest.json" rel="external nofollow"  />
    <title>React File Uploader</title>
  </head>
  <body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
    <!-- 引入js -->
    <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js" integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1" crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>
  </body>
</html>

编写组件

我们总共需要编写3各组件,分别为

  • FileUpload.js:用form标签的onSubmit和axios发送上传请求
  • Message.js:显示信息 上传成功 服务器错误 或 没有选择文件
  • Progress.js:用axios的onUploadProgress和bootstrap显示上传进度条

FileUpload

import React, { useState } from 'react'
import axios from 'axios'
import Message from './Message'
import Progress from './Progress'

const FileUpload = () => {

  return (
    <div>
      {message ? <Message msg={message} /> : null}
      <form onSubmit={onSubmit}>
        <div className="custom-file mb-4">
          <input type="file" className="custom-file-input" id="customFile" onChange={onChange}></input>
          <label className="custom-file-label" htmlFor="customFile">{filename}</label>
        </div>
        <Progress percentage={uploadedPercentage}></Progress>
        <input className="btn btn-primary btn-block mt-4" type="submit" value="Upload"></input>
      </form>
      {
        uploadedFile ? 
          <div className="row mt-5">
            <div className="col-md-6 m-auto">
              <h3 className="text-center">{uploadedFile.name}</h3>
              <img style={{width:'100%'}} src={uploadedFile.filePath} alt=""></img>
            </div>
          </div> :
          <p>nothing uploaded yet...</p>
      }
    </div>
  )
}
export default FileUpload

Message.js

import React from 'react'
import PropTypes from 'prop-types'

const Message = ({msg}) => {
  console.log('her')
  return (
    <div className="alert alert-info alert-dismissible fade show" role="alert">
      {msg}
      <button type="button" className="close" data-dismiss="alert" aria-label="Close">
        <span aria-hidden="true">&times;</span>
      </button>
    </div>
  )
}
Message.propTypes = {
  msg: PropTypes.string.isRequired,
}
export default Message

Progress.js

import React from 'react'
import PropTypes from 'prop-types'

const Progress = ({percentage}) => {
  return (
    <div className="progress">
      <div className="progress-bar" role="progressbar" 
        style={{ width: `${percentage}%` }} 
        aria-valuenow={percentage} aria-valuemin="0" aria-valuemax="100">{percentage}%</div>
    </div>
  )
}
Progress.propTypes = {
  percentage: PropTypes.number.isRequired,
}
export default Progress

测试

目前为止,全部的功能组件都已完成。

npm run dev

node.js使用express-fileupload中间件实现文件上传

最后附上git地址 Git

到此这篇关于node.js使用express-fileupload中间件实现文件上传的文章就介绍到这了,更多相关node.js 文件上传内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
通过ifame指向的页面高度调整iframe的高度
Oct 05 Javascript
JavaScript对象模型-执行模型
Apr 28 Javascript
JavaScript语言核心数据类型和变量使用介绍
Aug 23 Javascript
JavaScript简单实现弹出拖拽窗口(一)
Jun 17 Javascript
深入浅析JavaScript中的3DES
Aug 24 Javascript
jquery插件bootstrapValidator表单验证详解
Dec 15 Javascript
基于vuejs实现一个todolist项目
Apr 11 Javascript
javascript 中关于array的常用方法详解
May 05 Javascript
微信小程序 如何引入外部字体库iconfont的图标
Jan 31 Javascript
原生js实现移动端Touch轮播图的方法步骤
Jan 03 Javascript
jQuery动态生成的元素绑定事件操作实例分析
May 04 jQuery
在vue中使用Base64转码的案例
Aug 07 Javascript
html5 录制mp3音频支持采样率和比特率设置
js基础语法与maven项目配置教程案例
JavaScript与JQuery框架基础入门教程
Jul 15 #Javascript
Python机器学习之决策树和随机森林
微信小程序scroll-view不能左右滑动问题的解决方法
Vue Element-ui表单校验规则实现
Jul 09 #Vue.js
JavaScript数组reduce()方法的语法与实例解析
Jul 07 #Javascript
You might like
php empty()与isset()区别的详细介绍
2013/06/17 PHP
Eclipse的PHP插件PHPEclipse安装和使用
2014/07/20 PHP
WordPress中使主题支持小工具以及添加插件启用函数
2015/12/22 PHP
PHP后台微信支付和支付宝支付开发
2017/04/28 PHP
JavaScript 新手24条实用建议[TUTS+]
2009/06/21 Javascript
JS/jQuery实现默认显示部分文字点击按钮显示全部内容
2013/05/13 Javascript
javascript break指定标签打破多层循环示例
2014/01/20 Javascript
JavaScript获取XML数据附示例截图
2014/03/05 Javascript
js实现图片从左往右渐变切换效果的方法
2015/02/06 Javascript
原生Js实现简易烟花爆炸效果的方法
2015/03/20 Javascript
JQuery遍历DOM节点的方法
2015/06/11 Javascript
浅析JS获取url中的参数实例代码
2016/06/14 Javascript
vuejs2.0子组件改变父组件的数据实例
2017/05/10 Javascript
手把手教你使用vue-cli脚手架(图文解析)
2017/11/08 Javascript
js图片查看器插件用法示例
2019/06/22 Javascript
vue+koa2搭建mock数据环境的详细教程
2020/05/18 Javascript
如何使用gpu.js改善JavaScript的性能
2020/12/01 Javascript
[01:00]一分钟回顾2018DOTA2亚洲邀请赛现场活动
2018/04/07 DOTA
Python 多线程不加锁分块读取文件的方法
2018/12/11 Python
python 在指定范围内随机生成不重复的n个数实例
2019/01/28 Python
Python实现连接MySql数据库及增删改查操作详解
2019/04/16 Python
解决Django中修改js css文件但浏览器无法及时与之改变的问题
2019/08/31 Python
Python将视频或者动态图gif逐帧保存为图片的方法
2019/09/10 Python
关于Keras模型可视化教程及关键问题的解决
2020/01/24 Python
Python爬虫Scrapy框架CrawlSpider原理及使用案例
2020/11/20 Python
澳大利亚男士西服品牌:M.J.Bale
2018/02/06 全球购物
ABOUT YOU匈牙利:500个最受欢迎的时尚品牌
2019/07/19 全球购物
高校教师岗位职责
2014/03/18 职场文书
电气自动化求职信
2014/06/24 职场文书
学校总务处领导班子民主生活会对照检查材料思想汇报
2014/09/27 职场文书
正风肃纪剖析材料
2014/09/30 职场文书
副总经理党的群众路线教育实践活动个人对照检查材料思想汇报
2014/10/06 职场文书
聘任书范文大全
2015/09/21 职场文书
2020年元旦祝福语录,总有适合你的
2019/12/31 职场文书
jdbc使用PreparedStatement批量插入数据的方法
2021/04/27 MySQL
利用uni-app生成微信小程序的踩坑记录
2022/04/05 Javascript