로컬에서 구현을 완료하고 버셀에 배포하려는데 아래와 같은 에러가 출력되었다.
문제가 발생한 이유는 아래와 같았다.
Mixed Content
가 발생하고 있었다. 초기 HTML이 https
연결을 통해 로드되지만 다른 리소스(이미지, 스크립트 등)는 http
연결을 통해 로드될 때 발생.
안전하지 않은 http
프로토콜을 사용하게 되면 전체 페이지의 보안이 약화된다. ==> 공격자가 네트워크 연결을 도청하고 통신을 보거나 수정하는 등의 경로 내 공격에 취약해진다.
해당 문제를 해결하기 위해서는 몇 가지 방법이 있다.
<meta httpEquiv="Content-Security-Policy" content="upgrade-insecure-requests" />
를 넣으면 http요청을 https로 바꿔준다고한다. Metadata
를 설정하는 과정에서 http-equiv
옵션은 아직 지원하지 않는다고 한다. next docs사실 위에꺼를 할 필요없이 https
API를 받아오면 되는데,
서울 열린 데이터광장에서는 https
데이터를 지원하지 않는다.
결론적으로는 첫 번째 방법은 실패
getServerSideProps
는 서버에서 렌더링을 하고 브라우저에서는 실행되지 않는다.
해당 방법을 사용하면 서버에서 렌더링하여 브라우저로 쏘기 때문에 백엔드 서버를 사용하는 것과 같은 효과를 볼까 싶어서 사용해보고자 했다.
사용 방법은 아래 코드와 같다.
export const getServerProps = async() => {
try{
const res = await fetch('api code');
if(res.status === 200){
const user = await res.json();
return {props: {user}}
}
return {props:{user}}
}catch(err) // code..
}
const getUser = ({user}) => {
const userName = user && user.name;
return <p>{userName}</p>
}
그런데 데이터가 다 undefined로 넘어가지는 문제가 발생했다.
예제와 똑같이 테스트를 만들어서 실행해봐도 왜인지 모르겠는데 계속 undefined만 출력이 되었다.
해당 방법은 다음에 사용해보기로 하고 마지막 남은 방법을 사용해보고자 했다.
해당 경로로 요청이 들어오면 다른 대상 경로에 매핑하는 기능이다.
URL 프록시 역할을 하고, 대상 경로를 마스킹하여 사용자가 사이트에서 자신의 위치를 변경하지 않은 것처럼 보이게 한다.
// next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
async rewrites() {
return [
{
source: "/api/dataList", // 요청한 경로
destination: `https://jsonplaceholder.typicode.com/users`, // 내가 사용할 경로
},
];
},
};
module.exports = nextConfig;
처음에는 저 source
경로가 라우팅 소스경로인가 싶어서 라우팅 주소를 사용했는데 계속 에러를 뱉어내서 몇 시간을 허비했는데 라우팅 주소가 아닌 내가 요청하는 api경로를 적는 부분이였다.
세번째 방법은 rewrites
를 사용하여 해결했다.
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
async rewrites() {
return [
{
source: "/api/parkingList/:start/:end",
destination: `${process.env.NEXT_PUBLIC_API_URL}/:start/:end`,
},
];
},
};
module.exports = nextConfig;
const response = await fetch(`api/parkingList/${startIndex}/${endIndex}`);
위와 같이 fetch
를 하면 source
부분의 경로에 맞는 경우 내가 호출하고 싶은 API로 재작성하여 호출한다.
뒤에 붙어있는 :start
부분은 경로가 일치할 경우를 적은 것이다.
와일드카드 경로로 일치하고 싶으면 /:slug*
와 같은 방식으로 적으면 된다.
++ 추가적으로 vercel환경과 local환경을 다르기때문에 환경마다 설정을 어떻게 해줘야하나 싶었는데 다음과 같은 방법으로 해결했다.
//.env
공통으로 사용하는 환경변수
NEXT_PUBLIC_API_URL = code..
//.env.local
로컬환경에서 실행되는 환경변수
NEXT_PUBLIC_BASE_URL = http://localhost:3000
//.env.production
NEXT_PUBLIC_BASE_URL = https://parking-good.vercel.app
Production
, Preview
, Development
본인이 필요한 조건에 따라 설정하고 등록해두면 로컬에서 실행할 때, 배포환경에서 실행할 때 추가적으로 코드를 지웠다 배포하지 않고 문제없이 같은 결과를 확인할 수 있다. Parking-issue1
해당 이슈 해결하려고 3일정도 걸린거 같은데, Next.js를 사용해서 프로젝트는 처음 진행하다 보니까 next.js로 공부하고 해당 이슈도 찾아보고 하면서 시간을 많이 사용한 것 같다.
그래도 직접 해결하려고 찾아보면서 .env
관리에 대해서도 공부하고 rewrites
와 더불어 redirects
도 같이 공부하는 경험이였다.
getServerSideProps
는 왜 안되는지 아직 잘 모르겠는데, 추후에 해당 메소드를 또 써야할 때가 올 수 있으므로 프로젝트가 끝난 뒤에 다시 한번 도전해봐야할 것 같다.