【发布时间】:2020-04-30 05:56:43
【问题描述】:
所以我试图通过 react.js 应用程序将配置文件图片上传到作为 REST API 运行的后端,使用 node.js express.js 和 sqlite 作为数据库。
但不知何故,我找不到任何适合我的教程。不过我一定很近。 所以我现在拥有的是这样的:
我的路线如下所示:
playerRoutes.js:
const express = require('express');
const router = express.Router();
const multer = require('multer');
const uuidv4 = require('uuid/v4');
const upload_dir = './uploads';
const storage = multer.diskStorage({
destination: (req, file, cb) => {
cb(null, upload_dir);
},
filename: (req, file, cb) => {
cb(null, `${uuidv4()}-${file.filename.toLowerCase}`);
}
});
const upload = multer({
storage: storage,
fileFilter: (req, file, cb) => {
if (
file.mimetype == 'image/png' ||
file.mimetype == 'image/jpg' ||
file.mimetype == 'image/jpeg'
) {
cb(null, true);
} else {
cb(null, false);
return cb(new Error('Only .png, .jpg and .jpeg format allowed!'));
}
}
});
const { playerController } = require('../controller');
router.get('/', playerController.getAllPlayer);
router.get('/:id', playerController.getSpecificPlayer);
router.post('/', upload.single('profileImg'), playerController.createPlayer);
router.put('/:id', playerController.updatePlayer);
router.delete('/:id', playerController.deletePlayer);
module.exports = router;
所以重点是storage 的设置,它告诉上传到哪里+upload 中的文件过滤器,对吧?
还有route.post,它将`upload.single('profileImg'),对吗?该路线将包括我的用于创建播放器的控制器,可以在此处找到:
playerController.js
const { Player } = require('../models');
module.exports = {
getAllPlayer(req, res) {
return Player.findAll({
attributes: ['id', 'name', 'nickname', 'profileImg']
})
.then(players => res.status(200).send(players))
.catch(err => res.status(400).send(err));
},
getSpecificPlayer(req, res) {
return Player.findByPk(req.params.id, {
attributes: ['id', 'name', 'nickname', 'profileImg']
}).then(player => {
if (!player) {
return res.status(404).send({
message: `Player with id ${req.params.id} not found`
});
}
return res.status(200).send(player);
});
},
createPlayer(req, res) {
console.log(req.file);
return Player.create({
name: req.body.name,
nickname: req.body.nickname
})
.then(player => res.status(201).send(player))
.catch(err => res.status(400).send(err));
},
updatePlayer(req, res) {
return Player.findByPk(req.params.id, {
attributes: ['id', 'name', 'nickname', 'profileImg']
})
.then(player => {
if (!player) {
return res.status(404).send({
message: `Player with id ${req.params.id} not found`
});
}
return player
.update({
name: req.body.name || player.name,
nickname: req.body.nickname || player.nickname,
profileImg: req.body.profileImg || player.profileImg
})
.then(() => res.status(200).send(player))
.catch(err => res.status(400).send(err));
})
.catch(err => res.status(400).send(err));
},
deletePlayer(req, res) {
return Player.findByPk(req.params.id, {
attributes: ['id', 'name', 'nickname', 'profileImg']
})
.then(player => {
if (!player) {
return res.status(404).send({
message: `Player with id ${req.params.id} not found`
});
}
return player
.destroy()
.then(() => res.status(204).send())
.catch(err => res.status(400).send(err));
})
.catch(err => res.status(400).send(err));
}
};
目前,关于几个教程,我应该在console.log(req.file) 中看到信息,当用帖子点击端点时,对吧?
模型如下所示:
models/player.js(续集模型)
'use strict';
module.exports = (sequelize, DataTypes) => {
const Player = sequelize.define(
'Player',
{
name: {
type: DataTypes.STRING,
validate: { notEmpty: { msg: 'Player name cannot be empty' } }
},
nickname: {
type: DataTypes.STRING
},
profileImg: {
type: DataTypes.STRING
}
},
{}
);
Player.associate = function(models) {
// associations can be defined here
};
return Player;
};
现在到前端代码(react.js):
这是我在我的 react 应用中加载的表单:
playerform.js
import React, { Component } from 'react';
import axios from 'axios';
import {
FormControl,
FormGroup,
FormLabel,
Form,
Button
} from 'react-bootstrap';
import PropTypes from 'prop-types';
class PlayerForm extends Component {
state = {
name: '',
nickname: '',
profileImg: ''
};
handleSubmit = e => {
e.preventDefault();
axios
.post(`${process.env.API_URL}/player`, JSON.stringify(this.state), {
headers: {
Accept: 'application/json',
'Content-Type': 'application/json'
}
})
.then(() => this.props.onCreate())
.catch(err => console.log(err));
};
onFileChange(e) {
this.setState({ profileImg: e.target.files[0] });
}
handelChange = e => {
this.setState({
[e.target.name]: e.target.value
});
};
render() {
return (
<div className="container">
<Form onSubmit={this.handleSubmit}>
<FormGroup>
<FormLabel>Name</FormLabel>
<FormControl
type="text"
name="name"
placeholder="Enter player name"
onChange={this.handelChange.bind(this)}
/>
</FormGroup>
<FormGroup>
<FormLabel>Nickname</FormLabel>
<FormControl
type="text"
name="nickname"
placeholder="Enter player nickname"
onChange={this.handelChange.bind(this)}
/>
</FormGroup>
<FormGroup>
<FormLabel>Picture</FormLabel>
<FormControl
type="file"
name="file"
playerholder="Upload player picture"
onChange={this.onFileChange.bind(this)}
/>
</FormGroup>
<Button variant="btn btn-primary" type="submit">
Add
</Button>
</Form>
</div>
);
}
}
PlayerForm.propTypes = {
onCreate: PropTypes.func.isRequired
};
export default PlayerForm;
因此,当输入内容并点击Add 按钮时,我的 api 指出 req.file 未定义,我无法找出原因。
谁能帮我找出错误?
【问题讨论】:
标签: node.js reactjs rest express sequelize.js