req.file 在控制台中显示未定义

req.file is showing undefined in console

我正在尝试从我的网络应用程序将视频上​​传到 YouTube,但我在将文件发送到我的后端时遇到错误它显示 req.file 在 req.body 中未定义它是显示视频文件:“未定义”和我能看到的所有其他值,但我无法将文件从我的 React 应用程序获取到后端。

Input.jsx

import axios from "axios";
import React, { useState } from "react";
// import Axios from "axios";

function Input() {
  const [form, setForm] = useState({
    title: "",
    description: "",
    file: null,
  });
  function handleChange(event) {
    const InputValue =
      event.target.name === "file" ? event.target.file : event.target.value;
    setForm({
      ...form,
      [event.target.name]: InputValue,
    });
  }

  function handleSubmit(event) {
    event.preventDefault();
    console.log({ form });
    const headers = {
      "content-type": "multipart/form-data",
    };
    const videoData = new FormData();

    videoData.append("videoFile", form.file);
    videoData.append("title", form.title);
    videoData.append("description", form.description);
    axios
      .post("http://localhost:3001/upload", videoData, { headers })
      .then((res) => {
        console.log(res.data);
      })
      .catch((err) => console.log(err));
  }
  return (
    <div className="form">
      <h1>
        <i className="fab fa-youtube"></i> Upload video
      </h1>
      <form onSubmit={handleSubmit} method="POST" enctype="multipart/form-data">
        <div>
          <input
            className="title"
            type="text"
            placeholder="Title"
            name="title"
            autoComplete="off"
            onChange={handleChange}
          />
        </div>
        <div>
          <textarea
            typeof="text"
            placeholder="description"
            name="description"
            autoComplete="off"
            onChange={handleChange}
          />
        </div>
        <div>
          <input
            type="file"
            accept="video/mp4,video/x-m4v,video/*"
            placeholder="Add"
            name="file"
            onChange={handleChange}
          />
        </div>
        <button className="btn btn-light" type="submit">
          Upload Video
        </button>
      </form>
    </div>
  );
}

export default Input;

是node.js部分 App.js(后端)

const express = require("express");
const multer = require("multer");
const youtube = require("youtube-api");
const open = require("open");
const cors = require("cors");
const fs = require("fs");
const credentials = require("./client_secret_1013548512515-lti2tpl88m8qqkum1hh095cnevtdi3lu.apps.googleusercontent.com.json");
const app = express();
const bodyParser = require("body-parser");
app.use(express.json());
app.use(cors());
app.use(bodyParser.urlencoded({ extended: true }));
const storage = multer.diskStorage({
  destination: "./",
  filename: (req, file, cb) => {
    const newFileName = `${Date.now()}-${file.originalname}`;

    cb(null, newFileName);
  },
});
const uploadVideoFile = multer({
  storage: storage,
}).single("videoFile");

app.post("/upload", uploadVideoFile, (req, res) => {
  console.log(req.body);
  console.log(req.file); //it is showing undefined
  if (req.file) { //getting error in this part
    const filename = req.file.filename;
    const { title, description } = req.body;

    open(
      oAuth.generateAuthUrl({
        access_type: "offline",
        scope: "https://www.googleapis.com/auth/youtube.upload",
        state: JSON.stringify({
          filename,
          title,
          description,
        }),
      })
    );
  }
});

app.get("/oauth2callback", (req, res) => {
  res.redirect("http://localhost:3000/success");

  const { filename, title, description } = JSON.parse(req.query.state);

  oAuth.getToken(req.query.code, (err, tokens) => {
    if (err) {
      console.log(err);
      return;
    }
    oAuth.setCredentials(tokens);

    youtube.videos.insert(
      {
        resource: {
          snippet: { title, description },
          status: { privacyStatus: "private" },
        },
        part: "snippet,status",
        media: {
          body: fs.createReadStream(filename),
        },
      },
      (err, data) => {
        console.log("Done");
        process.exit();
      }
    );
  });
});

const oAuth = youtube.authenticate({
  type: "oauth",
  client_id: credentials.web.client_id,
  client_secret: credentials.web.client_secret,
  redirect_url: credentials.web.redirect_uris[0],
});

PORT = 3001;
app.listen(PORT, () => {
  console.log("app is listening on port 3001");
});

请在 Input.jsx 文件中进行以下更改。

// 1. Inside the handleChange() function
const InputValue = event.target.name === "file" ? event.target.files : event.target.value;
// 2. Inside the handleSubmit() function
videoData.append("videoFile", form.file[0], form.file[0].name);

这应该输出 req.file 中的文件对象。