728x90

서비스를 운영하다보면 아무리 이미지 압축을 잘 하더라도,

이미지 자체가 워낙 큰 파일이라 로드에 시간을 길게 소요하는 경우가 발생합니다.

 

이런 경우를 대비해 이미지 로드에 부가적인 처리를 좀 해주면

멋스럽고 좋은 사용자 경험을 제공할 수 있습니다.

 

간단한 js와 css를 함께 응용해야하는데,

예제 코드들로 살펴보도록 하겠습니다.

 

[ 주요 키워드: classList, Image ]

 

1. 기본 핵심코드

1.1 html

<div class='image-wrapper'>
  <img class='image-thumbnail' src='/no-image.png' alt='이미지' />
</div>

1.2 css

.image-wrapper {
  background-color: #dadada;
  
  &.visible {
    background-color: transparent;
    transition: all 0.25s;
  }
  
  &.visible > .image-thumbnail {
    transform: scale(1);
    opacity: 1;
  }
}

.image-thumbnail {
  transform: scale(0.5);
  opacity: 0;
  
  width: 100%;
  height: auto;
  object-fit: cover;
}

1.3 js

<script>
  const source = "https://t1.daumcdn.net/tistory_admin/static/top/pc/img_common_tistory_200910.png";
  const image = new Image();
  image.setAttribute('src', source);
  image.onload = function() {
    const wrapper_node = document.querySelector('image-wrapper');
    const node = document.querySelector('image-thumbnail');
    
    wrapper_node.classList.add('visible')
    node.src = source;
  }
</script>

 

 

자, 이렇게하면 이미지가 로드된 후에 고급진 이펙트와 함께 이미지가 나타나게됩니다.

가능하다면 no image상태일때 이미지를 설정해줘도 좋겠죠?

 

 

하지만, 이렇게 단일 이미지를 로드할때보다는

여러 이미지를 로드할때 이것은 더욱 빛을 바랍니다.

예를들어,  Youtube의 영상 목록을 불러올때나 와디즈에서 펀딩 목록을 불러올때

image가 로드되는동안 기본 이미지(혹은 배경색)을 보여주다가

이미지가 로드되면 약간의 효과와 함께 이미지를 띄워줍니다.

 

 

이번에는 React 예제로 살펴보겠습니다.

예시의 편의성을 위해 데이터는 어딘가 서버로부터 불러왔다고 가정하겠습니다.

그리고 실제 개발에서 쓸수있도록, 페이지 스크롤에 따라 이미지 로드와 효과 적용을 핸들링 해보도록 하겠습니다.

 

const ImageList = ({ images ) => {
  return (
    <>
    {
      images.map((img, index) => {
        const image = new Image();
        image.load = function() {
          // how...?
        }
        return (
          <div key={"image-item-" + index.toString()} className='image-wrapper>
            <img className='image-thumbnail' alt='썸네일' />
          </div>
        );
      })
    }
    </>
  )
}

 

이전과 비슷한데  React라는 점, 그리고 단일 이미지가 아닌 list라는 부분에서 차이가 발생했습니다.

여기서 어떻게 각기 알맞는 이미지 태그에 이미지를 넣어줄 수 있을까요?

 

여러가지 방법이 있을 수 있지만,

여기서는 React hooks의 useRef를 사용해보도록 하겠습니다.

(최근에, hooks를 좀 익혀보는 중이거든요)

 

[ 주요 키워드: classList, Image, useRef, useEffect ]

 

<script>
import React, { useRef, useEffect } from 'react';

const ImageList = ({ images ) => {
  return (
    <>
    {
      images.map((img, index) => {
        const image_card = useRef(null);
        
        useEffect(() => {
          scorller();
          window.addEventListener('scroll', scroller, false);
          
          return window.removeEventListener('scoll', scroller, false);
        });
        
        const scroller = () => {
          const { classList: classes, offsetTop, clientHeight } = image_card.current;
          
          // 이미 visible 처리된 element는 중복작업 방지 - 쓸데없는 메모리낭비x
          if (classes.contains('visible')) return null;
          
          // 화면 스크롤 높이에따라 element가 노출되고 있는지를 체크
          const visible_timing = window.innerHeight + windwo.scrollY >= offsetTop - (clientHeight / 2);
          
          // scroll 위치까지 고려해서 이미지 로드 처리
          if (visible_timing) {
            const image = new Image();
            image.setAttribute('src', img);
            image.onload = function() {
              const node = image_card.current.querySelector('.image-thumbnail');
              if (node) {
                classes.add('visible');
                node.src = img;
              }
            }
          }
        }
        
        return (
          <div 
            key={'image-item-' + index.toString()} 
            className='image-wrapper'
            ref={image_card}
          >
            <img className='image-thumbnail' alt='썸네일' />
          </div>
        );
      })
    }
    </>
  )
}
</script>

 

이 처럼 React로 이미지 목록을 구현하는 방법을 살펴보았습니다.

어떤가요?

코드가 어렵다거나 하지는 않죠?

생각보다 간단하게 괜찮은 효과를 낼수 있음을 알 수 있습니다.

 

좀 더 나아간다면 ImageCard를 모듈화 하면 더 좋겠죠?

 

 

728x90
반응형
728x90

transtion 효과를 쓰다보면 의도치 않게

주변 컴포넌트가 깜박이게되는 현상을 맞이할때가 있다.

 

transition을 먹여둔 컴포넌트에 아래의 css 한줄만 추가하면 이 문제를 해결할 수 있다.

-webkit-backface-visibility: hidden;

 

728x90
반응형

'개발, 코딩 > CSS' 카테고리의 다른 글

Bootstrap 기본 (Grid, Container, Column, Spacing)  (0) 2022.10.14
반응형 작업 돌아보기 (+ flex)  (1) 2022.09.27
jQuery - easescroll, chrome issue  (0) 2022.02.17
HTML, div를 input으로 쓰기  (0) 2021.11.16
viewport에 대하여  (1) 2021.01.21
728x90

자바스크립트를 쓰는 개발자라면 매일 같이 마주하는

Object타입

이놈, 유용하지만 조심해서 써야한다.

 

코드를 쓰다보면 객체를 '복사'하게 되는 경우가 많은데 예를들면 아래와같다

const wallet = {
  card: 3,
  money: 0
};

const friend1_wallet = wallet;
const friend2_wallet = wallet;

console.log(wallet) // { card: 3, money: 0 }
console.log(friend1_wallet)  // { card: 3, money: 0 }
console.log(friend2_wallet)  // { card: 3, money: 0 }

 

자, 너무 나도 당연한 결과이다 그렇다면 이번엔 아래의 결과를 예상해보자

wallet.card = 4;

console.log(wallet);
console.log(friend1_wallet);
console.log(friend2_wallet);

 

아래의 결과가 정확히 예상되는가?

console.log(wallet); // { card: 4, money: 0 }
console.log(friend1_wallet); // { card: 4, money: 0 }
console.log(friend2_wallet); // { card: 4, money: 0 }

 

왜, 이런일이 생길까?

c와 같은 언어를 배우고 사용해본 개발자라면 메모리 참조에 대해서 알것이다.

const friend1_wallet = wallet; // 복사가 아닌 참조

 

friend1_wallet은 wallet이 가리키는 메모리 영역을 똑같이 바라보게 했을 뿐이기 때문에,

wallet을 바꾸면 당연하게도 firend1_wallet의 값이 바뀌게 되는것이다.

 

그렇다면, 

"지갑을 똑같이 복사한 다음 복사한 지갑에만 카드를 두개 더 넣어두고싶어요~"

라고 했을때 어떻게 처리를 해야할까?

 

우리의 javacript는 이를 위해 Object.assign() 메소드를 제공한다.

const wallet = {
  card: 3,
  money: 0
};

const friend1_wallet = Object.assign({}, wallet);
const friend2_wallet = Object.assign({}, wallet);

console.log(wallet) // { card: 3, money: 0 }
console.log(friend1_wallet)  // { card: 3, money: 0 }
console.log(friend2_wallet)  // { card: 3, money: 0 }

이렇게 하면 우리는 빈 객체에 wallet을 복사하게 된다.

 

따라서, 아래와 같이 실했했을때 결과를 예상해보자.

wallet.card = 6;

console.log(wallet);
console.log(freind1_wallet)
console.log(freind2_wallet)

 

결과를 예상해봤는가?

console.log(wallet); // { card: 6, money: 0 }
console.log(freind1_wallet); // { card: 3, money: 0 }
console.log(freind2_wallet); // { card: 3, money: 0 }

 

자, 이제 목적을 달성했다.

그런데...

"저는 지갑에 어머니가 맡기신 돈도 보관해야되요. 돈을 두가지로 분류해서 저장해주세요!" 라고 한다면

const wallet = {
  card: 3,
  money: {
    mother: 5000,
    mine: 100,
  },
};

const freind1_wallet = Object.assign({}, wallet);
const freind2_wallet = Object.assign({}, wallet);

console.log(wallet); // { card: 3, { mother: 5000, mine: 100 } }
console.log(freind1_wallet); // { card: 3, { mother: 5000, mine: 100 } }
console.log(freind2_wallet); // { card: 3, { mother: 5000, mine: 100 } }

 

자... 이런 상황에서 엄마가 1000원을 더 맡기셔서 wallet에 돈을 추가하는 상황이 되었다.

아래 상황의 결과를 예측해보자

wallet.money.mother += 3000;

console.log(wallet);
console.log(friend1_wallet);
console.log(friend2_wallet);

 

결과는 아래와 같다.

console.log(wallet); // { card: 3, money: { mother: 8000, mine: 100 } }
console.log(friend1_wallet); // { card: 3, money: { mother: 8000, mine: 100 } }
console.log(friend2_wallet); // { card: 3, money: { mother: 8000, mine: 100 } }

 

어라! 복사하면 참조 문제는 발생하지 않는것 아니었나요?

자, 여기서 이제 "얕은 복사" 라는 개념이 나온다.

Object.assign()은 얕은 복사를 해주는 메소드로 1Depth 까지만 그 특성을 유지해준다.

 

전개연산자도 이와 마찬가지다.

// 전개연산자 얕은복사 예시
const wallet = {
  card: 3,
  money: 0
};

const freind1_wallet = { ...wallet };

console.log(wallet); // { card: 3, money: 0 }
console.log(freind1_wallet); // { card: 3, money: 0 }

wallet.card = 4;

console.log(wallet); // { card: 4, money: 0 }
console.log(freind1_wallet); // { card: 3, money: 0 }


// 전개연산자 깊은복사...
const wallet = {
  card: 3,
  money: {
    mother: 5000,
    mine: 100
  }
};

const freind1_wallet = { ...wallet };

console.log(wallet); // { card: 3, money: { mother: 5000, mine: 100 } }
console.log(freind1_wallet); // { card: 3, money: { mother: 5000, mine: 100 } }

wallet.money.mother += 3000;

console.log(wallet); // { card: 3, money: { mother: 8000, mine: 100 } }
console.log(freind1_wallet); // { card: 3, money: { mother: 8000, mine: 100 } }

 

이런 문제를 해결하려면 어떻게해야 할까?

늘 그렇듯 방법이 있다.

1. 재귀함수를 통한 복사

2. JSON 메소드 응용하기

3. lodash등 라이브러리르 이용하기

 

1. 재귀함수를 통한 복사는 빈 객체를 생성하고 for...in 함수로 객체의 key,value를 빈 객체에 집어넣는 방식이다.

프로젝트 내에 deepCopy함수를 하나 생성해두고 두고두고 쓰면 제법 유용하다.

function deepCopy(obj) {
  const newObj = {};

  for (let key in obj) {
    if (typeof obj[key] === 'object') {
      newObj[key] = deepCopy(obj[key]);
    } else {
      newObj[key] = obj[key];
    }
  }

  return newObj;
}

 

2. JSON 메서드를 응용하는 방법은 간편하지만 퍼포먼스 적으로 좋지않다고 한다. 또한, File 타입 복사간 문제가 발생하니 사용을 지양하는게 좋을것으로 생각된다.

const obj = {
  a: 1,
  b: {
    b_1: 2,
    b_2: 3,
  }
}

const copiedObj = JSON.parse(JSON.stringify(obj));

 

3.  lodash 등 라이브러리 사용하기는 쉽고 강력하므로 개인적으로 이 방식을 권장하는바이다.

import _ from 'lodash';

const obj = {
  a: 1,
  b: {
    b_1: 2,
    b_2: 3,
  }
}

const copiedObj = _.cloneDeep(obj);
728x90
반응형
728x90

nodejs에서 pdfjs-dist 라이브러리를 사용하기위해 canvas가 필요했다.

(pdfjs가 canvas에 의존적이기 때문)

 

그런데 linux기반 서버에서 canvas설치 후 실행시 다음과 같은 에러가났다.

Cannot find module '../build/Release/canvas'

 

한참을 헤맸다.

node-gyp rebuild니 permission 에러니...

 

정답은 늘 가까이에 있고, 많이 사용하는 라이브러리는 늘 답안이 나와있다. (감사해요 stackoverflow)

I just use "npm uninstall canvas" and then install using "npm i canvas"

 

이 단 한줄의 문장으 내 머리를 후려쳤다.

생각해보니 canvas에서 지시한 지시사항을 실행하기 전에 canavs를 먼저 설치한것이다.

 

sudo apt-get install build-essential libcairo2-dev libpango1.0-dev libjpeg-dev libgif-dev librsvg2-dev

 

위는 canvas에서 ubuntu환경일 경우 먼저 설치하라고 안내해준 library들이다.

 

나는 이미 진행했으므로

npm uninstall canvas
npm install canvas

 

canvas를 다시 설치해주는것만으로 해결되었다.

 

pdfjs는 pdf to png작업을 위해 사용하였는데, 곧 관련내용을 정리해볼 예정이다.

728x90
반응형
728x90

브라우저 캐시는 사이트의 속도나 보안에 큰 영향을 미친다.

과거 캐시에 데이터를 때려박는 형태에서는 브라우저 캐시만 탈취하면 사용자 정보를 취득할수도 있었다.

현대에는 간단한 정보는 browser의 localStorage/sessionStorage를 이용해 처리한다.

 

유저 기반 사이트라면 반드시 들어가는 기본이자 가장 중요한 로그인/로그아웃

위 주제는 파도파도 끝이없다.

 

Node.js로 서버 개발을 하는 나는 cache를 이용해서 사용자 정보를 주고받는다.

이때, javascript로는 캐시를 읽어볼수 없게하는 httpOnly옵션과

https에서만 캐시를 캐치가능하게하는 secure옵션을 사용해 보안성을 높인다.

 

사용자 데이터는 JWT를 이용해 토큰화 해서 캐시에 담아 주고받는다.

통신 패킷 자체가 탈취당하더라도 암호화된 데이터는 비밀키가 탈취당하지 않는한 안전하다.

 

그런데, 아주 기본 상식적인 부분에서 문제를 캐치하지 못해 오늘 고생을 하였다.

요점은 이것이다.

naver.com에 로그인하면 m.naver.com  / blog.naver.com / finance.naver.com 등

naver.com의 서브도메인에 해당하는 사이트들에 재 로그인할 필요없이 활동이 가능하다.

그 방법은 브라우저 캐시에 있다. 네트워크 쿠키탭을 뜯어보면 NIDSES (domain: .naver.com)가 포함되어있는것을 알수있다. 각 쿠키가 어떤역할을 하는지 상세한 내용은 알수없으나 분명 사용자 데이터를 포함하고 있고 해당 데이터는 브라우저에 저장된다.

그렇기 때문에 하위 도메인에서도 계정상태를 유지할수 있는것이다.

 

이 부분을 잊어버린 나는 문제아닌 문제와 힘겨운 싸움을 했다.

회사 메인 도메인 사이트에서 로그아웃을 했더니, 서브 도메인 사이트에서도 자꾸만 로그아웃 되는게 아닌가?

이거는 곤란한대?! 하며 속앓이를 했다.

 

어떻게 "잘" 해결할수있는 방법은 없을까? 하고 고민도 해보고 여러가지 시도도 해보았다.

보안이 중요하지 않은 사이트에서는 꼼수는 있지만, 정상적인 사이트에서라면 해당 이슈를 거스리지않는게 맞다는 결론을 내렸다.

728x90
반응형
728x90

검색의 기본, 여러 데이터 중에 특정 대상만 불러오는것

기본이자 가장 어려운 파트라고도 할 수 있다.

 

특히, 보기좋은 코드가 개발자를 기분좋게하는데 검색쿼리를 짜다보면 자칫 코드가 길어질수있다.

여러가지 조건들이 붙기 때문이다.

 

그와중이 addFields를 남발하여  길어져버린 나의 코드가 눈에띄었다.

어디에 주로 addFields를 썼나 보니,

$lookup을 통해 다른 collection과 join한뒤 특정 document만 불러오고자 할때 리스트를 벗겨내는 과정에서 남용했다.

 

{
  $lookup: {
    from: 'users',
    localField: 'userId',
    foreginField: '_id',
    as: 'user'
  }
}

// 결과 => [{ _id: ObjectId('...'), name: '...', ... }]
// 원하는 데이터는 => { _id: ObjectId('...'), name: '...', ... }
// 따라서, 사용했던 코드

{
  $lookup: {
    from: 'users',
    localField: 'userId',
    foreginField: '_id',
    as: 'user'
  }
},
{
  $addFields: {
    user: {
      $arrayElemAt: ['$user', 0]
    }
  }
}

// 결과 => { _id: ObjectId('...'), name: '...', ... }

 

원하는 document만 불러오기 위해 코드가 무려 7줄이나 길어지는 문제가 발생했다.

$addFields는 이런식으로 쓰라고 있는 기능도 아닐것으로 생각이 든다.

$addFields는 저장된 데이터는 아니지만 클라이언트에 필요한 데이터, 예를들어 sum, count 등의 데이터들을 추가하기 위해 존재할것이다.

 

그렇다면, 무엇이 적절할까. 정답은 이미 나와있다.

 

{
  $lookup: {
    from: 'users',
    localField: 'userId',
    foreignField: '_id',
    as: 'user'
  }
},
{
  $project: {
    ...,
    user: { $arrayElemAt: ['$user', 0] }
  }
}

 

7줄의 코드가 아닌 단 한줄의 코드면 충분하다.

 

728x90
반응형
728x90

18.04 기분으로 작성한 포스팅입니다.

 

ubuntu를 처음 세팅하고나면 root계정의 비밀번호를 먼저 설정해줍니다.

sudo passwd root

 

ssh 설정을 해줄건데요. 딱 3줄만 수정해주면됩니다.

nano /etc/ssh/sshd_config

 

파일을 편집을해볼까요?

PermitRootLogin yes
PasswordAuthentication yes
ChallengeResponseAuthentication no

 

다른 설정은 건드리지말고 위의 3줄만 위와같이 잡아주면 됩니다.

 

잘 설정됐는지 테스트 및 재실행을 해볼게요

# test
sudo sshd -t

# restart
sudo service sshd restart

 

재실행이 잘 됐다면, 터미널을 종료하지말고 새로운 터미널을 열어 접속을 테스트 해봅니다.

# 설정 전 접속방법
ssh -i 'key.pem' ubuntu@ip(혹은 domain)

# 설정 후 접속방법
ssh root@ip(혹은 domain)

 

보안적인 면에서는 늘 키파일로 로그인하는게 좋겠지만, 여러 상황에 따라 비밀번호 접속 설정이 필요할수 있습니다.

728x90
반응형
728x90

개발을 하다보면 사용자가 페이지에서 이탈하는 시점에 이벤트를 발생시켜야 하는 경우가 있다.

예를들어, 페이지 이탈전 저장알림을 띄운다거나 페이지에 머무는 시간을 체크하거나 할때 말이다.

 

이때 필요한게 이벤트 리스너 중에 'beforeunload'라는 것이다.

MDN 문서에 보면 beforeunload에 대해 다음과 같이 설명되어있다.

beforeunload 이벤트는 문서와 그 리소스가 언로드 되기 직전에 window에서 발생합니다. 
이벤트 발생 시점엔 문서를 아직 볼 수 있으며 이벤트도 취소 가능합니다.

 

MDN도 예시로 아래와 같은것을 들고있다.

beforeunload 이벤트를 사용하면 사용자가 페이지를 떠날 때 정말로 떠날 것인지 묻는 확인 대화 상자를 표시할 수 있습니다. 
사용자가 확인을 누를 경우 브라우저는 새로운 페이지로 탐색하고, 취소할 경우 탐색을 취소하고 현재 페이지에 머무릅니다.

 

자, 이 리스너가 무엇인지  언제필요한건지 알았으니 어떻게 쓰는지도 알아보자

window.addEventListener('beforeunload', onBeforeClosed, false);

const onBeforeClosed = (e) => {
  // 표준에 따라 기본 동작 방지
  event.preventDefault();
  // Chrome에서는 returnValue 설정이 필요함
  event.returnValue = '';
}

 

MDN 예시를 약간 변형해보았다. 브라우저 호환성을 꼭 참고해서 사용하도록 하자.

여기서 중요한 포인트가 있다.

 

예상하거나 의도하지 않은 동작이 일어나지 않게 하기위해서는

이벤트 리스너를 다시 제거해주는 작업도 진행해야한다.

window.removeEventListener("beforeunload", onBeforeClosed, false);

 

 

728x90
반응형
728x90

사용자기반 앱/웹 개발을 하다보면 Input은 안쓸수가없다고해도 과언이 아니다.

 

이때, 모바일 입력 편의성 제공을 위해 Input타입을 number로 잡아줬더니

 

숫자롤러가 나타나 디자인을 해치는 일이 발생한 경험이 있을것이다.

 

간단한 css추가로 숫자롤러를 없애보자.

 

input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
    /* display: none; <- Crashes Chrome on hover */
    -webkit-appearance: none;
    margin: 0; /* <-- Apparently some margin are still there even though it's hidden */
}

input[type=number] {
    -moz-appearance:textfield; /* Firefox */
}

 

 

728x90
반응형
728x90

해당 포스팅은 Gsuite에 기반한 포스팅임을 미리 말씀드립니다.

 

광고x

 

 

오랜만에 정성가득 포스팅을 해보고자 합니다.

 

내 도메인으로 이메일을 등록하는 것부터

 

여러가지 상황으로 인해 내 도메인의 네임서버(NS, name server)를 변경했을때 이메일이 먹통이 됐다면..?! 에 대한 해결방안까지.

 

 

 

ㄱ. 도메인 구매

 

국내에 유명한 호스팅업체가 몇 군데 있습니다.

예를들어 Cafe24, 가비아, 후이즈, 호스팅케이알 등

 

개인적으로 가비아나를 주로 이용하고 호스팅케이알이 저렴하다고 생각해 종종 이용합니다.

어디든 상관없으니 들어가서 마음에 드는 도메인을 검색해 구매하도록 합니다.

 

 

 

 

ㄴ. Gsuite 시작

 

구매하였다면, 이제 Gsuite를 시작할 차례입니다.

workspace.google.co.kr/intl/ko/

 

위의 링크로 들어가면 우측상단에 "무료 평가판 시작" 이라는 버튼이 있습니다.

해당 버튼을 눌러 봅니다.

그러면 간단한 설정들이 몇가지 나오는데요.

차근차근 진행해주면 됩니다. (직원수, 국가, 연락처 등이니 부담없이 편하게 하시면 됩니다.)

 

자, 기본정보를 입력하고나면 도메인을 소유하고있냐고 묻는데요.

우리는 구매한 도메인이 있으니, 도메인을 소유하고 있습니다를 클릭합니다.

 

그리고 구매한 도메인을 입력해줍니다.
도메인이 tistory.com(www.tistory.com)이라면 tistory.com을 입력해주면 되겠죠?

 
자, 여기부터가 조금 어려울수있는데요 .

무슨무슨 설정을 하라는 가이드가 나옵니다. 방황하지 않도록 합니다.

 

 

 

 

ㄷ. 메일서버 설정


도메인을 구매했던 사이트로 돌아가

마이서비스(마이페이지) > 도메인 관리툴
로 이동합니다.

잘 살펴보면 어드 사이트던간에 도메인 관리툴에 "DNS 설정" 혹은 "DNS 레코드 설정"등의 버튼이 있습니다.
해당 버튼을 클릭해 관리 화면으로 이동해봅니다.

설정된게 아무것도 없을텐대요. 여기서 구글에서 가이드해준대로 설정을 하나씩 진행해줄 예정입니다.
1. "추가"버튼을 클릭
2. primary에 구글에서 지정해준 1,5,10, 15 등을 입력
3. value/description에 구글에서 지정해준 ASPMX.L.GOOGLE.COM. 등의 값을 입력
4. 총 5-6개정도가 가이드 됩니다. 꼼꼼하게 입력했는지 다시한번 확인합니다.
5. TTL (수명)은 기본값/공백으로 두어도 무방합니다.
6. MX 확인 레코드(mx-verification.google.com으로 끝남 <- 이것도 빼먹지 않았는지 한번 더 체크합니다.

 

반드시 설정을 저장하고 화면에서 나오도록 합니다.

 


ㄹ. Gsuite에서 연결 확인

 

여기까지 했다면 설정은 거의 다 끝났습니다.
다시 Gsuite로 돌아가서 다음/확인/완료 버튼을 눌러주면 Guiste연결을 체크합니다.
다만, 위의 설정을 저장하고나면 처리에 어느정도 시간이 소요될 수 있어 연결오류가 뜰수도 있습니다.

당황하지 말고 한번더 연결확인을 해주면됩니다.

설정은 모두 끝났고

test email보내기 기능을 통해 이메일을 발송, 해당 계정에서 수신해보면 됩니다.

 

끝!




ㅁ. 기타 이슈 해결 - 네임서버를 변경했더니 이메일이 수신되지 않아요. 

설정을 모두 마치고 잘 이용하다가
어느날 도메인 만료 혹은 호스팅 이전 등의 상황으로 인해 네임서버를 변경해야 될일이 생길 수 있습니다.
사람일은 모르는법이니까요.

그러면, 이메일이 정상적으로 동작하지 않게 되는데요.
이는, ㄹ 단계에서 연결설정 했을때와 내 도메인의 상태가 달라졌으니 사실 당연한 결과입니다.

너무 걱정하지 않아도됩니다. 걱정은 제가 미리했으니까요.

네임서버를 변경해서 도메인이 바라보게한 호스팅 서버가 있죠?
그곳에서 'ㄷ' 단계에 해당하는 설정을 해주면됩니다.


그리고, 마지막으로...
Gsuite 어드민 > 도메인 관리 > 설정
에 들어가보면 이메일 활성화 하라는 빨강색 글씨가 있을겁니다.

도움말 > support.google.com/a/answer/7009324?hl=ko&ref_topic=6302293#zippy=%2C%EB%8B%A8%EA%B3%84-%EC%83%88-%EB%8F%84%EB%A9%94%EC%9D%B8-%EC%B6%94%EA%B0%80-%EB%B0%8F-%EC%9D%B4%EB%A9%94%EC%9D%BC-%EC%84%A4%EC%A0%95%ED%95%98%EA%B8%B0

그 버튼을 꾹 눌러주면 구글에서 다시 체크를 진행하고 정상적으로 설정되어있을경우 다시 메일시스템을 복구해줍니다.

 

긴  글 읽어주셔서 감사합니다.

728x90
반응형