페이지 작성해보기
디렉토리를 하나 만들고 그 안에 index.html
, style.css
, app.js
세가지 파일을 만들어 각각 아래의 내용을 저장한다. 각각의 파트를 설명하자면 너무도 많은 내용이 필요하다. 이 문서에서는 자세한 내용은 이야기 하지 않고 이 구조를 경험하고 이해하는 것만 집중하자.
HTML
<!DOCTYPE html>
<html>
<head>
<title>연락처</title>
<link rel="stylesheet" href="./style.css">
<script src="./app.js"></script>
</head>
<body>
<main>
<h1>연락처</h1>
<ul>
<li>가나다: ganada@ganada.com</li>
<li>마바사: mabasa@mabasa.com</li>
<li>아자차: ajacha@ajacha.com</li>
<li>카타파: catapa@catapa.com</li>
</ul>
</main>
</body>
</html>
CSS
body {
color: #eeeeee;
background-color: #333333;
}
JS
(function (){
document.addEventListener("DOMContentLoaded", function() {
document.querySelectorAll("li").forEach(function(li){
li.addEventListener("click", function() {
alert(this.textContent);
})
})
})
})();
실행
위 파일을 만들었다면 index.html을 브라우저로 열어서 실행되는것을 확인해볼 수 있다. html 구조와 css로 화면을 렌더링하고 js를 통해 사용자 이벤트를 연결하였다. 전세계에 있는 모든 웹 페이지는 이 구조를 벗어나지 않는다. 레이아웃 구성, js 모듈화, css 분할, 템플릿 태그, 태그 분할과 재사용 등등 자세히 들어가면 정말 방대한 방식들이 존재하지만 요즘에는 webpack 이나 vite같은 번들러를 활용하여 자동으로 적절한 구조를 만들어준다. 물론, 번들링된 결과도 이 구조를 벗어나지 않는다.
데이터 통신
모든 프로그램은 입력과 출력이 있다. 화면을 표시하여 출력을 확인해 보았으니 데이터를 입력할 수 있는 수단을 만들어 보자. html 파일은 브라우저에서 렌더링되어 전적으로 브라우저가 구동되고 있는 사용자의 PC로컬환경에서만 작동한다. 페이지가 그렇게 사용되도록 설계되었다면 문제가 없겠지만 보통 웹 어플리케이션을 작성한다면 서버 자원을 활용할 수 있도록 하는 것이 목적일 것이다.
그렇다면 로컬에서 작동하는 웹 페이지에서 작성한 데이터를 서버로 전달해야할 필요가 있다. 이 때 사용할 수 있는 방법은 여러가지가 있지만 이 문서에서는 대표적인 몇 가지만 소개해 주려고 한다.
클라이언트에서 서버로 데이터를 전송할 때에는 Request
와 Response
라는 객체를 우선 이해해야한다. 용어는 서버 입장에서 정의된 것으로 서버에서 이 객체를 다룰때에도 req, res 라는 변수명을 주로 사용한다. Request는 크게 헤더와 바디 두 부분으로 나뉘는데 요청에 대한 정보는 헤더에 데이터는 바디를 통해 전송된다. 서버측은 헤더를 먼저 분석하여 서버가 소화해낼 수 있는 요청이라면 바디를 읽어들이고 그렇지 않다면 바디를 수신하지 않고 오류를 반환하거나 클라이언트로 올바르지 않은 요청임을 알려줄 수 있다. 이러한 작업순서는 비교적 큰 데이터인 바디를 읽어들이기 전에 예상되는 오류를 감지해 네트워크 트래픽을 줄일 수 있다.
이렇게 데이터를 전송할 때에는 서버가 제공하는 특정한 URL과 method가 필요하다. method는 기능을 구분하는 구분자로써 사용되는데 get
, post
, put
, patch
, delete
, options
, trace
와 같은 것들이 있다. 우리가 서버에 접속하여 웹 페이지를 응답받는 것도 생략된 get 방식의 method가 작동하였기 때문에 응답받은 것이다. 즉, 웹 서버는 기본적으로 URL과 method를 구분자로 엔드 포인트가 결정되며 이를 두고 restful
이라고 표현한다. 주로 사용하는 method는 다음처럼 구분할 수 있다.
- get: 읽기
- post: 신규
- put: 덮어쓰기
- patch: 부분변경
- delete: 삭제
Query String
http://localhost:3000/path/of/resource?username=abc&email=123
가장 간단하게 서버에 데이터를 전달할 수 있어서 많이 사용된다. URL의 끝에 ?
를 구분자로하여 abc=123
과 같이 필드와 값을 지정해줄 수 있다. &
를 통해 여러개의 데이터를 전송할 수 있다.
form 태그
<form action="/path/of/resource" method="post">
<input type="text" name="username" />
<input type="email" name="email" />
<button type="submit">전송</button>
</form>
폼 태그는 사용자에게 입력할 수 있는 UI를 제공하고 입력된 데이터는 submit
버튼을 통해 서버로 데이터를 전송할 수 있다. 전통적인 방식의 데이터 전송방법으로 페이지가 action
에 설정된 URL로 이동되면서 데이터를 전송한다. method
는 해당 하는 URL에 대응되는 기능들을 선택할 수 있는 방법이다. 서버가 restful
방식의 기능 인터페이스를 제공할 때 유용하게 사용할 수 있다.
method가 get일 경우 각각의 필드들은 querystring으로 붙여진다. 큰 데이터의 경우 데이터가 request 바디를 통해 전송될 수 있도록 post, put, patch 등을 사용하는 것이 좋다. Request 객체의 헤더는 기본적으로 500kb가 넘을 경우 중간에 데이터가 잘리는 경험을 할 수도 있다. 이런 최대길이 제한은 서버 설정에 따라 다를 수 있겠으나 애초에 URL 자체가 지저분해져 사용자에게 혼란스러움을 주기 때문에 최대한 지양하는 것이 좋다.