尝试使用multer上传文件,但req.file未定义

时间:2019-07-30 15:58:03

标签: mysql node.js reactjs express multer

我试图将文件上传到我的Express服务器的文件系统,以及在MySQL中存储文件路径和其他表单数据。但是,由于未定义req.file,对服务器的POST请求返回500错误。我不确定在这里我做错了什么吗?

以下是在单独文件中进行multer的设置

var multer = require('multer');

const storage = multer.diskStorage({
    destination: (req, file, cb) => {
        cb(null, './public/uploads');
    },
    filename: (req, file, cb) => {
        cb(null, file.originalname);
    }
});

const upload = multer({ storage: storage });

module.exports = {
    storage: storage,
    upload: upload
}

这是上载表格的途径。

var db = require('../sequelize');
var multerConfig = require('../config/multerConfig');
var multer = require('multer');

module.exports = app => {
    app.post('/uploadForm', multerConfig.upload.single('registrationform'), (req, res) => {
        console.log('====================================');
        console.log(req.file);
        console.log('====================================');
        db.RegistrationForm.create({
            unit_number: req.body.unit_number,
            filepath: req.file.destination + "/" + req.file.filename,
            uploaded_by: req.body.uploaded_by
        })
        .then(newRegistrationform => {
            console.log("New Registration Form below uploaded successfully!");
            console.log(newRegistrationform); 
        })
        .catch(err => {
            console.log(err);
        });
    });
};

这是相关的客户端代码。其中一些与我已经在工作的护照设置有关。

将父组件添加到上传器表单

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import UploadForm from "../../components/UploadForm";
import axios from 'axios';

class Uploader extends Component {
    constructor(props) {
        super(props);
        this.state = {
            first_name: '',
            last_name: '',
            email: '',
            username: '',
            password: '',
            error: false,
            unit_number: '',
            filepath: '',
        }
        this.handleFormSubmit = this.handleFormSubmit.bind(this);
        this.fileInput = React.createRef();
    }

    componentDidMount() {
        const accessString = localStorage.getItem('JWT');
        const {
            match: {
                params: { username },
            },
        } = this.props;
        console.log(username);
        if (accessString == null) {
            this.setState({
                error: true,
            });
        } else {
            axios.get('http://localhost:3001/findUser',
                {
                    params: {
                        username,
                    },
                    headers: { Authorization: 'JWT ' + accessString },
                }
            )
            .then((response) => {
                console.log('This is the response below');
                console.log(response);
                this.setState({
                    first_name: response.data.first_name,
                    last_name: response.data.last_name,
                    email: response.data.email,
                    username: response.data.username,
                    password: response.data.password,
                    error: false,
                });
            })
            .catch((error) => {
                console.error(error.response);
                this.setState({
                    error: true,
                });
            })
        }
    }

    logout = (event) => {
        event.preventDefault();
        localStorage.removeItem('JWT');
        window.location = "/";
    };

    handleInputChange = name => (event) => {
        this.setState({
            [name]: event.target.value,
        });
    };

    handleFileInputChange = (event) => {
        if (this.fileInput.value === "") {
            this.setState({
                filepath: ""
            });
        } else {
            event.target.readOnly = false;
            this.setState({
                filepath: "./public/uploads/" + this.fileInput.current.files[0].name,
            });
            event.target.readOnly = true;
        }
        event.target.value = this.state.filepath;
    }

    handleFormSubmit = (event) => {
        event.preventDefault();
        console.log(this.state.unit_number);
        const {
            first_name,
            last_name,
            email,
            username,
            password,
            error,
            unit_number
        } = this.state;

        const fileInput = this.fileInput.current.files[0].name;

        if (unit_number === '' || fileInput === '') {
            alert("Please choose a file and input a unit number.");
        } else {
            axios.post(
                'http://localhost:3001/uploadForm',
                {
                    unit_number,
                    uploaded_by: last_name + ", " + first_name,

                }
            )
            .then((response) => {
                console.log('This is the response below');
                console.log(response);
                this.setState({
                    unit_number: ''
                });
                this.fileInput.value= "";
            })
            .catch((error) => {
                console.log(error);
            })
        }
    };

    render() {
        const {
            first_name,
            last_name,
            email,
            username,
            password,
            error,
            unit_number
        } = this.state;

        if (error) {
            return (
                <div>
                    <p>Problem fetching user data. Please login again.</p>
                    <a href='/login'><button>Login</button></a>
                </div>
            )       
        }
        return (
            <div>
                <h1>Welcome, {first_name} {last_name}!</h1>
                <h2>Upload a Registration Form.</h2>
                <UploadForm handleInputChange={this.handleInputChange} handleFileInputChange={this.handleFileInputChange} handleFormSubmit={this.handleFormSubmit} unit_number={this.unit_number} first_name={this.first_name} last_name={this.last_name} fileInput={this.fileInput} filepath={this.filepath} />
                <button onClick={this.logout}>Logout</button>
            </div>
        );
    }
}

Uploader.propTypes = {
    match: PropTypes.shape({
        params: PropTypes.shape({
            username: PropTypes.string.isRequired,
        }),
    }),
};

export default Uploader;

上面的子组件,仅是UploadForm组件。

import React from 'react';
function UploadForm(props) {
    return (
        <div>
            <form encType="multipart/form-data" onSubmit={props.handleFormSubmit}>
                <table>
                    <tbody>
                        <tr>
                            <th>Choose File</th>
                            <th>Unit Number</th>
                            <th>File Path</th>
                        </tr>
                        <tr>
                            <td><input type="file" name="registrationform" id="registrationform" ref={props.fileInput} /></td>
                            <td><input type="text" id="unit_number" value={props.unit_number} onChange={props.handleInputChange('unit_number')} /></td>
                            <td><input type="text" id="filepath" onChange={props.handleFileInputChange} readOnly /></td>
                        </tr>
                    </tbody>
                </table>
                <button>Upload</button>
            </form>
        </div>
    );
}

export default UploadForm;

相关Sequelize模型

module.exports = (sequelize, type) => {
    return sequelize.define('registrationform', {
        id: {
            type: type.INTEGER,
            primaryKey: true,
            autoIncrement: true,
        },
        unit_number: {
            type: type.STRING,
            allowNull: false,
        },
        filepath: {
            type: type.STRING,
            allowNull: false,
        },
        uploaded_by: type.STRING,
    });
};

我希望在提交上传表单时,应将文件上传到“ uploads”文件夹,并且该文件的文件路径,单元号以及当前上传该文件的登录用户都应存储在MySQL数据库。

0 个答案:

没有答案