无法在nodejs服务器上上传csv文件

cannot upload csv file on nodejs server

我正在尝试通过前端的 reactnode.js 服务器上传一个 csv 文件并将其存储在数组中.我已经使用 fast csv 模块来解析这个 csv 文件,但是 fast csv 模块要求缓冲区或 url 。我的反应是向我发送一个空白对象。我被严重卡住了,请帮助我摆脱困境。我指望你了。

import React from 'react';
import axios from 'axios';

const [company, setCompany] = React.useState('');
const [city, setcity] = React.useState("");
const [file, setFile] = React.useState("");
const [open, setOpen] = React.useState(false);

let csvData = new FormData();
csvData.append("file", file);


const handleSubmit = async () => {
    try {
        const res = await axios.post('http://localhost:5000/csv',  { csvData } );
        console.log(res);
    } catch (error) {
        console.error(error);
    }
};

 <input className={classes.input} id="contained-button-file" multiple type="file" 
         onChange={(e) => setFile(e.target.files[0])} />

                    <label htmlFor="contained-button-file">

                        <Button variant="contained" color="primary"
                        component="span" startIcon={<CloudUpload />}>
                            Upload Data
                        </Button>

                    </label>

更新:

根据提供的响应更新了后端代码,以便我现在可以获得有关前端代码的帮助。

更新代码后从后端获取错误。

错误:TypeError: Cannot read property 'path' of undefined

我的后端代码是这样的:

import fs from 'fs';
import multer from 'multer';
const upload = multer({ dest: '/tmp/csv/' });
const csv = require('fast-csv');

router.post('/csv', upload.single('file'), (req, res, next) => {
let filerows = [];

let stream = fs.createReadStream(req.file.path);

stream.pipe(
    // csv.fromPath(req.file.path)
    csv
        .parse()
        .on('data', (data) => {
            filerows.push(data);
        })
        .on('error', () => {
            res.status(500).json({ message: 'Failed to upload' });
        })
        .on('end', () => {
            // console.log(filerows);
            
            const sql =
            'INSERT INTO bikes_database(website, company_name, category,city, brand_name, bike_name, bike_url, hour_rent, weekday_rent, weekend_rent, 7_days_rent, 15_days_rent, 30_days_rent, gst, convinence_fee,booking_confirmation, helmet,deposit, km_limit, speed_limit, home_delivery, product_page) VALUES ?';
            
            db.query(sql, [filerows], (err, result) => {
                if (err) throw err;
                res.json("uploaded successfully")
            });

            fs.unlinkSync(req.file.path);
        })
);

});

您缺少为文件提供路径位置的 multer 中间件。没有它,路径可能未定义,这可能是导致错误的原因

  const fs = require('fs');
  const multer = require('multer');
  const upload = multer({ dest: 'tmp/csv/' });
  const csv = require('fast-csv');

  router.post('/csv', upload.single('file'), function (req, res) {
    const fileRows = [];

    // open uploaded file
    csv.fromPath(req.file.path)
      .on("data", function (data) {
        fileRows.push(data); // push each row
      })
      .on("error", function () {
          res.status(500).json({
              message: "Failed to upload file"
          });
      })
      .on("end", function () {
        console.log(fileRows)
        fs.unlinkSync(req.file.path);   // remove temp file
        
        //process "fileRows" and respond
        
         res.json({
            message: "Upload Completed!"
         });
      })
  }));

至于你的反应代码,我可以看到你正在使用从请求返回的文本设置任何元素。在 handle submit 内部,您需要设置收到的响应中的文本。类似这样,但如果收到错误消息,您还需要处理设置错误消息

     this.setState({
         text: response.data.message 
     });

对于后端,我更新的代码工作正常:

import fs from 'fs';
import multer from 'multer';
const upload = multer({ dest: '/tmp/csv/' });
const csv = require('fast-csv');

router.post('/csv', upload.single('file'), (req, res, next) => {
let filerows = [];

let stream = fs.createReadStream(req.file.path);

stream.pipe(
// csv.fromPath(req.file.path)
csv
    .parse()
    .on('data', (data) => {
        filerows.push(data);
    })
    .on('error', () => {
        res.status(500).json({ message: 'Failed to upload' });
    })
    .on('end', () => {
        // console.log(filerows);
        
        const sql =
        'INSERT INTO bikes_database(website, company_name, category,city, brand_name, 
   bike_name, bike_url, hour_rent, weekday_rent, weekend_rent, 7_days_rent, 
   15_days_rent, 30_days_rent, gst, convinence_fee,booking_confirmation, 
   helmet,deposit, km_limit, speed_limit, home_delivery, product_page) VALUES ?';
        
        db.query(sql, [filerows], (err, result) => {
            if (err) throw err;
            res.json("uploaded successfully")
        });

        fs.unlinkSync(req.file.path);
    })
  );

对于前端,我们有:

 import React from 'react';
 import axios from 'axios';

const [company, setCompany] = React.useState('');
const [city, setcity] = React.useState("");
const [file, setFile] = React.useState("");
const [open, setOpen] = React.useState(false);

let csvData = new FormData();
csvData.append("file", file);


const handleSubmit = async () => {
try {
    const res = await axios({
            method: 'post',
            url: 'http://localhost:5000/csv',
            data: csvData,
            headers: { 'Content-Type': 'multipart/form-data' },
        });
    console.log(res);
} 
catch (error) {
    console.error(error);
}
 };

 <input className={classes.input} id="contained-button-file" multiple type="file" 
     onChange={(e) => setFile(e.target.files[0])} />

                <label htmlFor="contained-button-file">

                    <Button variant="contained" color="primary"
                    component="span" startIcon={<CloudUpload />}>
                        Upload Data
                    </Button>

                </label>