-
카테고리
-
세부 분야
풀스택
-
해결 여부
해결됨
미리보기가 보이지 않습니다
23.11.23 21:25 작성 23.11.23 21:29 수정 조회수 207
0
//app.js
app.use('/', express.static(path.join(__dirname, 'uploads')));
//PostForm.js
import { Button, Form, Input } from 'antd';
import React, { useCallback, useEffect, useRef } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import styled from 'styled-components';
import useInput from '../hooks/useInput';
import {
ADD_POST_REQUEST,
REMOVE_IMAGE,
UPLOAD_IMAGES_REQUEST,
addPost,
} from '../reducers/post';
const FormWrapper = styled(Form)`
margin: 10px 0 20px;
`;
const ButtonStyle = styled(Button)`
float: 'right';
`;
const PostForm = () => {
const { imagePaths, addPostLoading, addPostDone } = useSelector(
(state) => state.post
);
const dispatch = useDispatch();
const imageInput = useRef();
const [text, onChangeText, setText] = useInput('');
useEffect(() => {
if (addPostDone) {
setText('');
}
}, [addPostDone]);
const onSubmitForm = useCallback(() => {
if (!text || !text.trim()) {
return alert('게시글을 작성하세요.');
}
const formData = new FormData();
imagePaths.forEach((p) => {
formData.append('image', p);
});
formData.append('content', text);
return dispatch({
type: ADD_POST_REQUEST,
data: formData,
});
}, [text, imagePaths]);
const onClickImageUpload = useCallback(() => {
imageInput.current.click();
}, [imageInput.current]);
const onChangeImages = useCallback((e) => {
console.log('images', e.target.files); //배열모양을 띄는 객체
const imageFormData = new FormData();
[].forEach.call(e.target.files, (f) => {
imageFormData.append('image', f);
});
dispatch({
type: UPLOAD_IMAGES_REQUEST,
data: imageFormData,
});
}, []);
const onRemoveImage = useCallback(
(index) => () => {
dispatch({
type: REMOVE_IMAGE,
data: index,
});
},
[]
);
return (
<FormWrapper encType='multipart/form-data' onFinish={onSubmitForm}>
<Input.TextArea
value={text}
onChange={onChangeText}
maxLength={140}
placeholder='어떤 신기한 일이 있었나요?'
/>
<div>
<input
onChange={onChangeImages}
type='file'
name='image'
hidden
multiple
ref={imageInput}
/>
<Button onClick={onClickImageUpload}>이미지 업로드</Button>
<ButtonStyle type='primary' htmlType='submit'>
Twit
</ButtonStyle>
</div>
<div>
{imagePaths.map((item, i) => (
<div key={item} style={{ display: 'inline-block' }}>
<img
src={`http://localhost:3065/${item}`}
style={{ width: '200px' }}
alt={item}
/>
<div>
<Button onClick={onRemoveImage(i)}>제거</Button>
</div>
</div>
))}
</div>
</FormWrapper>
);
};
export default PostForm;
//post.js
const multer = require('multer');
const path = require('path');
const fs = require('fs');
const { Post, Image, Comment, User } = require('../models');
const { isLoggedIn } = require('./middlewares');
const router = express.Router();
try {
fs.accessSync('uploads');
} catch (error) {
console.log('uploads 폴더가 없으므로 생성합니다.');
fs.mkdirSync('uploads');
}
//이미지나 동영상처리는 웬만하면 프론트에서 클라우드로 바로 올리는게 좋다.
const upload = multer({
storage: multer.diskStorage({
destination(req, file, done) {
done(null, 'uploads');
}, //배포때는 s3로 , 개발에는 드라이브에
filename(req, file, done) {
const ext = path.extname(file.originalname); //확장자 추출
const basename = path.basename(file.originalname, ext);
done(null, basename + '_' + new Date().getTime() + ext); //이나당151817842.png
},
}),
limits: { fileSize: 20 * 1024 * 1024 }, //20MB
});
router.post('/', isLoggedIn, upload.none(), async (req, res, next) => {
// POST /post
try {
const post = await Post.create({
content: req.body.content,
UserId: req.user.id,
});
if (req.body.image) {
if (Array.isArray(req.body.image)) {
const images = await Promise.all(
req.body.image.map((image) => Image.create({ src: image }))
);
await post.addImages(images);
} else {
const image = await Image.create({ src: req.body.image });
await post.addImages(image);
}
}
console.log('POST', post);
const fullPost = await Post.findOne({
where: post.id,
include: [
{
model: Image,
},
{
model: Comment,
include: [{ model: User, attributes: ['id', 'nickname'] }],
},
{
model: User, //작성자
attributes: ['id', 'nickname'],
},
{
model: User, //좋아요 누른 사람
as: 'Likers',
attributes: ['id'],
},
],
});
res.status(201).json(fullPost);
} catch (error) {
console.error(error);
next(error);
}
});
router.post(
'/images',
isLoggedIn,
upload.array('image'),
async (req, res, next) => {
//POST /post/images
try {
console.log(req.files);
res.json(req.files.map((v) => v.filename));
} catch (error) {
console.error(error);
next(error);
}
}
);
안녕하세요 제로초님! 질문이 있습니다..
파일은 제대로 올라가서 uploads 폴더안에 있는데 화면에서 이미지를 가져오지 못하고있습니다..
프론트-백 api통신도 잘 되는데, 왜 개발자도구-네트워크에서 이미지를 가져올 수 없는지 이유를 모르겠습니다 ㅠㅠ
답변을 작성해보세요.
1
답변 1