node.js 오류
-
게시물 수정 , 삭제는 로그인 필요
웹사이트를 제작하는 과정에서 리엑트와 서버를 키고
웹에서 전송 버튼을 누르면 서버 콘솔에 방 등록 결과가 찍혀야하고 DB에도 저장이 돼야 합니다
그런데 전송 버튼을 누르면 이미지에 대한 정보만 넘어오고 다른 정보가 서버로 넘어오지 않고
Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
at ServerResponse.setHeader (_http_outgoing.js:558:11)
at ServerResponse.header (C:\Users\ASROCK\Documents\roomsharingservice-server\node_modules\express
at ServerResponse.send (C:\Users\ASROCK\Documents\roomsharingservice-server\node_modules\express\l
at C:\Users\ASROCK\Documents\roomsharingservice-server\server.js:82:21
at Layer.handle [as handle_request] (C:\Users\ASROCK\Documents\roomsharingservice-server\node_modu
at next (C:\Users\ASROCK\Documents\roomsharingservice-server\node_modules\express\lib\router\route
at Route.dispatch (C:\Users\ASROCK\Documents\roomsharingservice-server\node_modules\express\lib\ro
at Layer.handle [as handle_request] (C:\Users\ASROCK\Documents\roomsharingservice-server\node_modu
at C:\Users\ASROCK\Documents\roomsharingservice-server\node_modules\express\lib\router\index.js:28
at Function.process_params (C:\Users\ASROCK\Documents\roomsharingservice-server\node_modules\expre
이런 에러가 발생합니다 axios 통신은 포스트맨으로 사용을 했습니다
(포스트맨으로 임의의 값을 입력하고 넣었을 때는 디비에 잘 들어갑니다)
코드 올려봅니다
리엑트 파일
import "./index.css";
import axios from "axios";
import { useState } from "react";
import { Button, Divider, Form, Input, InputNumber, Upload } from "antd";
import { Switch, Route, Link, useHistory } from "react-router-dom";
import { API_URL } from "../config/constants"; //서버주소 API_URL Ctrl+좌클릭이동 주소수정가능
function RoomRegisPage() {
const [imageUrl, setImageUrl] = useState(null);
const onSubmit = (values) => {
console.log(values);
axios
.post(`${API_URL}/Rooms`, {
//서버통신해서 DB로 보내는것
address1: values.adr1,
address2: values.adr2,
address3: values.adr3,
address4: values.adr4,
datein: values.datein,
dateOut: values.dateout,
roomtype: values.roomtype,
people:values.people,
price: parseInt(values.price),
description: values.description,
imageurl:values.imageurl,
})
.then((result) => {
console.log(result);
}).catch(function (error){
console.error(error);
});
};
const onChangeImage = (info) => {
if (info.file.status === "uploading") {
return;
}
if (info.file.status === "done") {
const response = info.file.response;
const imageUrl = response.imageUrl;
setImageUrl(imageUrl);
}
};
return (
<div>
<div id="header">
<div id="header-area">
<Link to="/">
<img src="../images/logo.png" id="logo" alt="logo" />
</Link>
</div>
</div>
<div className="regiscontainer">
<h1>방 등록 페이지</h1>
<div className="roomRegisBox">
<Form name="방등록" onFinish={onSubmit}>
<div className="roomDetail">
<Form.Item name="upload-pic">
<div className="roomPic">
<Upload
name="image"
action={`${API_URL}/image`} //이미지가 올라갈 링크
listType="picture"
showUploadList={false}
onChange={onChangeImage}
>
{imageUrl ? (
<img
id="upload-img"
src={`${API_URL}/${imageUrl}`} //이미지가 올라갈 링크
/>
) : (
<div id="upload-img-placeholder">
<img src="/images/camera.png" />
<span>이미지를 업로드해주세요.</span>
</div>
)}
</Upload>
</div>
</Form.Item>
<div className="roomDetailsec">
<div className="Detailsec">
<span className="adrspan">주소</span>
<Form.Item name="address1">
<select className="searchboxselect">
<option>도시선택</option>
<option value="서울">서울</option>
</select>
</Form.Item>
<Form.Item name="address2">
<select className="searchboxselect">
<option>구선택</option>
<option value="강남구">강남구</option>
<option value="동작구">동작구</option>
<option value="광진구">광진구</option>
</select>
</Form.Item>
<Form.Item name="address3">
<select className="searchboxselect">
<option>동선택</option>
<option value="역삼동">역삼동</option>
<option value="청담동">청담동</option>
<option value="논현동">논현동</option>
</select>
</Form.Item>
<Form.Item name="address4">
<Input className="upload-adr4" placeholder="상세주소" />
</Form.Item>
</div>
<div className="Detailsec">
<span className="checkinspan">체크인 기간</span>
<Form.Item name="datein">
<Input className="checkIn" type="date" />
</Form.Item>
<span> ~ </span>
<Form.Item name="dateout">
<Input className="checkOut" type="date" />
</Form.Item>
</div>
<div className="Detailsec">
<span className="typespan">방 타입</span>
<Form.Item name="roomtype">
<select className="typeselect">
<option>방선택</option>
<option value="1">1룸</option>
<option value="2">2룸</option>
<option value="3">3룸</option>
</select>
</Form.Item>
</div>
<div className="Detailsec">
<span className="perspan">인원</span>
<Form.Item name="people">
<select className="perselect">
<option>인원선택</option>
<option value="1">1명</option>
<option value="2">2명</option>
<option value="3">3명</option>
</select>
</Form.Item>
</div>
<div className="Detailsec">
<span className="moneyspan">금액</span>
<Form.Item name="price">
<InputNumber defaultValue={0} className="upload-price" />
</Form.Item>
</div>
<div className="Detailsec">
<span className="Detailspan">기타</span>
<Form.Item name="description">
<Input.TextArea
size="large"
id="room-description"
showCount
maxLength={300}
placeholder="방에 대한 추가 설명을 적어주세요."
/>
</Form.Item>
</div>
</div>
</div>
<div className="button">
<Form.Item>
<Button id="room-submit-button" size="large" htmlType="submit">
등록
</Button>
</Form.Item>
</div>
</Form>
</div>
</div>
<div id="footerbox">
<div id="fo1">
<span id="quick">회사소개</span>
<span id="quick">이용약관</span>
<span id="quick">개인정보처리방침</span>
<span id="quick">이용안내</span>
<span id="quick">제휴문의</span>
</div>
<div id="fo2">
주식회사 에어 고객센터 : 1588-1588 주소 : 서울특별시 강남구 청담동 782-22
</div>
<div id="fo3">
<span id="three">
사업자등록번호 : 205-87-21547 통신판매업 신고번호 제2021-서울-0111호
</span>
</div>
<div id="fo4">
<span id="four">
서비스 이용문의 : 1588-1577 | 이메일 : airtrace@airtrace.com |
서비스제휴문의 : partnership@airtrace.com
</span>
</div>
</div>
</div>
);
}
export default RoomRegisPage;
node.js 서버 파일
const express = require("express");
const cors = require("cors");
const app = express();
const models = require("./models");
const port = 8090;
const multer = require("multer");
const addroom = multer({
storage: multer.diskStorage({
destination: function (req, file, cb) {
cb(null, "addroom/"); // 이미지 저장 경로
},
filename: function (req, file, cb) {
cb(null, file.originalname); // 이미지 파일 이름 설정
},
}),
});
app.use(express.json());
app.use(cors());
app.use("/addroom", express.static("addroom"));
app.get("/Rooms", (req, res) => {
models.Rooms.findAll({
order: [["createdAt", "DESC"]], // 방 조회 정렬 (오름차순) 로직 -> 최근에 등록한 방이 먼저 보이게끔 설정하기 위해서
attributes: [
"id",
"address1",
"address2",
"address3",
"address4",
"datein",
"dateout",
"roomtype",
"people",
"description",
"imageurl",
], // 가져오고 싶은 데이터만 받아올 수 있는 로직
})
.then((result) => {
console.log("Rooms : ", result);
res.send({
Rooms: result,
});
})
.catch((error) => {
console.error(error);
res.status(400).send("에러 발생");
});
});
app.post("/Rooms", (req, res) => {
const body = req.body;
res.send({
body,
});
const {
address1,
address2,
address3,
address4,
datein,
dateout,
roomtype,
people,
price,
description,
imageurl,
} = body;
if (
// 만약 필드 중 하나라도 입력을 안 했을 경우 에러를 출력하는 로직
!address1 ||
!address2 ||
!address3 ||
!address4 ||
!datein ||
!dateout ||
!roomtype ||
!people ||
!price ||
!description ||
!imageurl
) {
res.status(400).send("모든 필드를 입력해주세요");
}
models.Rooms.create({
address1,
address2,
address3,
address4,
datein,
dateout,
roomtype,
people,
price,
description,
imageurl,
})
.then((result) => {
console.log("방 등록 결과 : ", result);
res.send({
result,
});
})
.catch((error) => {
console.error(error);
res.status(400).send("방 등록에 문제가 발생했습니다");
});
});
app.get("/Rooms/:id", (req, res) => {
const params = req.params;
const { id } = params;
models.Rooms.findOne({
// 방 번호 (id) 와 일치하는 정보를 불러오는 로직
where: {
id: id,
},
attributes: [
"id",
"address1",
"address2",
"address3",
"address4",
"datein",
"dateout",
"roomtype",
"people",
"description",
"imageurl",
],
})
.then((result) => {
console.log("ROOMS : ", result);
res.send({
Rooms: result,
});
})
.catch((error) => {
console.log(error);
res.status(400).send("방 조회에 에러가 발생했습니다.");
});
});
app.post("/image", addroom.single("image"), (req, res) => {
// 이미지 업로드 로직
const file = req.file;
console.log(file);
res.send({
imageUrl: file.path, // 파일의 경로
});
});
app.listen(port, () => {
console.log("airtrace 서버가 돌아가고 있습니다");
models.sequelize
.sync()
.then(() => {
console.log("DB 연결 성공!");
})
.catch((err) => {
console.error(err);
console.log("DB 연결 에러");
process.exit();
});
});
필드의 정보를 담는 js파일
module.exports = function (sequelize, DataTypes) {
const rooms = sequelize.define("Rooms", {
address1: {
type: DataTypes.STRING(30),
allowNull: false,
},
address2: {
type: DataTypes.STRING(30),
allowNull: false,
},
address3: {
type: DataTypes.STRING(30),
allowNull: false,
},
address4: {
type: DataTypes.STRING(200),
allowNull: false,
},
datein: {
type: DataTypes.STRING(50),
allowNull: false,
},
dateout: {
type: DataTypes.STRING(50),
allowNull: false,
},
roomtype: {
type: DataTypes.STRING(10),
allowNull: false,
},
people: {
type: DataTypes.STRING(15),
allowNull: false,
},
price: {
type: DataTypes.INTEGER(50),
allowNull: false,
},
description: {
type: DataTypes.STRING(500),
allowNull: false,
},
imageurl: {
type: DataTypes.STRING(300),
allowNull: false,
},
});
return rooms;
};
#node.js 오류