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 相关文章推荐
基于JQuery实现鼠标点击文本框显示隐藏提示文本
Feb 23 Javascript
javascript在当前窗口关闭前检测窗口是否关闭
Sep 29 Javascript
AngularJS的内置过滤器详解
May 14 Javascript
JavaScript中split与join函数的进阶使用技巧
May 03 Javascript
JS实现放大、缩小及拖拽图片的方法【可兼容IE、火狐】
Aug 23 Javascript
详解JS去重及字符串奇数位小写转大写
Dec 29 Javascript
两种简单的跨域方法(jsonp、php)
Jan 02 Javascript
10道典型的JavaScript面试题
Mar 22 Javascript
Vue+Webpack完美整合富文本编辑器TinyMce的方法
Nov 30 Javascript
bootstrap 日期控件 datepicker被弹出框dialog覆盖的解决办法
Jul 09 Javascript
layui 关闭open弹出框 刷新table表格页面的方法
Sep 16 Javascript
ES6中Promise的使用方法实例总结
Feb 18 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 CURL获取cookies模拟登录的方法
2013/11/04 PHP
PHP中exec函数和shell_exec函数的区别
2014/08/20 PHP
ThinkPHP表单数据智能写入create方法实例分析
2015/09/27 PHP
php实现基于openssl的加密解密方法
2016/09/30 PHP
PHP三种方式实现链式操作详解
2017/01/21 PHP
javascript下IE与FF兼容函数收集
2008/09/17 Javascript
jquery插件实现鼠标经过图片右侧显示大图的效果(类似淘宝)
2013/02/04 Javascript
JavaScript静态类型检查工具FLOW简介
2015/01/06 Javascript
dul无法加载bootstrap实现unload table/user恢复
2016/09/29 Javascript
jQuery实现的checkbox级联选择下拉菜单效果示例
2016/12/26 Javascript
jQuery自定义插件详解及实例代码
2016/12/29 Javascript
Javascript中 带名 匿名 箭头函数的重要区别(推荐)
2017/01/29 Javascript
详解JavaScript 中getElementsByName在IE中的注意事项
2017/02/21 Javascript
js实现登录注册框手机号和验证码校验(前端部分)
2017/09/28 Javascript
angular的输入和输出的使用方法
2018/09/22 Javascript
微信小程序动态设置图片大小的方法
2019/11/21 Javascript
node.js express捕获全局异常的三种方法实例分析
2019/12/27 Javascript
微信小程序使用自定义组件导航实现当前页面高亮
2020/01/02 Javascript
[50:22]完美盛典-2018年度红毯走秀
2018/12/16 DOTA
python常用函数详解
2016/09/13 Python
Python编程实现数学运算求一元二次方程的实根算法示例
2017/04/02 Python
Python3之读取连接过的网络并定位的方法
2018/04/22 Python
python实现数据导出到excel的示例--普通格式
2018/05/03 Python
Python自带的IDE在哪里
2020/07/01 Python
Pandas的数据过滤实现
2021/01/15 Python
关于解决iframe标签嵌套问题的解决方法
2020/03/04 HTML / CSS
Structs界面控制层技术
2013/10/11 面试题
家长会演讲稿范文
2014/01/10 职场文书
运动会的口号
2014/06/09 职场文书
党员学习群众路线心得体会
2014/11/04 职场文书
深入开展党的群众路线教育实践活动心得体会
2014/11/05 职场文书
学生犯错保证书
2015/05/09 职场文书
公司开业主持词
2015/07/02 职场文书
工作会议简报
2015/07/20 职场文书
2019大学生预备党员转正思想汇报
2019/06/21 职场文书
整理Python中常用的conda命令操作
2021/06/15 Python