230713 개발일지 TIL - 클라이언트의 fetch 요청 URL 오류로 인한 문제 해결

The Web On Everything·2023년 7월 13일
0

개발일지

목록 보기
62/269

클라이언트의 fetch 요청 URL 오류로 인한 문제 해결
(POST http://localhost:3000/posts 404 (Not Found))

문제점
글 작성 후 추가하기 버튼을 클릭하면 404에러가 생기고 db.json에 데이터를 저장이 안되고 있는 현상

// db.json
{
  "todos": [
    {
      "id": 1,
      "title": "react"
    },
    {
      "id": 2,
      "title": "react2"
    },
    {
      "id": 3,
      "title": "react3"
    },
  ],
  "posts": [
    {
      "id": 1,
      "title": "json-server",
      "author": "typicode"
    },
  ],
  "comments": [
    {
      "id": 1,
      "body": "some comment",
      "postId": 1
    }
  ],
  "profile": {
    "name": "typicode"
  }
}
// Add.jsx (글 등록 페이지)
import React, { useEffect, useState } from "react";
import Box from "@mui/material/Box";
import TextField from "@mui/material/TextField";
import IconButton from "@mui/material/IconButton";
import TextareaAutosize from "@mui/material/TextareaAutosize";
import Typography from "@mui/material/Typography";
import Button from "@mui/material/Button";
import DeleteIcon from "@mui/icons-material/Delete";
import AddIcon from "@mui/icons-material/Add";
import SendIcon from "@mui/icons-material/Send";
import Stack from "@mui/material/Stack";
import axios from "axios";

function Add() {
  const [todos, setTodos] = useState(null);
  // 비동기 함수
  const fetchTodos = async () => {
    // const response = await axios.get("http://localhost:4000/todos");
    // console.log("response", response);
    const { data } = await axios.get("http://localhost:4000/todos");
    console.log("data", data);
    setTodos(data);
  };

  useEffect(() => {
    // db로부터 값을 가져오기
    fetchTodos();
  }, []);
  const [text, setText] = React.useState("");
  const addEmoji = (emoji) => () => setText(`${text}${emoji}`);

  const [author, setAuthor] = useState("");
  const [title, setTitle] = useState("");
  const [content, setContent] = useState("");

  const handleAdd = () => {
    const newPost = {
      author: author,
      title: title,
      content: content,
    };

    fetch("http://localhost:3000/posts", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify(newPost),
    })
      .then((response) => response.json())
      .then((data) => {
        console.log("New post added:", data);
        // 추가 완료 후 필요한 상태 업데이트 등의 작업 수행
      })
      .catch((error) => {
        console.error("Error adding post:", error);
        // 오류 처리
      });
  };

  return (
    <div
      style={{
        padding: "0 25px",
      }}
    >
      <Box
        sx={{
          width: "100%",
          maxWidth: "100%",
        }}
      >
        <h1>작성자</h1>
        <TextField
          fullWidth
          label="작성자"
          id="fullWidth"
          placeholder="작성자의 이름을 입력해주세요."
          value={author}
          onChange={(e) => setAuthor(e.target.value)}
        />
        <h1>제목</h1>
        <TextField
          fullWidth
          label="제목"
          id="fullWidth"
          placeholder="제목을 입력해주세요."
          value={title}
          onChange={(e) => setTitle(e.target.value)}
        />
        <h1>내용</h1>
        <TextareaAutosize
          style={{
            boxSizing: "border-box",
            padding: "16.5px 14px",
            width: "100%",
            borderColor: "rgba(0, 0, 0, 0.23)",
            borderRadius: "4px",
          }}
          placeholder="여기에 입력하세요..."
          value={content}
          onChange={(e) => setContent(e.target.value)}
          minRows={7}
          maxRows={7}
          label="내용"
        />
        <Typography
          variant="body2"
          sx={{ ml: "auto" }}
          style={{ textAlign: "right" }}
        >
          {content.length}</Typography>
      </Box>

      <Stack direction="row" spacing={2}>
        <Button
          variant="outlined"
          startIcon={<AddIcon />}
          style={{
            margin: "10px 0",
            padding: "10px 0",
            width: "100%",
          }}
          onClick={handleAdd}
        >
          추가하기
        </Button>
      </Stack>

      <div>
        {todos?.map((item) => {
          return (
            <div key={item.id}>
              {item.id} : {item.title}
            </div>
          );
        })}
      </div>
    </div>
  );
}

export default Add;

원인
JSON 서버 실행은 http://localhost:4000으로 실행하고 있었고 Add.jsx에서 handleAdd함수 fetch 요청이 http://localhost:3000/posts로 전송되고 있었다.

해결방법
Add.jsx에서 handleAdd함수 fetch 요청이 http://localhost:4000/todos로 수정해주면 db.json에 등록한 값이 저장된다.

// db.json
{
  "todos": [
    {
      "id": 1,
      "title": "react"
    },
    {
      "id": 2,
      "title": "react2"
    },
    {
      "id": 3,
      "title": "react3"
    },
    {
      "author": "ㅁㅇㅁㄴㅇ",
      "title": "ㅁㅇㅁㄴㅇ",
      "content": "ㅁㅇㅁㅇㅁㄴㅇ",
      "id": 4
    },
    {
      "author": "ㅁㄴㅇㅁㄴㅇ",
      "title": "ㅁㅇㅁㄴㅇ",
      "content": "ㅁㅇㅁㅇㅇㅁ",
      "id": 5
    }
  ],
}
  // 수정 할 부분
  const handleAdd = () => {
    const newPost = {
      author: author,
      title: title,
      content: content,
    };

    fetch("http://localhost:4000/todos", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify(newPost),
    })
      .then((response) => response.json())
      .then((data) => {
        console.log("New post added:", data);
        // 추가 완료 후 필요한 상태 업데이트 등의 작업 수행
      })
      .catch((error) => {
        console.error("Error adding post:", error);
        // 오류 처리
      });
  };

db.json에 저장이 된 것을 확인 할 수 있다.

느낀 점
서버와 클라이언트 간의 데이터 통신을 위해 fetch를 사용하였다. 하지만, 어떤 이유에서인지 fetch 요청이 제대로 작동하지 않았다.원인은 fetch 요청 URL이 잘못되었던 것이었다.
그러던 중, 개발환경에서 사용 중인 포트 번호를 잘못 기재한 것을 발견하였다.
실제로 fetch 요청이 보내지는 URL은 "http://localhost:4000/todos"여야 했지만, 잘못된 포트 번호로 "http://localhost:3000/posts"로 요청이 전송되고 있었다.

코드를 작성하거나 설정을 변경할 때 URL, 포트 번호, 경로 등을 정확하게 확인하고 작성하는 습관을 가져야 함을 깨닫게 되었다. 이번 문제해결을 통해 앞으로 불필요한 시간을 낭비하는 것을 방지할 수 있을 것 같다.

profile
오늘은 무슨 오류를 만날까?! 널 만나러 가는 길~ LOL

0개의 댓글