인프런 커뮤니티 질문&답변
업로드시 POST http://localhost:3065/ 404 (Not Found) 에러질문입니다.
해결된 질문
작성
·
1.7K
0
antd upload컴포넌트를 사용해서 해당 강의를 학습하고 있습니다.
근데 이미지 업로드시 POST http://localhost:3065/ 404 (Not Found) 에러가 발생하고 있습니다.
redux툴을 확인해보니 아래와 같이 upload_images_success는 실행됬는데 redux의 imagepaths에는 파일명이 없습니다.



![app.js - prepare - Visual Studio Code [Administrator] 2022-09-24 오후 4_37_56.png app.js - prepare - Visual Studio Code [Administrator] 2022-09-24 오후 4_37_56.png](https://cdn.inflearn.com/public/files/posts/d88dc8b5-3fbc-452d-8f09-f1afd940eea6/app.js - prepare - Visual Studio Code [Administrator] 2022-09-24 오후 4_37_56.png)
확실하지는 않지만 antd upload에 action속성이 잘못되어서 오류가 발생하는것같은데 에러 원인에 대해서 알 수 있을까요?
참고 코드도 첨부하겠습니다.
uploadform
const normFile = useCallback((e) => {
console.log('Upload event:', e);
if (Array.isArray(e)) {
return e;
}
return e?.fileList;
}, []);
const onChangeImages = useCallback((e) => {
console.log('images', e.fileList);
const imageFormData = new FormData();
[].forEach.call(e.fileList, (f) => {
imageFormData.append('image', f);
});
dispatch({
type: UPLOAD_IMAGES_REQUEST,
data: imageFormData,
})
}, []);
<ImageUploaderWrapper
name="images"
rules={[
{
required: true,
message: '조리사진을 첨부하세요.',
},
]}
valuePropName="fileList"
getValueFromEvent={normFile}
>
{/* action: 파일을 업로드할 실제 URL -> localhost3065/images */}
<Upload.Dragger
name="image"
multiple
action="http://localhost:3065"
listType="picture"
onChange={onChangeImages}
>
<p style={{marginBottom: '0.5em'}}>Drag files here OR</p>
<Button type='primary' size='large' icon={<UploadOutlined />}>Upload</Button>
</Upload.Dragger>
</ImageUploaderWrapper>
redux
export const initialState = {
mainPosts: [],
imagePaths: [],
uploadImagesLoading: false, // 이미지 업로드
uploadImagesDone: false,
uploadImagesError: null,
};
export const UPLOAD_IMAGES_REQUEST = 'UPLOAD_IMAGES_REQUEST';
export const UPLOAD_IMAGES_SUCCESS = 'UPLOAD_IMAGES_SUCCESS';
export const UPLOAD_IMAGES_FAILURE = 'UPLOAD_IMAGES_FAILURE';
const reducer = (state = initialState, action) => {
return produce(state, (draft) => {
switch (action.type) {
case UPLOAD_IMAGES_REQUEST:
draft.uploadImagesLoading = true;
draft.uploadImagesDone = false;
draft.uploadImagesError = null;
break;
case UPLOAD_IMAGES_SUCCESS:
draft.imagePaths = action.data;
draft.uploadImagesLoading = false;
draft.uploadImagesDone = true;
break;
case UPLOAD_IMAGES_FAILURE:
draft.uploadImagesLoading = false;
draft.uploadImagesError = action.error;
break;
default:
break;
}
});
};
export default reducer;
saga
function uploadImagesAPI(data) {
return axios.post('/post/images', data);
}
function* uploadImages(action) {
try {
const result = yield call(uploadImagesAPI, action.data);
yield put({
type: UPLOAD_IMAGES_SUCCESS,
data: result.data,
})
} catch(err) {
yield put({
type: UPLOAD_IMAGES_FAILURE,
data: err.response.data
})
}
}
function* watchUploadImages() {
yield takeLatest(UPLOAD_IMAGES_REQUEST, uploadImages);
}
export default function* postSaga() {
yield all([
fork(watchUploadImages),
]);
}
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');
},
filename(req, file, done) {
const ext = path.extname(file.originalname);
const basename = path.basename();
done(null, basename + '_' + new Date().getTime() + ext);
},
}),
limits: { fileSize: 20 * 1024 * 1024 },
});
router.post('/images', isLoggedIn, upload.array('image'), async (req, res, next) => {
try {
console.log(req.files);
res.json(req.files.map((v) => v.filename));
} catch (error) {
console.error(error);
next(error);
}
});
app.js
app.use('/', express.static(path.join(__dirname, 'uploads')));답변 2
0
정말 죄송한데 마지막으로 질문 하나만 드리겠습니다.
이미지를 업로드한 뒤 추가로 업로드하면 다음과 같이 이전 업로드를 포함해서 실행됩니다.

![index.js - prepare - Visual Studio Code [Administrator] 2022-09-24 오후 11_56_30 (2).png index.js - prepare - Visual Studio Code [Administrator] 2022-09-24 오후 11_56_30 (2).png](https://cdn.inflearn.com/public/files/posts/8ece29ae-cad9-4ec2-9fb8-c747500b0e59/index.js - prepare - Visual Studio Code [Administrator] 2022-09-24 오후 11_56_30 (2).png)

![index.js - prepare - Visual Studio Code [Administrator] 2022-09-24 오후 11_57_35 (2).png index.js - prepare - Visual Studio Code [Administrator] 2022-09-24 오후 11_57_35 (2).png](https://cdn.inflearn.com/public/files/posts/fc21d4aa-70eb-4280-9e61-386d7e61c29b/index.js - prepare - Visual Studio Code [Administrator] 2022-09-24 오후 11_57_35 (2).png)
onBeforeUpload를 사용해서 업로드 전에 조건을 줘서 첫 업로드를 제외하고 실행할 수 있을것같은데 혹시 이부분에 대해서 답변 받을 수 있을까요?
혼자 해결해보려고 계속 찾아봤는데 답을 찾기 힘들어서 질문드립니다.
postingform
const onChangeImages = useCallback((e) => {
const imageFormData = new FormData();
e.fileList.forEach((f) => {
imageFormData.append('image', f.originFileObj);
});
dispatch({
type: UPLOAD_IMAGES_REQUEST,
data: imageFormData,
})
}, []);
const onBeforeUpload = useCallback((file, fileList) => {
// Access file content here and do something with it
// console.log(file)
// Prevent upload
return false
}, []);req.files 출력결과
router.post('/images', isLoggedIn, upload.array('image'), async (req, res, next) => {
try {
console.log('라우터', req.files);
res.json(req.files.map((v) => v.filename));
} catch (error) {
console.error(error);
next(error);
}
});![index.js - prepare - Visual Studio Code [Administrator] 2022-09-25 오전 12_04_42 (2).png index.js - prepare - Visual Studio Code [Administrator] 2022-09-25 오전 12_04_42 (2).png](https://cdn.inflearn.com/public/files/posts/70605eb8-6493-4754-a346-3504e583a1e3/index.js - prepare - Visual Studio Code [Administrator] 2022-09-25 오전 12_04_42 (2).png)
![index.js - prepare - Visual Studio Code [Administrator] 2022-09-25 오전 12_04_44 (2).png index.js - prepare - Visual Studio Code [Administrator] 2022-09-25 오전 12_04_44 (2).png](https://cdn.inflearn.com/public/files/posts/b5e25eae-946e-4c27-99bb-ed9c1d94b792/index.js - prepare - Visual Studio Code [Administrator] 2022-09-25 오전 12_04_44 (2).png)
0
e.preventDefault()는 무슨 이유인지 실행이 안되서
다음과 같이 antd upload action속성을 주석처리하니까 에러는 해결됬습니다.
하지만 이후에도 back/images, redux의 imagePaths state에는 파일명이 저장이 안되네요 ㅜㅜ
<Upload.Dragger
name="image"
multiple
// action="http://localhost:3065" 주석처리하니 에러가 발생안함
listType="picture"
onChange={onChangeImages}
>
<p style={{marginBottom: '0.5em'}}>Drag files here OR</p>
<Button type='primary' size='large' icon={<UploadOutlined />}>Upload</Button>
</Upload.Dragger>
추가로 콘솔로확인해보니 FormData가 다음과 같이 비어있는 것을 확인했습니다.

saga
function uploadImagesAPI(data) {
console.log('사가의 데이터', data);
return axios.post('/post/images', data);
}
function* uploadImages(action) {
try {
const result = yield call(uploadImagesAPI, action.data);
yield put({
type: UPLOAD_IMAGES_SUCCESS,
data: result.data,
})
} catch(err) {
yield put({
type: UPLOAD_IMAGES_FAILURE,
data: err.response.data
})
}
}
upload form onChangeImages
const onChangeImages = useCallback((e) => {
console.log('images', e.fileList);
const imageFormData = new FormData();
[].forEach.call(e.fileList, (f) => {
imageFormData.append('image', f);
});
dispatch({
type: UPLOAD_IMAGES_REQUEST,
data: imageFormData,
})
}, []);formData는 원래 콘솔에서 비어있습니다. 먼저 네트워크 탭에서 POST /post/images 요청에 payload에 formData가 들어있는지 보시고요. 서버쪽에서 console.log(req.files) 확인해보세요.
네트워크 payload를 확인해보니 다음과 같이 image에는 [object object]로 데이터가 들언간것같은데
서버에 작성한 console(req.files)는 출력되지 않네요 ㅜㅜ



back/routes/post.js
const upload = multer({
storage: multer.diskStorage({
destination(req, file, done) {
done(null, 'uploads');
console.log('upload1', req.files);
},
filename(req, file, done) {
const ext = path.extname(file.originalname);
const basename = path.basename();
done(null, basename + '_' + new Date().getTime() + ext);
console.log('upload2', req.files);
},
}),
limits: { fileSize: 20 * 1024 * 1024 },
});
router.post('/images', isLoggedIn, upload.array('image'), async (req, res, next) => {
try {
console.log('라우터', req.files);
res.json(req.files.map((v) => v.filename));
} catch (error) {
console.error(error);
next(error);
}
});말씀해주신대로 event객체를 잘못 formData에 넣은것같아서 아래와 같이 수정했습니다.

const onChangeImages = useCallback((e) => {
console.log('images', e.fileList);
const imageFormData = new FormData();
// [].forEach.call(e.fileList, (f) => {
// imageFormData.append('image', f);
// });
e.fileList.forEach((f) => {
imageFormData.append('image', f.originFileObj);
});
dispatch({
type: UPLOAD_IMAGES_REQUEST,
data: imageFormData,
})
}, []);
근데 실행하니 다음과같은 서버에러가 발생하네요 ㅜㅜ








.png)
리덕스에 들어있어서 그렇습니다. 리덕스에서 이미지 객체를 비우는 액션을 만들어 이미지 업로드 후 제거해세요.