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 相关文章推荐
经典的解除许多网站无法复制文字的绝招
Dec 31 Javascript
js 页面传参数时 参数值含特殊字符的问题
Dec 13 Javascript
JavaScript数字和字符串转换示例
Mar 26 Javascript
jQuery简单实现日历的方法
May 04 Javascript
详解Vue.js入门环境搭建
Mar 17 Javascript
Angular中$state.go页面跳转并传递参数的方法
May 09 Javascript
js+css实现打字效果
Jun 24 Javascript
JavaScript求一个数组中重复出现次数最多的元素及其下标位置示例
Jul 23 Javascript
解决bootstrap模态框数据缓存的问题方法
Aug 10 Javascript
如何使用 vue + d3 画一棵树
Dec 03 Javascript
JavaScript惰性求值的一种实现方法示例
Jan 11 Javascript
微信小程序订阅消息(java后端实现)开发
Jun 01 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中的实现trim函数代码
2007/03/19 PHP
php启用sphinx全文搜索的实现方法
2014/12/24 PHP
Zend Framework基本页面布局分析
2016/03/19 PHP
Laravel框架使用技巧之使用url()全局函数返回前一个页面的地址方法详解
2020/04/06 PHP
jquery BS,dialog控件自适应大小
2009/07/06 Javascript
基于Jquery+Ajax+Json的高效分页实现代码
2011/10/29 Javascript
JS高级调试技巧:捕获和分析 JavaScript Error详解
2014/03/16 Javascript
JS中实现简单Formatter函数示例代码
2014/08/19 Javascript
javascript实现base64 md5 sha1 密码加密
2015/09/09 Javascript
thinkphp实现无限分类(使用递归)
2015/12/19 Javascript
JavaScript程序中实现继承特性的方式总结
2016/06/24 Javascript
AngularJS 中使用Swiper制作滚动图不能滑动的解决方法
2016/11/15 Javascript
Vue中的Vux配置指南
2017/12/08 Javascript
脚手架vue-cli工程webpack的基本用法详解
2018/09/29 Javascript
require.js 加载过程与使用方法介绍
2018/10/30 Javascript
js实现网页同时进行多个倒计时功能
2019/02/25 Javascript
稍微学一下Vue的数据响应式(Vue2及Vue3区别)
2019/11/21 Javascript
Vue混入mixins滚动触底的方法
2019/11/22 Javascript
RxJS在TypeScript中的简单使用详解
2020/04/13 Javascript
vue+element使用动态加载路由方式实现三级菜单页面显示的操作
2020/08/04 Javascript
基于vue.js仿淘宝收货地址并设置默认地址的案例分析
2020/08/20 Javascript
Postman无法正常返回结果问题解决
2020/08/28 Javascript
vue使用transition组件动画效果的实例代码
2021/01/28 Vue.js
通过Python 接口使用OpenCV的方法
2018/04/02 Python
Python 输出时去掉列表元组外面的方括号与圆括号的方法
2018/12/24 Python
使用Python自动生成HTML的方法示例
2019/08/06 Python
解决django model修改添加字段报错的问题
2019/11/18 Python
HTML5通过调用canvas对象的getContext()方法来获取绘图环境
2014/06/23 HTML / CSS
html5教你做炫酷的碎片式图片切换 (canvas)
2017/07/28 HTML / CSS
为什么group by 和order by会使查询变慢
2014/05/16 面试题
jQuery treeview树形结构应用
2021/03/24 jQuery
后勤人员岗位职责
2013/12/17 职场文书
公务员上班玩游戏检讨书
2014/09/17 职场文书
小学少先队活动总结
2015/05/08 职场文书
赞美教师的句子
2019/09/02 职场文书
详解Django中 render() 函数的使用方法
2021/04/22 Python