axios 无法将文件从react js前端上载到Express后端

lc8prwob  于 2023-02-12  发布在  iOS
关注(0)|答案(1)|浏览(130)
//This is frontend

import React, { useState } from "react";
import axios from "axios";
import "./App.css";

const App = () => {
  const [logFile, setLogFile] = useState<File | null>(null);

  const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    setLogFile(e.target.files![0]);
  };

  const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
    e.preventDefault();

    try {
      const formData = new FormData();
      formData.append("logFile", logFile!);
      console.log(formData);
      const response = await axios.post(
        "http://localhost:3001/logs",
        formData,
        {
          headers: {
            "Content-Type": "multipart/form-data",
          },
        }
      );
      console.log(response.data);
    } catch (error) {
      console.error(error);
    }
  };

  return (
    <>
      <div className="App">
        <h1>Upload file</h1>
        <form onSubmit={handleSubmit}>
          <div>
            <input type="file" onChange={handleChange} />
          </div>
          <button type="submit">Submit</button>
        </form>
      </div>
    </>
  );
};

export default App;




//This is backend
const express = require('express');
const app = express();
const port = 3001;
const winston = require('winston');
const cors = require("cors")

app.use(cors())

const logger = winston.createLogger({
  transports: [
    new winston.transports.File({
      level: 'error',
      filename: 'error.log',
      handleExceptions: true,
      json: true,
      maxsize: 5242880,
      maxFiles: 5,
      colorize: false
    }),
    new winston.transports.File({
      level: 'warn',
      filename: 'warning.log',
      handleExceptions: true,
      json: true,
      maxsize: 5242880,
      maxFiles: 5,
      colorize: false
    })
  ],
  exitOnError: false
});

app.use(express.json());

app.get("/", (req, res) => {
  res.json({ "message": req.body.logFile })
})

app.post('/logs', (req, res) => {
  const logFile = req.body.logFile;
  const errorLogs = [];
  const warnLogs = [];

  // Log error and warn messages to separate files
  logFile?.forEach(log => {
    if (log.level === 'error') {
      logger.error(log);
      errorLogs.push(log);
    } else if (log.level === 'warn') {
      logger.warn(log);
      warnLogs.push(log);
    }
  });

  res.json({ errorLogs, warnLogs });
});

app.listen(port, () => {
  console.log(`Server is listening at http://localhost:${port}`);
});

我正在构建一个日志解析器来记录错误和警告级别,使用react js上传文件并从express服务器返回过滤后的数据(作为json)。但我得到的formData对象为空,而logfile在react js前端的控制台中显示上传的fie
我想将日志文件从前端发送到后端,并将过滤后的json数据从后端返回到前端

0g0grzrc

0g0grzrc1#

代码中的一个问题是form元素没有onSubmit事件,因此表单永远不会提交。要解决此问题,可以将input元素和submit按钮 Package 在form元素中,然后添加一个调用handleSubmit函数的onSubmit事件。
另一个问题是您使用fetch API发出POST请求,这可能无法正确处理multipart/form-data内容类型。您可以使用Axios库,这使得在请求正文中发送二进制数据更容易。

import React, { useState } from "react";
import axios from "axios";
import "./App.css";

const App = () => {
  const [logFile, setLogFile] = useState<File | null>(null);

  const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    setLogFile(e.target.files![0]);
  };

  const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
    e.preventDefault();

    try {
      const formData = new FormData();
      formData.append("logFile", logFile!);

      const response = await axios.post("http://localhost:3001/logs", formData, {
        headers: {
          "Content-Type": "multipart/form-data",
        },
      });
      console.log(response.data);
    } catch (error) {
      console.error(error);
    }
  };

  return (
    <>
      <div className="App">
        <h1>Upload file</h1>
        <form onSubmit={handleSubmit}>
          <div>
            <input type="file" onChange={handleChange} />
          </div>
          <button type="submit">Submit</button>
        </form>
      </div>
    </>
  );
};

export default App;
    • 编辑:**

问题是您正在使用req.body.logFile访问上传的文件,但是文件是作为multipart/form-data请求发送的,而不是作为JSON请求发送的,您需要使用一个可以处理multipart/form-data请求并提取文件的中间件。
要在Express应用程序中处理multipart/form-data请求,可以使用multer中间件。下面是一个如何使用它从请求中提取文件的示例:

const multer = require('multer');
const storage = multer.memoryStorage();
const upload = multer({ storage });

app.post('/logs', upload.single('logFile'), (req, res) => {
  const logFile = req.file;
  ...
});

在本例中,upload.single('logFile')将从multipart/form-data请求的logFile字段中提取文件,并将其作为Buffer存储在内存中。

相关问题