JSP day 6

유요한·2022년 11월 23일
0

JSP

목록 보기
8/14
post-thumbnail

프로그램을 실행할 때

   프로그램에서 실행하지 말고 주소를 쳐서 실행해야 한다.
   그래야 뒤에 뭐가 안 붙는다.
   예시 : http://localhost:9090/day06/

  • 세션(session)의 개요
    쿠키가 웹 브라우저에 사용자의 상태를 유지하기 위한 정보를 저장했다면, 세션(session)은 웹 서버 쪽의 웹 컨테이너에 상태를 유지하기 위한 정보를 저장한다.
    세션은 사용자의 정보를 유지하기 위해 javax.servlet.http 패키지의 HttpSession 인터페이스를 구현해서 사용한다. 쿠키는 사용자의 상태 유지를 위한 정보를 웹 브라우저에 저장해서 웹 서버가 쿠키 정보를 읽어서 사용한다.
    이것은 웹 브라우저에 저장된 쿠키는 웹 서버에서 열어볼 수 있다는 점에서 보안상 문제가 발생할 수 있다. 따라서 사용자의 정보를 유지하기 위해서는 쿠키를 사용하는 것보다 세션을 사용한 웹 브라우저와 웹 서버의 상태 유지가 훨씬 안정적이고, 보안상의 문제도 해결할 수 있다.
    세션은 웹 브라우저 당 1개씩 생성되어 웹 컨테이너에 저장된다

    웹 서버는 각각의 웹 브라우저로부터 발생한 요청에 대해서 특별한 식별자를 부여한다. 이후에 이 식별자를 웹 브라우저에서 발생한 요청들과 비교해서 같은 식별인지를 구별하게 된다. 이 특별한 식별자에 특정한 값을 넣을 수 있으며, 이것을 사용해서 세션을 유지하게 된다.
  • 세션(Session) 메소드 리스트
  • 세션(Session)의 속성

• index.jsp

	<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>인덱스</title>
</head>
<body>
	<a href="joinview.jsp">회원가입</a><br>
	<a href="loginview.jsp">로그인</a>
</body>
</html>

• loginview.jsp

	<%@page import="com.koreait.dto.UserDTO"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>로그인</title>
</head>
<style>
	body{
		background-color:rgb(245,246,247);
	}
	#wrap{
		width:600px;
		margin:0 auto;
	}
	#wrap > tr, #wrap > td{
		padding:10px;
	}
	#wrap > tr{
		width:200px;
	}
	#wrap > td{
		width:350px;
	}
	input[type=text], input[type=password]{
		padding:10px;
		width:200px;
		margin-left:20px;
		border:1px solid #ccc;
		outline:none;
	}
	input[type=submit]{
		margin-top:30px;
		padding:10px 20px;
		width:100px;
		border:none;
		background-color:rgb(0,200,80);
		border-radius:5px;
		color:#fff;
		font-weight:bold;
		font-size:18px;
	}
</style>
<body>
	<%
		// session		 : 세션(session)은 웹 서버 쪽의 웹 컨테이너에 상태를 유지하기 위한 정보를 저장한다.
		// .getAttribute : 선택한 요소(element)의 특정 속성의 값을 가져옵니다.
		UserDTO joinUser = (UserDTO)session.getAttribute("joinUser");
		String userid = null;
		if(joinUser != null){
			userid = joinUser.getUserid();
			session.removeAttribute("joinUser");
		}
		String check = request.getParameter("l");
		if(check != null && check.equals("f")){
	%>
			<script>alert("로그인 실패!");</script>
	<%
		}
	%>
	<div id="wrap">
		<form name="loginForm" action="login_db.jsp" method="post" onsubmit="return sendit();">
			<table>
				<tr>
					<th>아이디</th>
					<td>
						<input type="text" name="userid" placeholder="아이디를 입력하세요"
						value="<%=userid==null?"":userid%>">
					</td>
				</tr>
				<tr>
					<th>비밀번호</th>
					<td>
						<input type="password" name="userpw" placeholder="비밀번호를 입력하세요">
					</td>
				</tr>
				<tr>
					<th colspan="2"><input type="submit" value="로그인"></th>
				</tr>
			</table>
		</form>
	</div>
</body>
<script src="./user.js"></script>
</html>

• login_db.jsp

	<%@page import="com.koreait.dao.UserDAO"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
	UserDAO udao = new UserDAO();
	
	String userid = request.getParameter("userid");
	String userpw = request.getParameter("userpw");
	
	if(udao.login(userid,userpw)){
		session.setAttribute("loginUser", userid);
		response.sendRedirect("mainview.jsp");
	}
	else{
		response.sendRedirect("loginview.jsp?l=f");
	}
%>

• UserDAO.java

	package com.koreait.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;

import com.koreait.dto.UserDTO;

public class UserDAO {
	Context context;
	DataSource ds;
	
	Connection conn;
	PreparedStatement ps;
	ResultSet rs;
	
	public boolean join(UserDTO newUser) {
		int result = 0;
		try {
			// context : 설정하면서 name을 적었는데 name을 찾아올 객체
			context = new InitialContext(null);
			// lookup이 항상 DataSource type만 return하는게 아니다.
			// 다른 type을 만들 수 있기 때문인데 그렇다보니까 return할 때
			// object되어 있다. 즉, 업캐스팅된 객체를 돌려주기 때문에 다운캐스팅을 해줘야 한다.
			ds = (DataSource)context.lookup("java:comp/env/jdbc/mysql");
			conn = ds.getConnection();
			
			String sql = "insert into test_user values(?,?,?,?,?,?,?,?,?)";
			
			ps = conn.prepareStatement(sql);
			ps.setString(1, newUser.getUserid());
			ps.setString(2, newUser.getUserpw());
			ps.setString(3, newUser.getUsername());
			ps.setString(4, newUser.getUsergender());
			ps.setString(5, newUser.getZipcode());
			ps.setString(6, newUser.getAddr());
			ps.setString(7, newUser.getAddrdetail());
			ps.setString(8, newUser.getAddretc());
			
			String[] hobbies = newUser.getUserhobby();		// [게임, 운동, 코딩]
			// hobbies[0]을 하는 이유는 무조건 하나는 체크를 하기 위해서
			String hobbyStr = hobbies[0];					// "게임"
			// length가 1개면 반복문을 한번도 안돈다.
			// 즉, 0번방 한개만 존재하면 for문을 돌지 않는것이다.
			for (int i = 1; i < hobbies.length; i++) {		// ← 1~2니까 운동, 코딩이 포함된다.
				hobbyStr += "," + hobbies[i];				// 운동, 코딩 앞에 ,을 붙여서 추가해 준다.
			}
			ps.setString(9, hobbyStr);
			result = ps.executeUpdate();
			
			
		} catch(NamingException ne) {
			System.out.println(ne);
		} catch (SQLException sqle) {
			System.out.println(sqle);
		}
		return result == 1;
		
	}
	public boolean checkId(String userid) {
		try {
			// context : 설정하면서 name을 적었는데 name을 찾아올 객체
			context = new InitialContext(null);
			// lookup이 항상 DataSource type만 return하는게 아니다.
			// 다른 type을 만들 수 있기 때문인데 그렇다보니까 return할 때
			// object되어 있다. 즉, 업캐스팅된 객체를 돌려주기 때문에 다운캐스팅을 해줘야 한다.
			ds = (DataSource)context.lookup("java:comp/env/jdbc/mysql");
			conn = ds.getConnection();
			
			String sql = "select * from test_user where userid=?";
			
			ps = conn.prepareStatement(sql);
			ps.setString(1, userid);
			
			rs = ps.executeQuery();
			
			// 없어야 true
			return !rs.next();
			
		} catch(NamingException ne) {
			System.out.println(ne);
		} catch (SQLException sqle) {
			System.out.println(sqle);
		}
		return false;
	}
	public boolean login(String userid,String userpw) {
		try {
			context = new InitialContext(null);
			ds = (DataSource)context.lookup("java:comp/env/jdbc/mysql");
			conn = ds.getConnection();
			
			String sql = "select * from test_uesr where userid=? and userpw=?";
			
			ps = conn.prepareStatement(sql);
			ps.setString(1, userid);
			
			rs= ps.executeQuery();
			
			return rs.next();
			
		} catch(NamingException ne) {
			System.out.println(ne);
		} catch(SQLException sqle) {
			System.out.println(sqle);
		}
		return false;
		 
	}
}

• UserDTO.java

	package com.koreait.dto;

public class UserDTO {
	private String  userid;
	private String userpw;
	private String username;
	private String usergender;
	private String zipcode;
	private String addr;
	private String addrdetail;
	private String addretc;
	private String[] userhobby;
	
	
	public String getUserid() {
		return userid;
	}
	public void setUserid(String userid) {
		this.userid = userid;
	}
	public String getUserpw() {
		return userpw;
	}
	public void setUserpw(String userpw) {
		this.userpw = userpw;
	}
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public String getUsergender() {
		return usergender;
	}
	public void setUsergender(String usergender) {
		this.usergender = usergender;
	}
	public String getZipcode() {
		return zipcode;
	}
	public void setZipcode(String zipcode) {
		this.zipcode = zipcode;
	}
	public String getAddr() {
		return addr;
	}
	public void setAddr(String addr) {
		this.addr = addr;
	}
	public String getAddrdetail() {
		return addrdetail;
	}
	public void setAddrdetail(String addrdetail) {
		this.addrdetail = addrdetail;
	}
	public String getAddretc() {
		return addretc;
	}
	public void setAddretc(String addretc) {
		this.addretc = addretc;
	}
	public String[] getUserhobby() {
		return userhobby;
	}
	public void setUserhobby(String[] userhobby) {
		this.userhobby = userhobby;
	}
}

• login_db.jsp

	<%@page import="com.koreait.dao.UserDAO"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
	UserDAO udao = new UserDAO();
	
	String userid = request.getParameter("userid");
	String userpw = request.getParameter("userpw");
	
	if(udao.login(userid,userpw)){
		session.setAttribute("loginUser", userid);
		response.sendRedirect("mainview.jsp");
	}
	else{
		// "loginview.jsp?login=false" : 로그인이 실패했니?
		response.sendRedirect("loginview.jsp?l=f");
	}
%>

• mainview.jsp

	<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>mainview</title>
</head>
<body>
	<%
		String loginUser = null;
		loginUser = (String)session.getAttribute("loginUser");
		if(loginUser == null){	
	%>
			<script>
				alert("로그인 후 이용하세요!");
				location.href = "loginview.jsp"
			</script>
	<%
		}
		else{
	%>
	<table>
		<tr>
			<td><%=loginUser%> 님 방문을 환영합니다~!</td>
			<td><a href="logout_session.jsp">로그아웃</a></td>
		</tr>
	</table>
	<%
		}
	%>
</body>
</html>

• logout_session.jsp

	<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
	if(session.getAttribute("loginUser") != null){
		// session.invalidate() : 로그아웃하면 정보를 남겨둘 필요가 없으니 전부 날려주는 것
		session.invalidate();
		
		response.sendRedirect("index.jsp");
	}
%>

• join_db.jsp

<%@page import="com.koreait.dao.UserDAO"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<% request.setCharacterEncoding("UTF-8"); %>
<jsp:useBean id="newUser" class="com.koreait.dto.UserDTO"/>
<jsp:setProperty property="*" name="newUser"/>
 
<%
	//String[] hobbies = newUser.getUserhobby();
	
	//for(int i=0;i<hobbies.length;i++){
	//	System.out.println(hobbies[i]);	
	//}
	UserDAO udao = new UserDAO();
	
	if(udao.join(newUser)){
		session.setAttribute("joinUser", newUser);
%>
		<script>
			alert("회원가입을 축하합니다!");
			location.href = "loginview.jsp";
		</script>
<%
	}
	else{
%>
		<script>
			alert("잠시 후에 다시 시도해주세요.")
			location.href = "joinview.jsp";
		</script>
<%
	}
%>

• joinView.jsp

	<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>회원가입</title>
<style>
	body{
		background-color:rgb(245,246,247);
	}
	input{
		box-sizing: border-box;
		cursor:pointer;
	}
	table{
		border-collapse: collapse;
	}
	th{
		text-align: left;
	}
	th::after{
		content:"";
		display:inline-block;
		box-sizing:border-box;
		width:1px;
		height:14px;
		
	}
	th,td{
		padding:5px;
	}
	td{
		padding-left:20px;
		width:400px;
	}
	input[type=text], input[type=password]{
		padding:10px 15px 10px 10px;
		border:1px solid #ccc;
		width:250px;
	}
	input:focus{
		outline:none;
		border:1px solid rgb(0,200,80);
	}
	
	td > input[type=text]+input[type=button]{
		margin-left:10px;
		padding:8px 10px;
		background-color:rgb(0,200,80);
		color:#fff;
		font-size:14px;
		font-weight:bold;
		border:none;
		border-radius:5px;
		width:80px;
	}
	.gender_area > td{
		font-size:16px;
	}
	.zipcode_area > td > input[type=text]{
		width:200px;
	}
	.zipcode_area > td > input[type=button]{
		width:130px !important;
	}
	.addr_area > td > input[type=text], .addr_area+tr > td > input[type=text], .addr_area+tr+tr > td > input[type=text]{
		width:340px;
	}
	.hobby_area > td > div{
	 	display: flex;
		width:360px;
		flex-wrap: wrap;
	}
	.hobby_area > td > div > div{
		padding:10px;
		flex:1 1 40%;
	}
	.hobby_area > td > div > div:nth-child(2n){
		border-left:1px solid #ccc;
	}
	input[type=submit]{
		margin:0 auto;
		padding:10px 10px;
		margin-left:40px;
		background-color:rgb(0,200,80);
		color:#fff;
		font-size:20px;
		font-weight:bold;
		border:none;
		border-radius:5px;
		width:400px;
	}
</style>
</head>
<body>
	<form name="joinForm" method="post" action="join_db.jsp" onsubmit="return join();">
		<table>
			<tr>
				<td id="result" colspan="2"></td>
			</tr>			
			<tr>
				<th><label for="userid">아이디</label></th>
				<td><input type="text" name="userid" id="userid"><input type="button" value="중복검사" onclick="checkId()"></td>
			</tr>
			<tr>
				<th><label for="userpw">비밀번호</label></th>
				<td><input type="password" name="userpw" id="userpw"></td>
			</tr>
			<tr>
				<th><label for="userpw_re">비밀번호 확인</label></th>
				<td><input type="password" name="userpw_re" id="userpw_re"></td>
			</tr>
			<tr>
				<th><label for="username">이름</label></th>
				<td><input type="text" name="username" id="username"></td>
			</tr>
			<tr class="gender_area">
				<th>성별</th>
				<td>
					<label>남자 <input type="radio" name="usergender" value="M" checked></label>
					<label>여자 <input type="radio" name="usergender" value="W"></label>
				</td>
			</tr>
			<tr class="zipcode_area">
				<th>우편번호</th>
				<td>
					<!-- readonly는 수정이 안되게 막는 것이다. -->
					<input readonly name="zipcode" type="text" id="sample6_postcode" placeholder="우편번호"><input type="button" onclick="sample6_execDaumPostcode()" value="우편번호 찾기">
				</td>
			</tr>
			<tr class="addr_area">
				<th>주소</th>
					<!-- readonly는 수정이 안되게 막는 것이다. -->
				<td><input readonly name="addr" type="text" id="sample6_address" placeholder="주소"></td>
			</tr>
			<tr>
				<th>상세주소</th>
				<td><input name="addrdetail" type="text" id="sample6_detailAddress" placeholder="상세주소"></td>
			</tr>
			<tr>
				<th>참고항목</th>
					<!-- readonly는 수정이 안되게 막는 것이다. -->
				<td><input readonly name="addretc" type="text" id="sample6_extraAddress" placeholder="참고항목"></td>
			</tr>
			<tr class="hobby_area">
				<th>취미</th>
				<td>
					<div>
						<div>
							<label><input type="checkbox" name="userhobby" value="게임"> 게임하기</label>
						</div>
						<div>
							<label><input type="checkbox" name="userhobby" value="그림"> 그림그리기</label>
						</div>
						<div>
							<label><input type="checkbox" name="userhobby" value="영화"> 영화보기</label><br>
						</div>
						<div>
							<label><input type="checkbox" name="userhobby" value="운동"> 운동하기</label>
						</div>
						<div>
							<label><input type="checkbox" name="userhobby" value="노래"> 노래부르기</label>
						</div>
						<div>
							<label><input type="checkbox" name="userhobby" value="코딩"> 코딩하기</label>
						</div>
					</div>
				</td>
			</tr>
			<tr>
				<th colspan="2">
					<input type="submit" value="가입 완료">
				</th>
			</tr>
		</table>
	</form>
</body>
<script src="//t1.daumcdn.net/mapjsapi/bundle/postcode/prod/postcode.v2.js"></script>
<script src="./user.js"></script>
</html>

• WebContent에다가 javascriptSourceFile로 생성
• user.js

    → 여기서는 javascript 문법을 바로 사용 가능하다.
	 function sample6_execDaumPostcode() {
        new daum.Postcode({
            oncomplete: function(data) {
                // 팝업에서 검색결과 항목을 클릭했을때 실행할 코드를 작성하는 부분.

                // 각 주소의 노출 규칙에 따라 주소를 조합한다.
                // 내려오는 변수가 값이 없는 경우엔 공백('')값을 가지므로, 이를 참고하여 분기 한다.
                var addr = ''; // 주소 변수
                var extraAddr = ''; // 참고항목 변수

                //사용자가 선택한 주소 타입에 따라 해당 주소 값을 가져온다.
                if (data.userSelectedType === 'R') { // 사용자가 도로명 주소를 선택했을 경우
                    addr = data.roadAddress;
                } else { // 사용자가 지번 주소를 선택했을 경우(J)
                    addr = data.jibunAddress;
                }

                // 사용자가 선택한 주소가 도로명 타입일때 참고항목을 조합한다.
                if(data.userSelectedType === 'R'){
                    // 법정동명이 있을 경우 추가한다. (법정리는 제외)
                    // 법정동의 경우 마지막 문자가 "동/로/가"로 끝난다.
                    if(data.bname !== '' && /[동|로|가]$/g.test(data.bname)){
                        extraAddr += data.bname;
                    }
                    // 건물명이 있고, 공동주택일 경우 추가한다.
                    if(data.buildingName !== '' && data.apartment === 'Y'){
                        extraAddr += (extraAddr !== '' ? ', ' + data.buildingName : data.buildingName);
                    }
                    // 표시할 참고항목이 있을 경우, 괄호까지 추가한 최종 문자열을 만든다.
                    if(extraAddr !== ''){
                        extraAddr = ' (' + extraAddr + ')';
                    }
                    // 조합된 참고항목을 해당 필드에 넣는다.
                    document.getElementById("sample6_extraAddress").value = extraAddr;
                
                } else {
                    document.getElementById("sample6_extraAddress").value = '';
                }

                // 우편번호와 주소 정보를 해당 필드에 넣는다.
                document.getElementById('sample6_postcode').value = data.zonecode;
                document.getElementById("sample6_address").value = addr;
                // 커서를 상세주소 필드로 이동한다.
                document.getElementById("sample6_detailAddress").focus();
            }
        }).open();
    }
    function checkId() {
    	const userid = document.joinForm.userid;
    	if(userid.value.length<5 || userid.value.length>12) {
    		alert("아이디는 5자 이상 12자 이하로 입력해주세요!");
    		userid.focus();
    		return false;
    	}
    	const result = document.getElementById("result");
    	const xhr = new XMLHttpRequest();
    	
    	xhr.open("GET","checkId_db.jsp?userid="+userid.value,true);
    	// 서버에서 응답이 도착하면 특정한 자바스크립트 함수를 호출
    	xhr.onreadystatechange = function() {
    		// readyState == 4란 의미는 데이터를 전부 받은 상태, 완료된 상태를 의미한다.
    		if(xhr.readyState == 4) {
    			// status == 200은 서버로 부터 응답상태가 요청에 성공하였다는 의미다.
    			if(xhr.status == 200) {
    				// 문자열로 응답 데이터를 얻음
    				let txt = xhr.responseText;
    				txt = txt.trim();
    				
    				if(txt == "O") {
    					result.innerHTML = "사용할 수 있는 아이디입니다!";
    				} else {
    					result.innerHTML = "이미 존재하는 아이디입니다!";
    				}
    			}
    		}
    	}
    	xhr.send();
    } 
 
 // 회원가입 유효성 검사   
 function join() {
		const joinForm = document.joinForm;
		const result = document.getElementById("result");
		
		const userid = joinForm.userid;
		if(userid.value == ""){
			alert("아이디를 입력하세요!");
			userid.focus();
			//userid.style.borderColor = "red";
			return false;
		}
		if(userid.value.length < 5 || userid.value.length > 12){
			alert("아이디는 5자 이상 12자 이하로 작성해주세요!");
			userid.focus();
			return false;
		}
		//userid.style.borderColor = "black";
		if(result.innerHTML == ""){
			alert("아이디 중복검사를 해주세요!")
			return false;
		}
		if(result.innerHTML != "사용할 수 있는 아이디입니다!"){
			alert("아이디가 중복되었습니다!");
			userid.focus();
			return false;
		}
		const userpw = joinForm.userpw;
		const userpw_re = joinForm.userpw_re;
		if(userpw.value == ""){
			alert("비밀번호를 입력하세요!");
			userpw.focus();
			return false;
		}
		// 정규식 - https://developer.mozilla.org/ko/docs/Web/JavaScript/Guide/Regular_Expressions
		// /^(?=.*?)/ : 맨 뒤 ? 뒤에 문자를 쓰면 그 문자가 있는지 확인하는 정규식
		let reg = /^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[~?!@#$%^&*_-]).{8,}$/
		if(!reg.test(userpw.value)) {
			alert("비밀번호는 8자 이상, 숫자, 대문자, 소문자, 특수문자를 모두 포함해야 합니다!");
			userpw.focus();
			return false;
		}
		// ↓의미 \w : 어떤문자가 있고 \1\1\1 : 그 문자가 연속으로 3번 반복되는지
		// \w\1\1\1 : 어떤문자가 4번 연속으로 써지는지 확인
		if(/(\w\1\1\1/.test(userpw.value)) {
			alert("같은 문자를 4번 이상 연속해서 사용하실 수 없습니다!");
			userpw.focus();
			return false;
		}
		// 띄어쓰기가 포함되어 있는지 확인 
		/*if(/\s/)*/
		// -1이면 띄어쓰기가 포함 x
		// -1이 아니면 띄어쓰기 포함
		if(userpw.value.search(" ") != -1) {
			alert("비밀번호는 공백을 포함할 수 없습니다!");
			userpw.focus();
			return false;
		}
		if(userpw_re.value == "") {
			alert("비밀번호를 확인을  해주세요!");
			userpw_re.focus();
			return false;
		}
		if(userpw.value != userpw_re.value ) {
			alert("비밀번호 확인을 다시 해주세요!");
			userpw.focus();
			return false;
		}
		
		const username = joinForm.username;
		if(username.value == ""){
			alert("이름을 입력하세요!");
			username.focus();
			return false;
		}
		const zipcode = joinForm.zipcode;
		if(zipcode.value == "") {
			alert("주소찾기를 진행해주세요!");
			sample6_execDaumPostcode();
			return false;
		}
		const addrdetail = joinForm.addrdetail;
		if(addrdetail.value =="") {
			alert("주소를 마저 입력해주세요!");
			addrdetail.focus();
			return false;
		}
		// userhobby를 찾으면 배열로 받아 올 수 있다.
		// for(let hobby of hobbies) : userhobby라고 되어 있는 name들을 전부 꺼내오면서 hobby에 넣어준다.
		const hobbies = joinForm.userhobby;
		let check = false;
		
		for(let hobby of hobbies) {
			// hobby.checked : 취미가 채크가 되어있는지 확인
			if(hobby.checked) {
				check = true;
				break;
			}
		}
		if(!check) {
			alert("취미를 하나 이상 선택하세요!");
			return false;
		}
		return true;
	}
			
    
    
	// 로그인 유효성 검사
	function sendit() {
		const userid = document.loginForm.userid;
		const userpw = document.loginForm.userpw;
		
		if(userid.value=="") {
			alert("아이디를 입력하세요!")
			userid.focus();
			return false;
		}
		if(userpw.value=="") {
			alert("비밀번호를 입력하세요!")
			userpw.focus();
			return false;
		}
		return true;
	}	
profile
발전하기 위한 공부

0개의 댓글