Поэтому я пытаюсь загрузить изображение профиля с помощью реакции. 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'), верно? Маршрут будет включать в себя мой контроллер для создания Player, который можно найти здесь:
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)
при попадании в конечную точку с помощью сообщения, верно?
Модель выглядит следующим образом:
модели / игрок. 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;
};
Теперь перейдем к коду внешнего интерфейса (реакция. js):
Это форма, которую я загружаю в свое приложение реакции:
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 не определен, и я не могу понять, почему.
Может кто-нибудь помочь мне развернуть ошибку?