사용자가 회원가입이나 신청 프로세스 도중 페이지를 벗어나거나 새로고침할 경우 기존에 입력되는 모든 값이 초기화된다! 이를 의도한 사용자도 있겠지만, 실수로 눌려졌다면 좋은 사용자 경험을 줄 수 없을 것이다. beforeunload 사용자가 페이지를 떠나거나 닫을 때 발생하는 이벤트이다. 사용자가 페이지를 떠나려 할 때, 변경되지 않은 사항들을 저장했는지 확인시켜 줄 때 사용한다. 새로고침, 뒤로 가기, 브라우저 닫기 등의 경우에 아래와 같이 실행된다! window.addEventListener("beforeunload", (event) => { event.preventDefault(); }); 안내 메시지를 변경할 수 있나 했는데 일반적인 브라우저에서는 beforeunload 이벤트를 취소할 때 보이는 ..
카카오, 네이버와 애플까지! 소셜 로그인 구현이 필요했다. 소셜 로그인을 구현하며 고민했던 부분들 위주로 작성해 보겠다. 소셜 로그인 구현 각 redirect uri이 있는데, 이는 소셜 로그인이 성공 후(카카오, 네이버 등에서 로그인 후) 다시 서비스 페이지로 돌아올 페이지 위치이다. 성공 후 발급된 인가코드가 포함되어서 redirect uri로 이동된다! 일반적인 로그인 구현 과정은 다른 블로그 분들이 설명을 너무 잘해주셔서 내가 고민했던 부분들 위주로 작성해 보겠다. 소셜 로그인 성공 후 이전 페이지로 어떻게 보내지? 예를 들어 서비스에서 로그인 전 상태일 경우! 구매하기 클릭 -> 로그인 화면으로 이동 -> 로그인 성공 -> 메인 페이지로 이동이 아니라 구매하기 클릭 -> 로그인 화면으로 이동 -..
처음 해보는 엑셀 다운로드다! ㅎㅎ 백앤드에서 엑셀 파일이랑 엑셀 파일명을 response에 담아서 보내주신다고 해서 프론트에서 받아서 다운로드하는 부분을 구현해 봤다 그전에! Blob (Binary Large Object) 대용량의 바이너리를 다룰 수 있는 객체로, 백앤드에서 엑셀 파일을 만들어서 프론트에 받을 때 Blob객체를 활용하면 된다 1. api 호출 axiosT.post('/test/excel-download', { ...form }, { responseType: 'blob', headers: { 'Content-Type': 'multipart/form-data', }, }, ) 2. 엑셀 다운로드 api로 호출 결과값으로 Blob 객체를 생성해 준다 a 태그를 생성해서 href에 Blob ..
모바일에서 스크롤 없이 높이를 딱 맞게 사용하고 싶어서 height: 100vh로 설정했다 개발자도구(모바일)로 확인 했을 때는 잘 적용이 된 것처럼 보였다 하지만!! 실제 모바일 기기로 크롬, 사파리에서 확인 하니 높이가 딱 맞게 적용이 안되고 있었다 🥲 (화면의 오른쪽에 스크롤이 생겨버렸다..ㅎㅎ) 이 이유는 100vh가 상단 주소창 영역과 하단의 네비게이션 영역의 사이즈까지 반영을 못하기 때문이다 해결 방법 javascript에서 window.innerHeight를 이용해 1vh를 계산해 주면 된다 function setMobileVh() { let mobileVh = window.innerHeight * 0.01; document.documentElement.style.setProperty("--..
모바일 웹을 이용하다 보면 "앱에서 보실래요?"라는 팝업과 함께 앱 설치를 유도한다 이때 모바일 웹에서 앱으로 이동하기 위해서는 두 가지 경우로 나뉘는데 앱이 있는 경우 앱에서 해당 링크 페이지를 보여준다 앱이 없는 경우 구글 스토어나 앱 스토어로 이동해 앱 설치를 유도한다 앱의 설치 여부를 알 수 있는 방법은 없다! 그래서 살짝의 꼼수를 써서 구현했다 function deeplinker(url) { let isChange = false; const userAgent = navigator.userAgent; if (userAgent.match(/Android/i)) { // 안드로이드일 때 setTimeout(()=>{ if (!isChange) { gotoappstore(); } } ,100); } e..
현재 상황나는 jwt방식을 사용하며accessToken과 refreshToken을 모두 쿠키에 보관하고 있다.모두 httpOnly, Secure 옵션을 주어 안전하게 사용하고자 했다.httpOnly: document.cookie를 통해 자바스크립트에서 접근을 막는다. Secure: HTTPS로 통신하는 경우에만 쿠키가 전송된다. 전체적인 큰 그림은 아래와 같다.accessToken 재발급 시 refreshToken을 왜 갱신하느냐... 할 수도 있지만 서비스 상 로그인 상태를 최대한 오래 유지하기 위해 이렇게 진행했다. token을 어디에 저장하고 어떻게 관리할지에 대해 정답은 없고 주어진 상황에 맞게 사용하면 되는 거 같다.axios 인스턴스 생성프론트에서 쿠키를 직접 다룰 수 없어(httpOnly옵션..
내가 만들고자 하는 바텀시트는 1. pc에서는 모달형태로 나타나고 mobile에서는 아래에서 위로 올라오는 바텀시트 형태로 나타나야 한다. 2. 외부에서 열고 닫을 수 있어야 한다. 3. full(전체가 채워지도록)로 당겨질 수 있어야 한다. 4. 제목과 상단에 닫기 버튼의 여부를 attribute 형태로 전달받는다. 이런 기능을 가지고 있어야 한다. + 미리 결과를 보여주자면...! 순수한 자바스크립트로 바텀시트를 만들어봤다 바텀시트를 여러 곳에서 간편하게 쓰기 위해(함수로도 만들어보고 클래스로 해보려다가...) Web components로 만들게 되었다 ㅎㅎ 리액트나 뷰 등을 사용하지 않고 순수 자바스크립트로 컴포넌트를 만들 수 있는 방법이 있는데 바로 Web components를 사용하면 된다!! ..
상품 리스트에서 상세 상품을 본 후 뒤로 가기 시 원래 스크롤 위치를 기억했다가 보여주고 싶었다. 1. scroll 이벤트가 발생 시 해당 scrollTop의 값을 session에 저장 여기서 scroll이 발생 시마다 session에 값이 저장되는 것은 낭비이다. throttle를 이용해 마지막 이벤트가 발생하고 일정 시간(400ms)이 지나기 전까지 다시 호출되지 않도록 막아줬다. document.addEventListener('scroll', () => { if (!timer) { timer = setTimeout(() => { timer = null; const scrollValue = document.documentElement.scrollTop; sessionStorage.setItem("ma..
slice 배열의 begin부터 end까지에(end는 미포함) 대한 얕은 복사본을 새로운 배열 객체로 반환한다. 원본의 배열은 바뀌지 않는다. arr.slice([begin[, end]]) begin : 시작점 인덱스 end : 종료 지점 인덱스 (end 인덱스는 제외하고 추출) 리턴값 : 추출한 요소를 포함한 새로운 배열 const animals = ['ant', 'bison', 'camel', 'duck', 'elephant']; console.log(animals.slice(2)); // ["camel", "duck", "elephant"] console.log(animals.slice(2, 4)); // ["camel", "duck"] console.log(animals.slice(1, 5)); ..
나의 경우 answer의 길이가 2자 이하라면 마지막 문자를 answer의 길이가 3이 될 때까지 반복해서 끝에 붙이기를 하기 위해 아래와 같이 구현을 했다. while (answer.length