티스토리 뷰

728x90
SMALL

1부에선 콬어 자바스크립트에 대해 설명했고 이제부터는 일반적으로 클라인트 측 자바스크립트라고 부르는 웹브라우저에서 사용하는 자바스크립트에 대해 알아본다.

클라이언트 측 자바스크립트

Window 객체는 클라이언트 측 자바스크립트의 기능과 API에서 핵심적인 진입점이다. 이 객체는 웹브라우저의 창이나 프레임을 나타내고, 그러므로 특정 창(window)을 Window 객체로 참조할 수 있다. 명시적으로 window가 사용되지 않을때가 있는데, 이는 클라이언트 측 자바스크립트에서는 Window 객체가 전역 객체이기 때문이다. 이는 Window 객체가 유효범위 체인의 최상위에 있고, Window 객체의 프로퍼티와 메서드가 사실상 전역 변수와 전역 함수라는 의미다.

<!DOCTYPE html>
<html>
<head>
<style>
/* CSS styles for this page */
.reveal * { display: none; }  /* Children of class="reveal" are  not shown */
.reveal *.handle { display: block;} /* Except for the class="handle" child */
</style>
<script>
// Don't do anything until the entire document has loaded
window.onload = function() {
    // Find all container elements with class "reveal"
    var elements = document.getElementsByClassName("reveal");
    for(var i = 0; i < elements.length; i++) {  // For each one...
        var elt = elements[i];
        // Find the "handle" element with the container
        var title = elt.getElementsByClassName("handle")[0];
        // When that element is clicked, reveal the rest of the content
        title.onclick = function() {
            if (elt.className == "reveal") elt.className = "revealed";
            else if (elt.className == "revealed") elt.className = "reveal";
        }
    }
};
</script>
</head>
<body>
<div class="reveal">
<h1 class="handle">Click Here to Reveal Hidden Text</h1>
<p>This paragraph is hidden. It appears when you click on the title.</p>
</div>
</body>
</html>

 

웹 문서의 자바스크립트

자바스크립트 프로그램은 컨테이너 역할을 하는 Documnet 객체와 Element 객체를 통해서 문서 내용을 탐색하고 조작할 수 있다. 일반적으로 웹 문서 안에서는 되도록이면 자바스크립트를 덜 사용해야 한다.

웹 애플리케이션의 자바스크립트

웹 애플리케이션은 웹 문서의 자바스크립트 DHTML 기능을 모두 사용할 뿐만 아니라, 이를 넘어서서 웹브라우저 환경이 제공하는 내용과 표현, 행위를 조작하는 API 등의 핵심 부가 서비스를 제공한다.

확장된 서비스 중 가장 유명한 것은 XMLHttpRequest 객체다. 이 객체는 HTTP 요청을 짜서 네트워킹을 가능하게 한다. 웹앱은 페이지를 다시 불러오지 않고도 서버에서 새로운 정보를 가져오기 위해 이 서비스를 사용한다. 이런 일을 하는 웹 애플리케이션을 보통 Ajax 애플리케이션이라고 한다.

당연하게도 자바스크립트는 웹 문서보다는 웹 애플리케이션에서 더 중요하다. 웹 문서는 자스가 비활성되어도 그 역할을 해네지만 웹 애플리케이션에서는 자스를 비활서오하한 상태로 작업하는 것은 고려하지 않는다.

HTML 안에 자바스크립트 표현하기

클라이언트 측 자바스크립트를 HTML 문서 안에 내장하는 방법은 네 가지다.

1. <script> 태그와 </script> 태그 안에 직접 작성

2. <script> 태그의 src 속성에 별도 파일로 정의

3. onClick이나 onmouseover 같은 HTML 이벤트 핸들러 속성 안에 작성

4. javascript:라는 특별한 프로토콜을 사용해서 URL 안에 작성

(3, 4번은 최근 사용하지 않는다. 내용과 동작을 불리하기 위해)

<a href="javascript:void window.open('about:blank');">Open Window</a>

URL 안의 자바스크립트를 넣는 가장 적절한 사용처는 브라우저 북마크다.

자바스크립트 프로그램의 실행

다른 형태로 페이지에 존재하는 독립된 코드들은 하나의 전역 Window 객체를 공유한다. 이 말은 같은 Document 객체를 바라보며 같은 전역 함수와 변수를 공유한다는 뜻이고, 새로운 전역 변수나 함수가 정의되면 정의된 후에 작동하는 자바스크립트 코드에서도 이 변수와 함수가 노출된다는 의미다. <iframe> 요소를 사용한 내장 프레임이 있으면, 내장된 문사의 자스 코드에는 전혀 다른 전역 객체가 존재한다.

북마클릿의 javascript:URL은 문서 밖에 있으므로 사용자 확장이나 타 프로그램에서의 변경으로 볼 수 있다. 북마클릿을 실행하면 그 안의 자바스크립트 코드는 현재 문서의 전역 객체와 내용에 접근할 수 있고 조작도 할 수 있다.

자스 프로그램은 두 단계로 나뉘어서 실행한다. 첫 단계에서는 문서 내용을 불러오고 <script>요소의 코드를 실행한다.(내장, 외부 스크립트 포함) 스크립트는 일반적으로 순서대로 실행된다. 문서를 불러온 후 모든 스크립트를 실행하면, 두번째 단계로 넘어간다. 두번째 단계에서는 이벤트를 중심으로 비동기적으로 자바스크립트가 실행된다. 웹 페이지 안에 적혀있는 javascript:URL도 이벤트 핸들러의 한 형태이다.

동기, 비동기, 연기된 스크립트

defer 속성 : 브라우저는 문서를 모두 불러오고 파싱해서 조작할 준비가 끝날 때까지 스크립트 실행을 미룬다.

async 속성 : 스크립트를 다운로드 하는 동안에도 문서 파싱을 계속하고, 문서 파싱 완료와 관계없이 가급적 빨리 스크립트를 실행한다.

두 속성을 모두 실행하면 async 속성을 적용한다.

이벤트가 주도하는 자바스크립트

이벤트 핸들러 함수는 등록된 요소에서 이벤트가 발생하는 비동기 시점에 호출된다. 어떤 기능을 실행할 단축키가 필요한 웹 애플리케이션에서 key 이벤트에 이벤트 핸들러를 등록하는 것이 예가 될 수 있다.

프로그램이 이벤트에 응답하게 하려면, 이벤트 핸들러, 이벤트 리스너 경우에 따라서 콜백이라고도 하는 함수를 작성해야 한다. 그리고 이벤트가 발생했을 때 적용되도록 함수를 등록한다. 많이 알려진 것처럼, 이벤트 핸들러 등록을 위해 HTML 속성을 사용할 수 있으나 이러면 HTML과 자스 코드가 뒤섞여서 좋지 않다. 간단한 방법은 대상 객체의 속성에 자스 함수를 지정하는 것이다.

이벤트 핸들러 속성에는 'on'뒤에 이벤트 종류를 나타내는 이름을 쓴다. 이벤트를 통한 비동기 프로그래밍에서는 종종 중첩 함수를 사용하게 된다. 대부분의 브라우저에서 거의 모든 이벤트는 이벤트 핸들러에 객체를 전달인자로 넘기고, 이 객체의 프로퍼티로 이벤트에 대한 상세 정보를 제공한다. 이벤트 타깃이 문서 요소일 때는 이벤트가 버블링 과정을 통해 문서 계층 구조를 따라 올라간다.

하나의 이벤트에 여러 개의 이벤트 핸들러 함수를 등록하거나, 이미 어떤 모듈이 이벤트 핸들러를 등록한 객체를 타깃으로 삼아서 같은 이벤트에 이벤트 핸들러를 등록하는 모듈이 문제가 없으려면, 다른 이벤트 핸들러 등록 방법을 사용해야 한다. window.addEventListener("load", function(){...},false);

addEventListener() 함수의 첫 번째 인자는 이벤트 명이다.

setTimeout()과 setInterval() 함수. setTimeout()에 전달된 함수는 보통 콜백이라고 부른다.

클라이언트 측 자바스크립트 스레드 모델

자바스크립트는 단일 스레드 실행이다.

실행 시간이 오래 걸리는 연산을 실행해야 한다면, 그전에 문서를 모두 불러와야만 하고, 연산이 실행중이며 브라우저가 정지되지 않았음을 사용자에게 알려야 한다. 하위 작업으로 연산을 나누는 것이 가능하다면, 사용자에게 진행 상황을 보여주는 진행률 표시기를 갱신하면서, 백그라운드에서 하위 작업을 실행하기 위해 setTimeout()과 setInterval() 같은 함수를 사용할 수 있다.

HTML5는 웹 워커라고 하는 관리 가능한 동시성 처리 방식을 제공한다.

클라이언트 측 자바스크립트 실행 순서

1. 웹 브라우저는 Document 객체를 생성하고 웹 페이지 분석을 시작하는데, HTML 요소와 그 안의 텍스트 내용을 분석해서 Element 객체와 Text 노드를 웹 페이지 문서에 추가한다. 이때, document.readyState 속성 값은 'loading'이다.

2. HTML 분석기가 async나 defer 속성이 없는 <script> 요소와 만나면, 문서 안에 추가시키고, 내장 스크립트건 외부 파일이건 구분 없이 실행한다. 이런 스크립트는 동기 모드로 실행된다. 그래서 스크립트를 다운로드(가능하다면)하고 실행하는동안 HTML 분석기는 멈춘다. 이런 스크립트에서는 입력 대기열에 텍스트를 넣기 위해 document.write()를 사용할 수 있다. 이 텍스트는 HTML 분석기가 다시 작동할 때 문서의 일부가 된다. 때로는 동기 모드 스크립트에서도 단순히 나중에 사용할 함수를 정의만 하고 이벤트 핸들러만 등록한다. 하지만 이 함수를 실행할 때는 존재하는 문서 트리를 넘나들어 수정할 수 있다. 즉, 동시 모드 스크립트는 <script> 요소 자신과 그 이전에 나온 문서 내용에 접근할 수 있다.

3. HTML 분석기가 async 속성이 지정된 <script> 요소를 만나면, 스크립트 텍스트 다운로드를 시작하고 문서 분석도 계속한다. 스크립트는 다운로드된 후에 가능한 빨리 실행되겠지만, 분석기는 멈추거나 다운로드를 기다리지 않는다. 비동기 스크립트에서는 document.write() 메서드를 사용할 수 없다. <script> 요소 자신과 그 이전에 나온 문서 내용에 접근할 수 있고, 추가되는 문서 내용에는 접근 권한이 있을 수도, 없을 수도 있다.

4. 문서 분석이 완료되면, document.readyState 속성 값은 "interactive"로 바뀐다.

5. defer 속성이 있는 스크립트는 문서 내에 나타나는 순서대로 실행된다. 이때도 async 속성의 스크립트는 실행될 것이다. 지연된 스크립트는 완성된 문서 트리에 접근 권한이 있으며 document.write() 메서드는 사용하면 안된다.

6. 브라우저는 Document 객체에서 DOMContentLoaded 이벤트를 일으킨다. 이 이벤트는 프로그램 실행 단계가 동기 모드 스크립트 단계에서 비동기 모드인 이벤트 주도 단계로 옮겨갔다는 신호다. 그러나 이 시점까지도 아직 실행되지 않은 비동기 스크립트가 있을 수 있다.

7. 브라우저는 이 시점에서 문서를 완전히 분석했지만, 이미지 등의 추가로 불러와야 하는 내용을 기다릴 수 있다. 이런 내용도 모두 불러오고 모든 비동기 스크립트도 불러와서 실행했으면, document.readyState 속성 값은 'complete'로 바뀐다. 그리고 웹브라우저는 Window 객체에 load 이벤트를 발생시킨다.

8. 이 시점부터 이벤트 핸들러는 사용자 입력 이벤트, 네트워크 이벤트, 타이머 만료 등의 응답으로 비동기 호출된다.

호환성과 상호운용성

클라이언트 측 자바스크립트 호환성과 상호운용성 문제점은 일반적으로 세가지로 분류한다.

기술의 진화

웹 플랫폼은 계속 진화하고 확장되고 있다. 그리고 웹에는 새로운 기능이 생긴다. 새로운 브라우저는 이 기능을 지원하고 오래된 브라우저는 그렇지 않다. 웹 개발자는 강력한 새 기능을 사용하고 싶은 마음과 많은 방문자에게 사용되길 원하는 마음 모두에 사로잡힌다.

미구현 기능

때때로 브라우저 업체들은 어떤 기능이 구현할 만큼 정말 유용한지에 대해 이견이 있다. ex) IE8은 canvas 지원x

버그

모든 브라우저는 버그가 있다. 때로는 호환되는 클라이언트 측 자바스크립트 코드를 작성할 때 브라우저 버그를 인지하고, 이런 버그를 피해서 일하는 법을 알아야 한다.

 

인터넷 익스플로어의 조건부 주석

<!--[if IE]<script src="excanvas.js"></script><![endif]-->

접근성

자바스크립트가 있어야 정보를 볼 수 있도록 웹사이트를 디자인했다면, 여러분은 스크린 리더기를 사용하는 사용자를 소외시킨 것이다. 자바스크립트의 적절한 역할은 정보의 표현 방식을 개선하는 것이므로 정보 표현 자체를 대행해서는 안된다. 자바스크립트 접근성과 관련된 가장 중요한 원칙은 자바스크립트를 적용한 페이지가 자바스크립트 인터프리터를 끄고도 활용할 수 있도록 코드를 설계하는 것이다.

접근성의 또 다른 중요점은 마우스 같은 포인팅 장치를 사용할 수 없는 키보드 사용자를 배려하는 것이다.

접근성을 우려하는 웹 애플리케이션 개발자는 WAI-ARIA 표준에 익숙해야 한다.

보안

웹 브라우저에 자바스크립트 인터프리터가 들어 있다는 말은 웹 페이지를 불러오는 순간 여러분의 컴퓨터에서 임의의 자바스크립트 코드가 실행될 수도 있다는 의미다. 이것은 분명 보안상 문제가 될 수 있기 때문에 브라우저 제조사는 다음 두가지 상반된 목표의 균형을 잡기 위해 노력해 왔다.

1. 웹 애플리케이션에서 사용할 수 있는 강력한 클라이언트 측 API를 정의하는 일

2. 사용자 데이터에 접근해서 변경하고, 개인정보를 손상시키거나 금융사기를 저지르고, 여러분이 시간을 낭비하게 하는 악의적인 코드를 예방하는 일

자바스크립트가 할 수 없는 것

악성 코드에 대한 웹브라우저의 일차적인 방어책은 특정 기능들을 제공하지 않는 것이다. 예를 들어, 자바스크립트는 클라이언트 컴퓨터에서 임의로 디렉터리와 파일을 만들거나 지울 수 없다. 따라서 데이터를 삭제하거나 바이러스를 침투 시킬 수 없다.

같은 이유로 클라이언트 측 자바스크립트는 범용 네트워킹 기능이 전혀 없다. 물론 클라이언트 측 자스로 HTTP 프로토콜을 구현할 수 있지만 이런 API들은 중간 단계를 하나 거치지 않고는 광역 네트워크에 접근하는 것이 불가능하다.

악성 코드에 대한 웹 브라우저의 두 번째 방어책은 브라우저가 지원하는 어떤 기능에 사용 제약을 두는 것이다.

1. 자스는 브라우저에서 새 창을 열 수 있다. 하지만 광고주들의 팜업 남용을 막기 위해 대부분의 브라우저는 막아놨고 마우스 클릭으로 사용자가 직접 새 창을 열게 한다.

2. 자스는 스스로 연 새 창은 다시 닫을 수 있지만, 다른 창을 닫으려면 사용자가 확인 창에서 승인을 해주어야 한다.

3. <input type="file">의 value 속성은 값을 불러올 수는 있지만 지정할 수는 없다.

4. 스크립트는 자신이 실행된 문서의 서버와 다른 서버에서 불러온 문서의 내용은 읽을 수 없다.

동일 출처 정책

플러그인과 액티브엑스 컨트롤 스크립팅

이제 안써

크로스 사이트 스크립팅

크로스 사이트 스크립팅 혹은 XSS(Cross-site-scripting)는 사이트 공격자가 목표 사이트에 HTML 태그나 스크립트를 집어넣는 보안 문제를 일컫는 말이다. XSS 공격을 막는 것은 일반적으로는 서버 측 웹 개발자의 업무다. 그러나 클라이언트 측 자바스크립트 프로그래머도 XSS에 대해 알고 막을 수 있어야 한다.

XSS 공격을 막는 일반적인 방법은 동적으로 문서 내용을 생성하기 전에, HTML 태그를 지워버리는 것이다. 

<script>
var name=decodeURIComponent(window.location.search.substring(1)) || "";
document.write("Hello "+name);
</script>
//해결책
name=name.replace(/</g,"<").replace(/>/g,">");

서비스 거부 공격

앞에서 설명한 동일 출처 정책과 다른 보안 관련 제약 조건은 데이터를 손상시키고 개인 정보를 누출하는 등의 악성 코드 방어에는 훌륭한 역할을 한다. 그러나 이러한 보안 제약들이 사이트를 완전히 마비시키는 서비스 거부 공격을 막아주지는 못한다. 만약 자바스크립트가 활성화된 브라우저로 악의적인 웹 사이트를 방문한다면, 이 사이트는 alert() 대화상자를 무한정 띄워서 브라우저를 꼼짝 못하게 묶어둘 수 있다.

클라이언트 측 프레임워크

여러분이 프레임워크를 한번 선택하면, 여러분의 코드는 프레임워크가 정의한 API를 사용하여 작성해야 한다. 프레임워크를 사용할 때 얻을 수 있는 확실한 이점은 작성 코드량을 줄여주는 고수준 API가 있다는 사실이다. 또한 잘 만들어진 프레임워크는 앞에서 설명한 호환성과 보안, 접근성과 관련된 많ㄹ은 문제들에 대한 해결책을 다룰것이다.

 

728x90
LIST
댓글
공지사항