NodeJS

上传文件到服务端

文件上传

代码示例:

var express = require('express');
var router = express.Router();

/* GET home page. */
router.get('/', function (req, res, next) {
    res.render('index', {title: 'Express'});
});

module.exports = router;
// routes/upload.js

var express = require('express');
var router = express.Router();

/* GET home page. */
router.get('/', function (req, res, next) {
    res.render('upload', {title: 'Express'});
});

module.exports = router
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');

var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var loginRouter = require('./routes/login');
var uploadRouter = require('./routes/upload')

var session = require('express-session')
var MongoStore = require('connect-mongo')

var app = express();

var JWT = require('./util/JWT')

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');

app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({extended: false}));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

app.use(session({
    name: 'cookieName',
    secret: 'abcdefg',
    cookie: {
        maxAge: 1000 * 60 * 60,
        secure: false
    },
    resave: true,
    saveUninitialized: true,
    store: MongoStore.create({
        mongoUrl: 'mongodb://127.0.0.1:27017/test',
        ttl: 1000 * 60 * 10
    })
}))

app.use((req, res, next) => {
    if (req.url.includes('login')) {
        next()
        return
    }

    // console.log(req.headers[authorization]?.split(' ')[1])
    const token = req.headers['authorization']?.split(' ')[1]
    if (token) {
        const payload = JWT.verify(token)
        if (payload) {
            const newToken = JWT.generate({
                _id: payload._id,
                username: payload.username
            }, '1h')
            res.header('Authorization', newToken)
            next()
        } else {
            res.status(401).send({errCode: -1, errInfo: 'token失效了'})
        }
    } else {
        next()
    }
})

app.use('/', indexRouter);
app.use('/api', usersRouter);
app.use('/login', loginRouter);
app.use('/upload', uploadRouter)

// catch 404 and forward to error handler
app.use(function (req, res, next) {
    next(createError(404));
});

// error handler
app.use(function (err, req, res, next) {
    // set locals, only providing error in development
    res.locals.message = err.message;
    res.locals.error = req.app.get('env') === 'development' ? err : {};
    // render the error page
    res.status(err.status || 500);
    res.render('error');
});

module.exports = app;
// model/UserModel.js

const mongoose = require('mongoose')

const UserType = {
    username: String,
    pwd: String,
    age: Number,
    avatar: String
}

const Schema = new mongoose.Schema(UserType)

const UserModel = mongoose.model('user', Schema)

module.exports = UserModel
// services/UserService.js

const UserModel = require("../model/UserModel");

const UserService = {
    addUser: (username, pwd, age, avatar) => {
        return UserModel.create({
            username,
            pwd,
            age,
            avatar
        })
    },
    updateUser: (req, username, pwd, age) => {
        return UserModel.updateOne({_id: req.params.id}, {
            username,
            pwd,
            age
        })
    },
    deleteUser: (req) => {
        return UserModel.deleteOne({_id: req.params.id})
    },
    getUser: (page, limit) => {
        return UserModel.find({}, ['username', 'age', 'avatar'])
            .sort({age: 1})
            .skip((page - 1) * limit)
            .limit(limit)
    },
    login: (username, pwd) => {
        return UserModel.find({username, pwd})
    }
}

module.exports = UserService
// controllers/UserController.js

const UserService = require('../services/UserService')

const JWT = require('../util/JWT')

const UserController = {
    addUser: (req, res) => {
        const {username, pwd, age} = req.body
        const avatar = req.file ? `/uploads/${req.file.filename}` : `/images/默认头像.png`  // multer自带的注入字段
        UserService.addUser(username, pwd, age, avatar)
            .then(data => {
                res.send({ok: 1})
            })
            .catch(err => console.log(err))
    },
    updateUser: (req, res) => {
        const {username, pwd, age} = req.body
        UserService.updateUser(req, username, pwd, age)
            .then(data => {
                res.send({ok: 1})
            })
            .catch(err => console.log(err))
    },
    deleteUser: (req, res) => {
        UserService.deleteUser(req)
            .then(data => {
                res.send({ok: 1})
            })
            .catch(err => console.log(err))
    },
    getUser: (req, res) => {
        const {page, limit} = req.query
        UserService.getUser(page, limit)
            .then(data => {
                res.send(data)
            })
    },
    login: (req, res) => {
        const {username, pwd} = req.body
        UserService.login(username, pwd)
            .then(data => {
                if (data.length === 0) {
                    res.send({ok: 0})
                } else {
                    const token = JWT.generate({
                        _id: data[0]._id,
                        username: data[0].username
                    }, '1h')
                    res.header('Authorization', token)
                    res.send({ok: 1})
                }
            })
            .catch(err => console.log(err))
    },
    logout: (req, res) => {
        req.session.destroy(() => {
            res.send({ok: 1})
        })
    }
}

module.exports = UserController
var express = require('express');
var router = express.Router();
const multer = require('multer')

// 默认随机文件名 + 无扩展名
const upload = multer({dest: 'public/uploads/'})  // 在指定目录下创建相应的文件夹以存放上传的文件

const UserController = require('../controllers/UserController')

// single:接收上传的文件并存放在指定目录下(avatar对应前端的name属性值)
// upload.array('avatar', 16):多图片上传且限制单次上传数量(req.files拿到数组)
router.post('/user', upload.single('avatar'), UserController.addUser)

router.put('/user/:id', UserController.updateUser)

router.delete('/user/:id', UserController.deleteUser)

router.get('/user', UserController.getUser)

router.post('/login', UserController.login)

router.get('/logout', UserController.logout)

module.exports = router;
<!-- views/upload.ejs -->

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>Upload</title>
</head>
<body>
<form action="/api/user" method="POST" enctype="multipart/form-data">
    <!-- multipart/form-data后端不能直接处理 -->
    <div>
        用户名:<input type="text" name="username"/>
    </div>
    <div>
        密码:<input type="password" name="pwd"/>
    </div>
    <div>
        年龄:<input type="number" name="age"/>
    </div>
    <div>
        头像:<input type="file" name="avatar"/>
    </div>
    <div>
        <input type='submit' value="提交">
    </div>
</form>
</body>
</html>
<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="UTF-8">
    <title><%= title %></title>
    <link rel='stylesheet' href='/stylesheets/style.css' />
  </head>
  <body>
    <div>
      <div>用户名:<input type="text" id="username"></div>
      <div>密码:<input type="password" id="pwd"></div>
      <div>年龄:<input type="number" id="age"></div>
      <div>头像:<input type="file" id="avatar"></div>  <!-- multiple属性:多图片上传 -->
      <div><button id="register">添加用户</button></div>
    </div>
    <div>
      <button id="update">更新用户</button>
      <button id="delete">删除用户</button>
    </div>
    <table>
      <thead>
      <tr>
        <td>id</td>
        <td>用户名</td>
        <td>年龄</td>
        <td>头像</td>
      </tr>
      </thead>
      <tbody>

      </tbody>
    </table>
    <div>
      <button id="exit">退出登录</button>
    </div>
    <script src="/dist/axios.min.js"></script>
    <script>
      axios.interceptors.request.use(function (config) {
        const token = localStorage.getItem('token')
        config.headers.Authorization = `Bearer ${token}`
        return config
      }, function (error) {
        return Promise.reject((error))
      })

      axios.interceptors.response.use(function (response) {
        // console.log(response.headers)
        const {authorization} = response.headers
        authorization && localStorage.setItem('token', authorization)
        return response
      }, function (error) {
        if (error.response.status === 401) {
          localStorage.removeItem('token')
          location.href = '/login'
        }
        return Promise.reject(error)
      })
    </script>
    <script>
      const register = document.querySelector('#register')
      const username = document.querySelector('#username')
      const pwd = document.querySelector('#pwd')
      const age = document.querySelector('#age')
      const update = document.querySelector('#update')
      const deleteButton = document.querySelector('#delete')
      const exit = document.querySelector('#exit')
      const avatar = document.querySelector('#avatar')
      register.onclick = () => {
        // console.log(avatar.files)
        const formsdata = new FormData()
        formsdata.append('username', username.value)
        formsdata.append('password', pwd.value)
        formsdata.append('age', age.value)
        formsdata.append('avatar', avatar.files[0])
        axios.post('/api/user', formsdata, {
          headers: {
            'Content-Type': 'multipart/form-data'
          }
        }).then(res => console.log(res.data)).catch(err => console.log(err))
      }
      deleteButton.onclick = () => {
        axios.delete('/api/user/6317fa3d99222afe82d61af5').then(res => console.log(res.data)).catch(err => console.log(err))
      }
      update.onclick = () => {
        axios.put('/api/user/6317decdeb469ce9190d8c5c', {
          username: 'username',
          pwd: 'password',
          age: 24
        }).then(res => console.log(res.data)).catch(err => console.log(err))
      }
      exit.onclick = () => {
        localStorage.removeItem('token')
        location.href = '/login'
      }
      axios.get('/api/user?page=1&limit=2').then(res => {
        const tbody = document.querySelector('tbody')
        tbody.innerHTML = res.data.map(item => `
                <tr>
                    <td>${item._id}</td>
                    <td>${item.username}</td>
                    <td>${item.age}</td>
                    <td><img src="${item.avatar}"/></td>
                </tr>
                `).join('')
      }).catch(err => console.log(err))
    </script>
  </body>
</html>