해결된 질문
24.07.23 10:40 작성
·
150
0
포트폴리오 만든 게시판 정보 입력후 등록하기 버튼을 누르면 아래와 같이 오류가 뜹니다.
new:1 Access to fetch at 'http://backend-practice.codebootcamp.co.kr/graphql' from origin 'http://localhost:3004' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: The 'Access-Control-Allow-Origin' header has a value 'http://localhost:3000' that is not equal to the supplied origin. Have the server send the header with a valid value, or, if an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
코드상에는 문제가 없는 거같은데..
주소 확인 부탁드립니다.. ㅠ
import { gql, useMutation } from "@apollo/client";
import { useRouter } from "next/router";
import React, { useState } from "react";
import {
Address,
ButtonWrapper,
Contents,
ImageWrapper,
InputWrapper,
Label,
OptionWrapper,
Password,
RadioButton,
RadioLabel,
SearchButton,
Subject,
SubmitButton,
Title,
UploadButton,
Wrapper,
Writer,
WriterWrapper,
Youtube,
Zipcode,
ZipcodeWrapper,
} from "../../../styles/boardsNew";
const CREATE_BOARD = gql`
mutation createBoard($createBoardInput: CreateBoardInput!) {
createBoard(createBoardInput: $createBoardInput) {
_id
}
}
`;
export default function BoardsNewPage() {
const router = useRouter();
const [writer, setWriter] = useState("");
const [password, setPassword] = useState("");
const [title, setTitle] = useState("");
const [contents, setContents] = useState("");
const [writerError, setWriterError] = useState("");
const [passwordError, setPasswordError] = useState("");
const [titleError, setTitleError] = useState("");
const [contentsError, setContentsError] = useState("");
const [createBoard] = useMutation(CREATE_BOARD);
const onChangeWriter = (event) => {
setWriter(event.target.value);
if (event.target.value !== "") {
setWriterError("");
}
};
const onChangePassword = (event) => {
setPassword(event.target.value);
if (event.target.value !== "") {
setPasswordError("");
}
};
const onChangeTitle = (event) => {
setTitle(event.target.value);
if (event.target.value !== "") {
setTitleError("");
}
};
const onChangeContents = (event) => {
setContents(event.target.value);
if (event.target.value !== "") {
setContentsError("");
}
};
const onClickSubmit = async () => {
if (!writer) {
setWriterError("작성자를 입력해주세요.");
}
if (!password) {
setPasswordError("비밀번호를 입력해주세요.");
}
if (!title) {
setTitleError("제목을 입력해주세요.");
}
if (!contents) {
setContentsError("내용을 입력해주세요.");
}
if (writer && password && title && contents) {
try {
const result = await createBoard({
variables: {
createBoardInput: {
writer,
password,
title,
contents,
},
},
});
console.log(result.data.createBoard._id);
router.push(`/boards/${result.data.createBoard._id}`);
} catch (error) {
alert(error.message);
}
}
};
return (
<Wrapper>
<Title>게시글 등록</Title>
<WriterWrapper>
<InputWrapper>
<Label>작성자</Label>
<Writer
type="text"
placeholder="이름을 적어주세요."
onChange={onChangeWriter}
/>
<div style={{ color: "red" }}>{writerError}</div>
</InputWrapper>
<InputWrapper>
<Label>비밀번호</Label>
<Password
type="password"
placeholder="비밀번호를 작성해주세요."
onChange={onChangePassword}
/>
<div style={{ color: "red" }}>{passwordError}</div>
</InputWrapper>
</WriterWrapper>
<InputWrapper>
<Label>제목</Label>
<Subject
type="text"
placeholder="제목을 작성해주세요."
onChange={onChangeTitle}
/>
<div style={{ color: "red" }}>{titleError}</div>
</InputWrapper>
<InputWrapper>
<Label>내용</Label>
<Contents
placeholder="내용을 작성해주세요."
onChange={onChangeContents}
/>
<div style={{ color: "red" }}>{contentsError}</div>
</InputWrapper>
<InputWrapper>
<Label>주소</Label>
<ZipcodeWrapper>
<Zipcode placeholder="07250" />
<SearchButton>우편번호 검색</SearchButton>
</ZipcodeWrapper>
<Address />
<Address />
</InputWrapper>
<InputWrapper>
<Label>유튜브</Label>
<Youtube placeholder="링크를 복사해주세요." />
</InputWrapper>
<ImageWrapper>
<Label>사진첨부</Label>
<UploadButton>+</UploadButton>
<UploadButton>+</UploadButton>
<UploadButton>+</UploadButton>
</ImageWrapper>
<OptionWrapper>
<Label>메인설정</Label>
<RadioButton type="radio" id="youtube" name="radio-button" />
<RadioLabel htmlFor="youtube">유튜브</RadioLabel>
<RadioButton type="radio" id="image" name="radio-button" />
<RadioLabel htmlFor="image">사진</RadioLabel>
</OptionWrapper>
<ButtonWrapper>
<SubmitButton onClick={onClickSubmit}>등록하기</SubmitButton>
</ButtonWrapper>
</Wrapper>
);
}
import { gql, useQuery } from "@apollo/client";
import { useRouter } from "next/router";
import {
Avatar,
AvatarWrapper,
Body,
BottomWrapper,
Button,
CardWrapper,
Contents,
CreatedAt,
Header,
Info,
Title,
Wrapper,
Writer,
} from "../../../styles/boardsDetail";
export const FETCH_BOARD = gql`
query fetchBoard($boardId: ID!) {
fetchBoard(boardId: $boardId) {
_id
writer
title
contents
createdAt
}
}
`;
export default function BoardDetailPage() {
const router = useRouter();
const { data } = useQuery(FETCH_BOARD, {
variables: { boardId: router.query.boardId },
});
return (
<Wrapper>
<CardWrapper>
<Header>
<AvatarWrapper>
<Avatar src="/images/avatar.png" />
<Info>
<Writer>{data?.fetchBoard?.writer}</Writer>
<CreatedAt>
{new Date(data?.fetchBoard?.createdAt).toLocaleDateString()}
</CreatedAt>
</Info>
</AvatarWrapper>
</Header>
<Body>
<Title>{data?.fetchBoard?.title}</Title>
<Contents>{data?.fetchBoard?.contents}</Contents>
</Body>
</CardWrapper>
<BottomWrapper>
<Button>목록으로</Button>
<Button>수정하기</Button>
<Button>삭제하기</Button>
</BottomWrapper>
</Wrapper>
);
}
import "../styles/globals.css";
import { ApolloClient, InMemoryCache, ApolloProvider } from "@apollo/client";
export default function App({ Component, pageProps }) {
const client = new ApolloClient({
uri: "http://backend-practice.codebootcamp.co.kr/graphql",
cache: new InMemoryCache(),
});
return (
<ApolloProvider client={client}>
<Component {...pageProps} />
</ApolloProvider>
);
}
답변 2
0
2024. 07. 24. 08:30
안녕하세요! 민선님!
스스로 문제를 해결하신 것을 보니, 점점 개발자가 되어가는 것 같아 보기 좋네요!^^
추가적인 도움을 드리자면, 현재 백엔드 API에서 localhost:3000 주소만 허락을 해주고 있기 때문이랍니다!
만약, 실무에서 localhost:3004를 사용해야하는 상황이라면, 백엔드 개발자분께 3004번 포트를 열어달라고 요청하시면 되세요!^^
0
2024. 07. 23. 16:20
다른 답변보고 해결했습니다!
local host 주소를 3000밖에 지원 안한다고 하기에 해당주소로바꿔줬더니 성공적입니다 ㅠㅠ
local host 변경 방법(이미 3000을 다른 파일에서 사용중인 경우)은 터미널에 아래와 같이 입력 후
lsof -i :3000
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
node 12345 user 21u IPv4 0x.... 0t0 TCP *:3000 (LISTEN)
위의 예시와 같이 나오면 PID를 아래의 예시와 같이 명령해주시면 됩니다.
kill -9 12345