728x90
반응형

먼저 등록하고자 하는 데이터들을 text에 담아 ajax로 보내고, 백엔드에서 쿼리문으로 DB에 내용이 추가되도록 한다.

 

1. 클라이언트는 form으로 데이터들을 submit할 수 있게 만들어준다.

<div id="car-form-div" class="panel-body">
	<form id="car-form" action="" method="post" class="form-horizontal" data-parsley-validate="true" name="car-form" onsubmit="carJoin();">
		<div class="form-group row m-b-15">
			<label class="col-md-4 col-sm-4 col-form-label" for="CN">{{__('car_number')}} <span class="text-danger">*</span> :</label>
			<div class="col-md-8 col-sm-8">
				<input class="form-control" type="String" id="CN" name="CN" placeholder="{{__('car_number_msg')}}" data-parsley-required="true" data-parsley-error-message="{{__('required_detail')}}" data-parsley-trim-value="true" />
			</div>
		</div>
		<div class="form-group row m-b-15">
			<label class="col-md-4 col-sm-4 col-form-label" for="CN">{{__('car_customer_phone')}} :</label>
			<div class="col-md-8 col-sm-8">
				<input class="form-control" type="String" id="CPN" name="CPN" placeholder="{{__('car_customer_phone')}}" data-parsley-type="digits" data-parsley-type-message="{{__('register_digits_error')}}" data-parsley-trim-value="true" />
			</div>
		</div>
		<div class="form-group row m-b-0">
			<label class="col-md-4 col-sm-4 col-form-label">&nbsp;</label>
			<div class="col-md-8 col-sm-8">
				<button type="submit" class="btn btn-primary width-80">{{__('registration')}}</button>
				<button type="reset" class="btn btn-primary width-80">{{__('reset')}}</button>
			</div>
		</div>
		<!--현재 시간 변수-->
		<input type="hidden" class="form-control" name = "Ctime" id = "Ctime" />
	</form>
</div>

 

2. script 쪽에서 데이터들을 검증한 뒤에 ajaxJoin() 함수를 실행해준다.

// 차량 등록 ajax
	function carJoin() {
		var formParsley  = $('#car-form').parsley();
		if(formParsley.isValid() == true) {
			ajaxJoin('/car/car_join', i18nconvert, { CN: document.getElementsByName("CN")[0].value, CPN: document.getElementsByName("CPN")[0].value });
		}
		event.preventDefault();
	}

 

3. ajaxJoin 함수에서 백엔드로 데이터를 전송하고, 받아올 데이터에 따라 실행 될 내용들을 정의해준다.

// 공통 등록(차량, 장비)
function ajaxJoin(url, i18nconvert, data) {
	console.log(data)
    $.ajax({
        type: 'POST',
        url: url,
        dataType: 'json',
        data: {
            data : JSON.stringify(data)
        }
    }).done(function(data) {
        if(data.type == 'device') {
            if(data.result == 'success') {
				alert(i18nconvert('device_register_success'));
				location = '/device_list';
			}
			else if(data.result == 'exist') {
				alert(i18nconvert('device_duplicated'));
			}
			else if(data.result == 'type') {
				alert(i18nconvert('device_mac_wrong'));
			}
			else {
				alert(i18nconvert('device_register_fail'));
			}
        }
		else if(data.type == 'car') {
			if(data.result == 'success') {
				alert(i18nconvert('car_register_success'));
				location = '/car_list';
			}
			else if(data.result == 'exist') {
				alert(i18nconvert('car_exist_error'));
			}
			else if(data.result == 'type') {
				alert(i18nconvert('car_type_error'));
			}
			else if(data.result == 'length') {
				alert(i18nconvert('car_length_error'));
			}
			else if(data.result == 'excelType') {
				alert(i18nconvert('car_exceltype_error'));
			}
			else if(data.result == 'excelLength') {
				alert(i18nconvert('car_excellength_error'));
			}
			else {
				alert(i18nconvert('car_register_fail'));
			}
		}
    });
}

 

728x90
반응형
728x90
반응형

간단하게 큰 그림을 얘기하자면, 먼저 처음 데이터는 백엔드에서 modelquery를 이용해 해당 리스트에 필요한 모든 정보를 불러온다. 등록 버튼을 만들어서 팝업창을 띄어도 되지만, 만들 때 등록 페이지는 따로 있는게 나을거 같다는 의견을 토대로 만들었기에 등록 페이지는 따로 구현을 했다.

 

테이블에서 중요한것은 등록 > 리스트 > 수정 > 삭제 > 페이지네이션 > 검색 > 정렬 > 페이지갯수 > 엑셀 다운

이 순인거 같다.( 주관적인 의견이며 개인적으로 개발할 때 저 순서대로 하는것이 제일 편했고, 엇갈리는것이 없었다. )

 

1. CRUD 작업은 node.js 백엔드를 타서 실행되도록 하였다.

 

2. 페이지네이션은 Object를 사용하였으며, 클라이언트쪽에서 가능하도록 하였다.

 

3. 검색과 정렬은 먼저 어떻게 검색할 지, 정렬할 지 옵션을 변수로 만들어 백엔드에 넘겨주고 원하는 데이터를 받아와

   Ajax로 부분만 바뀌도록 하였다.

 

4. 페이지 갯수는 클라이언트쪽에서 원하는 갯수만큼 보여줄 수 있도록 설정하였다.

 

5. 엑셀 다운은 클라이언트에서 내가 보고있는 테이블들만 엑셀로 담아주도록 하였다.

 

그림으로 나타내면 다음과 같다.

먼저 전체 리스트를 받아오거나, search또는 sort를 할 경우

HTML script에 object를 선언해준 후

var pagingObject = new Object({name : "Device", url : "/ajax/device_list", CNU : "{{company.CNU}}", array : [], sort : "CA", page : 0, postNum : 10, pageNum : 5, startpage : 0, endpage : 0, search: "", searchtext : "", searchdate : ""});

백엔드에 옵션에 대한 정보를 주고, 백엔드에서 쿼리문을 이용해 조회하며, 클라이언트의 object 내용들을 바꿔준다.

 

 

다음은 클라이언트 쪽에서 페이지네이션을 하거나 페이지의 갯수를 조정해줄 경우

ajax로 가져온 데이터들을 조리있게 바꿔서 리스트의 내용들을 교체해준다.

728x90
반응형
728x90
반응형

JQuery를 1년간 개발한 결과 결국 제일 중요한 것은 Ajax와 Object인 것을 깨달았다. 이는 React에선 Axios, State(리액트 훅)으로 이어지며, JQuery를 나름 심도있게 개발하니 React도 이해하기가 쉬웠다.

기억하자 JQuery는 Object와 Ajax가 제일 중요하고 쓸모있다!

 

화면 구성

구성한 테이블의 화면이다. 주요 기능들 위주로 설명하겠다.

 

728x90
반응형
728x90
반응형

1. 먼저 화면 구성을 해준다. 버튼을 눌렀을 경우 onclick으로 함수가 실행되도록 한다.(로그아웃도 동일)

 

 

2. HTML script - get메소드를 쓰기 때문에 location 을 바꿔주어서 백엔드에서 로직이 실행되도록 한다.

// 회원탈퇴 기능
function withdrawal(i18nconvert) {
	var answer;
	//페이지를 이동하기 전에 confirm()을 사용해 다시 한번 확인한다.
	//확인을 선택하면 answer에  true, 취소를 선택하면 false 값이 들어간다.
	answer = confirm(i18nconvert("layout_withdrawal_confirm"));
	//확인을 선택한 경우 자바스크립트를 호출할 때 같이 넘어온 url이라는 변수에 들어있는 주소로 페이지 이동
	if(answer == true){
		location = '/auth/withdrawal';
	}
	else {
		return false;
	}
}

// 로그아웃 기능
function logout(i18nconvert) {
	var answer;
	//페이지를 이동하기 전에 confirm()을 사용해 다시 한번 확인한다.
	//확인을 선택하면 answer에  true, 취소를 선택하면 false 값이 들어간다.
	answer = confirm(i18nconvert("layout_signout_confirm"));
	//확인을 선택한 경우 자바스크립트를 호출할 때 같이 넘어온 url이라는 변수에 들어있는 주소로 페이지 이동
	if(answer == true){
		location = '/auth/logout';
	}
	else {
		return false;
	}
}

 

 

3. 백엔드쪽에서 로그아웃은 쿠키가 삭제되도록, 회원탈퇴는 DB에서 데이터가 삭제되도록 한다.

//logout시 Browser Cookie 삭제
router.get("/logout", async function( req, res, next){
  try {
    await res.cookie("token", req.cookies,{expiresIn:0});
    res.redirect("/");
  } catch(err){
    console.error(err);
    next(err);
  }
});

//withdrawal시 Browser Cookie 삭제 하고 소독이력을 제외한 company에 관련된 내용들 삭제
router.get("/withdrawal", isNotLoggedIn, async function(req, res, next){
  const CID = req.decoded.CID;
  const CNU = req.decoded.CNU;
  
  try {
    await modelQuery(QUERY.Remove,COLLECTION_NAME.Company,{"_id": CID},{});
    await modelQuery(QUERY.Remove,COLLECTION_NAME.Car,{"CNU": CNU},{});
    await modelQuery(QUERY.Remove,COLLECTION_NAME.Device,{"CNU": CNU},{});
    await modelQuery(QUERY.Remove,COLLECTION_NAME.Worker,{"CNU": CNU},{});

    await res.cookie("token", req.cookies, { expiresIn : 0 });
    
    res.redirect("/");

  } catch(err){
    console.error(err);
    next(err);
  }
});
728x90
반응형
728x90
반응형

1. 먼저 nunjucks를 설치해준다.

npm install nunjucks

 

2. express와 nunjucks를 연결해준다.

// app.js
const express = require('express');
const app = express();

app.set('port', process.env.PORT || 3000);
app.set('view engine', 'html')
nunjucks.configure('views', {
  express: app, 
  watch: true, 
});

const indexRouter = require('./routes/index');
app.use('/', indexRouter);

 

3. 라우터에 사용할 변수를 페이지에 렌더링해준다.

const express = require('express');
const router = express.Router();

router.get('/', (req, res) => {
  res.locals.title = 'Express'
  res.render('index')
});

module.exports = router;

 

4. 최상위 html 파일에 넌적스 변수를 선언해준다.

// layout.html
<!DOCTYPE html>
<html>
  <head>
    <title>{{title}}</title>
    <link rel="stylesheet" href="/style.css" />
  </head>
  <body>
    {% block content %}
    {% endblock %}
  </body>
</html>

// index.html
{% extends 'layout.html' %}

{% block content %}
<h1>{{title}}</h1>
<p>Welcome to {{title}}</p>
{% endblock %}

 

 

이렇게 하면 백엔드에서 넘겨준 변수를 html에서 쓸 수 있다. {{ }} 이걸로 변수를 감싸주면 끝!

{% %} 이런 형식으로 변수를 이용한 반복문, 또다른 변수선언 등을 할 수도 있다.

728x90
반응형
728x90
반응형

※ 지점, 본사는 무시하셔도 됩니다.

 

먼저 사업자등록번호(아이디)를 입력한 후 존재하면 해당 정보에 등록된 이메일 주소가 일부 가려진 채로

나오게 되고 (혹시나 이메일 주소를 잊었을 경우), 이메일 주소를 입력하고 버튼을 누르면 전송이 되게끔 하였다.

(이메일 보내기는 회원가입 글을 확인 부탁드립니다) 이후에 이메일을 보내는 부분은 회원가입을 했을 경우랑 같고, 

바뀐 임의의 비밀번호를 이메일 주소로 보내게끔 하였으며, 사이트 내에 프로필 수정 화면을 통해 비밀번호를

변경할 수 있도록 했다.

728x90
반응형
728x90
반응형

1. 미들웨어는 이런식으로 사용이 된다.

// 로그인
router.get('/login', isLoggedIn, (req, res) => {
  res.render('login');
});

 - 라우터가 실행될 때, 그전에 먼저 실행되서 어떻게 할건지를 설정해준다. ( 예를들어 로그인이 안되어있을 경우 이런 페이지로 가겠다. ) 사실 라우터마다 설정들을 다 해줄 순 있지만, 굳이 반복되는 코드를 여러번 쓰는것보단 미들웨어로 한번에 처리하면 사용하기에도 편리하다.

 

먼저, middleware.js라는 파일을 만들고 exports 되는 함수들을 정의한 다음에

const { isLoggedIn, isNotLoggedIn, DataSet, agentDevide } = require('./middleware');

이런 식으로 미들웨어 사용이 필요한 라우터 마다  require로 정의를 해주었다.

 

 

 

2. 나는 이런식으로 로그인이 될 경우에 메인화면으로 오게 만들었고,

exports.isLoggedIn = (req, res, next) => {
  try {
    req.decoded = jwt.verify(req.cookies.token, secretObj.secret);
    res.redirect('/main');
  } catch(err) {
    next();//Token 만료시 다시 로그인 페이지로 넘어가게 설정
  }
};

 

3. 모든 페이지마다 로그인이 안되어있을 경우에 루트 페이지로 가도록 설정했다.

exports.isNotLoggedIn = (req, res, next) => {
  try {
    req.decoded = jwt.verify(req.cookies.token, secretObj.secret);
    next();   
  } catch(err) {
    res.redirect('/') ;//Token 만료시 다시 로그인 페이지로 넘어가게 설정
  }
};
728x90
반응형
728x90
반응형

화면 구성

※ 본사 지점은 무시하셔도 됩니다.

 

1. html 코드

 기본적으로 사업자번호(아이디)와 비밀번호를 입력하도록 설계하였다.

<form action="" method="post" id="login-form2" class="margin-bottom-0" onsubmit="login('login-form2','CNU2','ANA2','PW2');">
<!--사업자번호-->
  <div class="form-group m-b-20">
  <input id="CNU2" name = "CNU2" type="text" class="form-control form-control-lg inverse-mode" placeholder="{{__('business_number')}}" required />
  </div>
<!--비밀번호-->
  <div class="form-group m-b-20">
  <input id="PW2" name = 'PW2' type="password" class="form-control form-control-lg inverse-mode" placeholder="{{__('pw')}}" required />
  </div>
<!--버튼-->
  <div class="login-buttons">
  <button type="submit" class="btn btn-primary btn-block btn-lg">{{__('login')}}</button> 
  <li class="form-control-lg inverse-mode"><a href="/register" >{{__('signup')}}</a>   /  <a href="/find" > {{__('findpw')}}</a></li>
  </div>
</form>

 

2. script부분에서 input을 parsley로 형식을 검사한 후에 loginAjax를 실행하도록 하였다.

function login(form, companyNumber, agentInfo, password) {
    var CNU = document.getElementsByName(companyNumber)[0].value;
    var ANU = document.getElementsByName(agentInfo)[0].value.split("/")[0];
    var ANA = document.getElementsByName(agentInfo)[0].value.split("/")[1];
    var PW = document.getElementsByName(password)[0].value;
    var validateCNU = $('#'+form).parsley();

    if(validateCNU.isValid() == true) {
    	loginAjax(CNU,ANU,ANA,PW);
    }
    event.preventDefault();
  }

 

3. loginAjax() 함수로 백엔드에 데이터를 보낸 후 성공할 경우 어떻게 할건지를 정의한다.

// 로그인 기능
function loginAjax(companyNumber, agentNumber, agentName, password) {
	$.ajax({
		type: 'POST',
		url: 'auth/login',
		dataType: 'json',
		data: {
			CNU: companyNumber,
			ANU: agentNumber,
			ANA: agentName,
			PW: password
		}
	}).done(function(data) {
		if(data.result == 'success') {
			location = '/main';
		}
		else if(data.result == 'fail') {
			alert(i18nconvert('login_error'));
		}
		else {
			alert(i18nconvert('login_fail'));
		}
	});
}

 

3. 백엔드쪽에서 올바른 데이터가 들어왔을 경우 로그인 정보를 쿠키에 담아준다.

//login 진행 할경우 토큰 만들어서 cookie에 넣음
router.post("/login", async(req, res, next) => {
  const {CNU, ANU, ANA, PW} = req.body;
  try {
    const company = await modelQuery(QUERY.Findone,COLLECTION_NAME.Company,{ "CNU" : CNU+ANU, "ANA" : ANA, "ANU" : ANU },{});// CNU에 맞는 데이터 찾아오기
    if(company) {
      //bcrypt 암호화된 PW와 입력 PW 비교
      if(bcrypt.compareSync(PW, company.PW) ){
        const token = jwt.sign({ CNU : company.CNU, ANU : company.ANU, ANA : company.ANA, CNA : company.CNA, CID : company._id, AH : company.AH },// 토큰의 내용(payload)
          secretObj.secret,   // 비밀 키
          { expiresIn: '1440m' });  // 유효 시간은 1440분 하루 설정
        res.cookie("token", token); // 쿠키에 token 등록
        
        return res.send({ result : 'success' });
      }
      else{
        return res.send({ result : "fail" });
      }
    }
    else {
      return res.send({ result : "fail" });
    }
  } catch(err){
    res.send({ result : "fail" });
    console.error(err);
    next(err);
  }
});

 

 

페이지마다 미들웨어를 설정해서 로그인된 정보가 쿠키에 없을 경우에 로그인 화면이나 원하는 화면으로 돌아가도록

설정을 해주면 좋다!

728x90
반응형
728x90
반응형

전 글에서 클라이언트 쪽 데이터 전송까지 다루었다.

이번 글에서는 백엔드쪽을 다루어보겠다.

 

1. 전체 코드( email.js )

//Express
const express = require('express');
const router = express.Router();
//Module
const nodemailer = require('nodemailer');
const bcrypt = require('bcrypt');
//Schemas
const {modelQuery} = require('../schemas/query')
const {COLLECTION_NAME, QUERY} = require('../const/consts');

// -- Start Code -- //

// nodemailer 설정
const smtpTransport = nodemailer.createTransport({
  service: "Gmail",
  auth: {
      user: "사용자 이메일주소(구글)",
      pass: process.env.gmail
  },
  tls: {
      rejectUnauthorized: false
  }
});

// 이메일 전송
router.post('/send', async (req, res, next) => {
  const reademailaddress = req.body.EA;
  
  const exEA = await modelQuery(QUERY.Findone,COLLECTION_NAME.Company,{ "EA" : reademailaddress },{});
  try {
    // 이메일이 중복됐을 때
    if(exEA) {
      return res.send({ result : 'exist' });
    }
    else {
      let authNum = Math.random().toString().substr(2,6);
      const hashAuth = await bcrypt.hash(authNum, 12);
      console.log(authNum);
      res.cookie('hashAuth', hashAuth,{
        maxAge: 300000
      });
      const mailOptions = {
        from: "mk.manager2020@gmail.com",
        to: reademailaddress,
        subject: "OASIS 인증번호 관련 메일 입니다.",
        text: "인증번호는 " + authNum + " 입니다.",
        html: "<div style='font-family: 'Apple SD Gothic Neo', 'sans-serif' !important; width: 540px; height: 600px; border-top: 4px solid #348fe2; margin: 100px auto; padding: 30px 0; box-sizing: border-box;'>"+
              "<h1 style='margin: 0; padding: 0 5px; font-size: 28px; font-weight: 400;'>"+
              "<span style='font-size: 15px; margin: 0 0 10px 3px;'>MK_</span><br />"+
              "<span style='color: #348fe2;'>인증번호</span> 안내입니다."+
              "</h1>"+
              "<p style='font-size: 16px; line-height: 26px; margin-top: 50px; padding: 0 5px;'>"+
              "안녕하세요.<br />"+
              "요청하신 인증번호가 생성되었습니다.<br />"+
              "감사합니다."+
              "</p>"+
              
              "<p style='font-size: 16px; margin: 40px 5px 20px; line-height: 28px;'>"+
              "인증번호: <br />"+
              "<span style='font-size: 24px;'>"+authNum+"</span>"+
              "</p>"+
              "<div style='border-top: 1px solid #DDD; padding: 5px;'>"+
              "</div>"+
              "</div>",
      };
      await smtpTransport.sendMail(mailOptions, (err, res) => {
        if(err) {
          console.log(err);
        } else{
          console.log('success');
        }
        smtpTransport.close();
      });
      
      return res.send({ result : 'send' });
    }
  } catch (err) {
    res.send({ result : 'fail' });
    console.error(err);
    next(err);
  }
});

// 이메일 인증
router.post('/cert', async (req, res, next) => {
  const CEA = req.body.CEA;
  const hashAuth = req.cookies.hashAuth;
  
  try {
    if(bcrypt.compareSync(CEA, hashAuth)) {
      res.send({ result : 'success' });
    }
    else {
      res.send({ result : 'fail' });
    }
  } catch(err) {
    res.send({ result : 'fail' });
    console.error(err);
    next(err);
  }
});

module.exports = router;

 

2. 먼저 nodemailer를 사용하기 전 설정을 해준다.

// nodemailer 설정
const smtpTransport = nodemailer.createTransport({
  service: "Gmail",
  auth: {
      user: "사용자 이메일주소(구글)",
      pass: process.env.gmail
  },
  tls: {
      rejectUnauthorized: false
  }
});

 

3. 그다음 ajax로 보낸 데이터를 받을 라우터를 설정해준다. 먼저 mongoose 쿼리로 이미 가입된 이메일이 있는지를 확인하고, 있을 경우에 랜덤으로 인증번호를 생성해 준 뒤 쿠키에 bcrypt로 암호화된 인증번호를 담는식으로 설정하였다.

이메일 전송이 성공하면 클라이언트쪽에서 인증번호 입력칸, 인증버튼이 생성된다.

 

 

 

이메일을 인증하는 방법은 너무나 다양하다. 각자 본인의 입맛에 맞게 설계하면 된다.

 

 

 

구글로 이메일을 보낼 경우에 구글 계정에서 설정해야 될 것들이 있다.

자세한 내용은 아래 주소 참고바란다.

https://ant-programmer.tistory.com/70

728x90
반응형
728x90
반응형

화면 구성

 

nodemailer 라는 좋은 npm모듈이 있다. 해당 서비스는 클라이언트에서 백엔드(node.js)에 이메일을 보낼거란 신호를 주고, 백엔드 쪽에서 여러 설정( 어떤 메일을 어떤 주소로 보낼건지 등 )을 해놓은 상태에서 메일을 전송하게 되고,

자신이 보낸 메일 인증번호와 클라이언트에서 입력한 인증번호가 같으면 인증이 완료되는 시스템이다.

 

1. 클라이언트 html쪽에선 먼저 이메일 주소 입력창, 인증번호 입력창, 보내기버튼, 인증버튼이 존재한다.

    class 에 d-none 옵션을 추가해서 이메일을 보내지 않은 상태에선 인증번호 입력칸, 인증 버튼이 없도록 했다.

<!--이메일 인증-->
<label class="control-label">{{__('email')}} {{__('auth')}}<span class="text-danger"> *</span> </label>
  <div class="form-group m-b-20">
    <input id="EA" name="EA" type="email" class="form-control form-control-lg inverse-mode" value ="{{email}}" placeholder="{{__('email')}}" data-parsley-error-message=null required >
    <input id="CEA" name="CEA" type="text" class="form-control form-control-lg inverse-model mt-3 d-none" placeholder="{{__('authnum')}}" data-parsley-error-message="{{__('required_detail')}}" data-parsley-errors-container="#err-msg2" required >
  <div class="d-flex justify-content-between align-items-center mt-2">
  <div id="err-msg2" class="text-realred"></div>
    <input type="button" id="sendBtn" class="btn btn-primary btn-block btn-lg ml-auto custombtn" value="{{__('send')}}" onclick="emailSend('EA')">
    <input type="button" id="cerBtn" class="btn btn-primary btn-block btn-lg mt-0 ml-auto custombtn d-none" value="{{__('auth')}}" onclick="emailCer('CEA')">
    <input type="hidden" id="hideCK" name="hideCK" value="">
  </div>
</div>

 

2. 클라이언트 javascript 데이터 검증부분에선 먼저 버튼에 onclick에 붙어있는 함수들을 선언한다. parsley를 사용해 input에 제대로 된 데이터가 들어갔는지 먼저 검증하고 맞으면 아래 함수를 실행하도록 되어있다. 

	// 이메일 전송 기능
	function emailSend(email) {
		var EA = document.getElementsByName(email)[0].value;
		var validateEA = $('#'+email).parsley();
		
		if(validateEA.isValid() == true) {
			emailSendAjax(EA);
		}
		else {
			return alert("{{__('register_email_valid_msg')}}");
		}
	}
	
	// 이메일 인증 기능
	function emailCer(cerNum) {
		var CEA = document.getElementsByName(cerNum)[0].value;
		var validateCEA = $('#'+cerNum).parsley();
		
		if(validateCEA.isValid() == true) {
			emailCerAjax(CEA);
		}
		else {
			alert("{{__('register_auth_enter')}}");
		}
	}

 

3. 클라이언트 javascript 함수 실행부분에선 검증된 데이터가 들어왔을 때, ajax로 백엔드에 데이터를 전송하도록 하였다.

// 이메일 전송 기능
function emailSendAjax(email) {
    $.ajax({
		type: 'POST',
		url: '/email/send',
		dataType: 'json',
		data: {
			EA: email
		}
	}).done(function(data) {
		if (data.result == 'exist') {
			alert(i18nconvert('register_already_msg'));
		}
		else if (data.result == 'send') {
			alert(i18nconvert('register_auth_com_msg'));
			document.getElementsByName('EA')[0].readOnly = true;
			document.getElementById('CEA').classList.remove('d-none');
			document.getElementById('cerBtn').classList.remove('d-none');
			document.getElementById('sendBtn').classList.add('d-none');
			
			clearTimeout(timer);
			stopWatch(300);
		}
		else {
			alert(i18nconvert('register_email_send_fail'));
		}
	});
}

// 이메일 인증 기능
function emailCerAjax(cerNum) {
    $.ajax({
		type: 'POST',
		url: '/email/cert',
		dataType: 'json',
		data: {
			CEA: cerNum
		}
	}).done(function(data) {
		if (data.result == 'success') {
			alert(i18nconvert('register_auth_success'));
			clearTimeout(timer);
			document.getElementsByName('CEA')[0].readOnly = true;
			document.getElementById('err-msg2').innerHTML = i18nconvert('register_auth_success');
			document.getElementsByName('hideCK')[0].value = 'true';
		}
		else {
			alert(i18nconvert('register_auth_fail'));
			document.getElementsByName('CEA')[0].value = null;
			document.getElementsByName('hideCK')[0].value = null;
		}
	});
}

 

백엔드 쪽은 다음 글에서 설명하겠다.

 

@ 인증번호 타이머 기능

   setInterval 함수를 사용해 1초에 한번씩 바꿔주었다.

function stopWatch(TimeSet) {
	timer = setInterval(function(){
		sec = (TimeSet)%60;
		document.getElementById('err-msg2').innerHTML =i18nconvert('register_auth_time') + '&nbsp;' + parseInt(TimeSet/60) + i18nconvert('register_auth_minute') + sec + i18nconvert('register_auth_second') + "." + "<br><a href='javascript:;' id='resend' class='text-white' onclick=emailSend('EA')><u>"+i18nconvert('register_auth_resend')+"</u></a>";
		TimeSet--;
		
		if(TimeSet < 0){
			clearTimeout(timer);
			alert(i18nconvert('register_auth_timeout'));
			document.getElementsByName('EA')[0].value = null;
			document.getElementsByName('CEA')[0].value = null;
			document.getElementsByName('EA')[0].readOnly = false;
			document.getElementsByName('CEA')[0].readOnly = false;
			document.getElementsByName('hideCK')[0].value = null;
			document.getElementsByName('hideCNU')[0].value = null;
			document.getElementById('CEA').classList.add('d-none');
			document.getElementById('cerBtn').classList.add('d-none');
			document.getElementById('sendBtn').classList.remove('d-none');
			document.getElementById('err-msg2').innerHTML = i18nconvert('register_reauth_msg');
		}
    }, 1000);
}
728x90
반응형

+ Recent posts