express+react实现上传文件

一、使用express+mongodb搭建后端服务

  • 1、安装依赖包

    npm install express
    # 处理跨域的中间件
    npm install cors 
    npm install mongoose
    # 上传文件的
    npm install multer
    
  • 2、expressapp.js文件

    const express = require("express");
    const path = require("path");
    const bodyParser = require("body-parser");
    const cors = require('cors');
    const {
          
           Task } = require("./models");
    
    const mongoose = require("mongoose");
    const {
          
           static } = require("express");
    const multer = require('multer');
    // connect
    // mongodb://username:password@host:port/database
    //mongoose.connect("mongodb://[email protected]:sqf0617.@localhost:27017/db", {
          
          
    mongoose.connect("mongodb://localhost:27017/db", {
          
          
      useCreateIndex: true,
      useNewUrlParser: true,
      useUnifiedTopology: true,
    });
    
    const app = express();
    // 配置可以提交json数据
    app.use(bodyParser.json());
    app.use(bodyParser.urlencoded({
          
           extended: true }));
    app.use(static("public"));
    app.use(cors()); // 跨域中间件
    
    //指定上传文件的存储空间
    const storage = multer.diskStorage({
          
          
      //指定上传的目录
      destination: path.join(__dirname, 'public', 'uploads'),
      filename (req, file, callback) {
          
          
        // callback 第二个参数是文件名 时间戳.jpg
        callback(null, Date.now() + path.extname(file.originalname));
      }
    });
    // 在需要上传的地方使用这个
    const upload = multer({
          
           storage });
    
    // 定义一个借口,可以上传一个avatar图片字段和title的字段
    app.post("/api/task", upload.single('avatar'), async (req, res) => {
          
          
      const {
          
           body: reqBody } = req;
      const {
          
           title } = reqBody;
      let avatar = `${
            
            req.protocol}://${
            
            req.headers.host}/uploads/${
            
            req.file.filename}`;
      try {
          
          
        const task = await Task.create({
          
          title,avatar});
        res.send(task);
      } catch (error) {
          
          
        const err = error.errors;
        if (err) {
          
          
          let messages = [];
          for (let key in err) {
          
          
            messages.push(err[key].message);
          }
          return res.status(500).send({
          
           messages: messages.join("-------") });
        }
      }
    });
    app.listen(3001, () => {
          
          
      console.log("http://localhost:3001");
    });
    
    

二、前端react结合axios上传文件

  • 1、前端代码

    import React, {
          
           useState, useRef } from 'react';
    import './index.css';
    import axios from 'axios';
    
    function CreateTask () {
          
          
      const [title, setTitle] = useState('');
      const file = useRef(null);
    
      const saveData = () => {
          
          
        // 使用formData上传
        let formData = new FormData()
        const currentFile = file.current.files[0];
        formData.append('avatar', currentFile, currentFile.name);
        // let config = {
          
          
        //   headers: { 'Content-Type': 'multipart/form-data' }
        // };
        formData.append('title', title);
        axios.post('http://localhost:3001/api/task', formData).then(response => {
          
          
          console.log(response);
          if (response.status === 200) {
          
          
            alert('add data success');
            window.location.href = '/'
          }
        })
      }
      return (
        <div className="App">
          <div className="f1">
            <span className="input-title">Title</span>
            <input type="text" placeholder="Enter task title" value={
          
          title} onChange={
          
          (event) => {
          
           setTitle(event.target.value) }} />
          </div>
          
          <div className="f1">
            <span className="input-title">task type</span>
            <input type="file" name="avatar" ref={
          
          file} />
          </div>
          <div className="save">
            <button className="save-btn" onClick={
          
          saveData}>Save</button>
          </div>
        </div>
      );
    }
    
    export default CreateTask;
    
    

猜你喜欢

转载自blog.csdn.net/kuangshp128/article/details/109150775