ajax 인 프랙티스 : 실전 예제를 통한 최신 ajax 기법 마스터

102

Post on 22-Jul-2016

246 views

Category:

Documents


19 download

DESCRIPTION

데이브 크레인, 베어 바이볼트, 조드 손네벨드 지음 | 일래스틱웨어, 최용호, 이승준 옮김 | 위키북스 오픈소스 & 웹 시리즈_004 | ISBN: 9788995856499 | 27,000원 | 2007년 10월 31일 발행 | 600쪽

TRANSCRIPT

Page 1: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터
Page 2: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

Ajax인 프랙티스실 전 예 제 를 통 한 최 신 A j a x 기 법 마 스 터

Page 3: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

Ajax 인 프랙티스실전 예제를 통한 최신 Ajax 기법 마스터

Page 4: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

iv

저 자 에 대 해 .............................................xvii

옮 긴 이 글 ................................................xviii

서 문 ......................................................xx

감 사 의 글 ................................................xxii

이 책 에 대 해 .............................................xxiv

표 지 그 림 에 대 해 ......................................xxviii

1부 Ajax기초

1장 Ajax를포용한개발자들

1.1 혁신 기술로서의 Ajax .........................................5

1.1.1 사용자의 워크플로우 재정의 ...................................5

1.1.2 웹 애플리케이션 아키텍처 재정의 ...............................7

1.2 Ajax의 기본 특징 .............................................10

1.2.1 XMLHttpRequest 소개 ........................................10

1.2.2 XMLHttpRequest의 인스턴스화 .................................11

1.2.3 요청 전송 ...................................................12

1.2.4 응답 처리 ...................................................14

1.2.5 다른 XMLHttpRequest 메서드와 속성 ............................16

abort() .....................................................16

setRequestHeader(header, value) ...............................17

getResponseHeader(header)/getAllResponseHeaders() .............17

1.3 프레임워크를 사용하여 Ajax를 단순하게 만들기 ....................18

1.3.1 Prototype의 Ajax.Request 객체로 요청 만들기 .....................20

문제 ........................................................20

솔루션 ......................................................20

클라이언트 측 코딩 ...........................................21

목 차

Page 5: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

v

서버 측 코딩 .................................................23

토론 ........................................................23

1.3.2 Ajax 응답 단순화 .............................................24

문제 ........................................................25

솔루션 ......................................................25

토론 ........................................................26

1.4 요약 .......................................................27

2장 Ajax와의통신방법

2.1 서버 측 자바스크립트 생성 .....................................30

2.1.1 서버에서 생성된 코드 수행 ....................................30

문제 ........................................................31

솔루션 ......................................................31

토론 ........................................................33

2.1.2 좋은 코드 생성 규정 활용하기 ...................................33

문제 ........................................................33

솔루션 ......................................................35

토론 ........................................................37

2.2 JSON 소개 ...................................................38

JSON 기초 ...................................................38

2.2.1 서버에서 JSON 생성하기 .......................................40

문제 ........................................................41

솔루션 ......................................................41

토론 ........................................................44

2.2.2 전체 라운드 트립에서 JSON을 사용하여 데이터 처리하기 ............45

문제 ........................................................45

솔루션 ......................................................45

토론 ........................................................49

대괄호에서 꺽음 괄호까지 ......................................50

2.3 Ajax에서 XML과 XSLT 사용하기 .................................50

2.3.1 서버에서 생성된 XML 파싱하기 .................................50

문제 ........................................................51

솔루션 ......................................................51

토론 ........................................................56

Page 6: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

vi

2.3.2 XSLT와 XPath를 이용하여 XML 처리 ..............................57

문제 ........................................................57

솔루션 ......................................................57

토론 ........................................................62

2.4 Ajax와 웹 서비스 사용 .........................................63

문제 ........................................................65

솔루션 ......................................................65

토론 ........................................................70

2.5 요약 ........................................................71

3장 객체지향라이브러리와Prototype

3.1 객체지향 자바스크립트 ........................................75

3.1.1 객체 기초 ...................................................75

3.1.2 함수는 퍼스트 클래스 (first-class) ................................78

함수 선언 및 호출 .............................................79

함수 컨텍스트 이해 ...........................................81

낯선 사람이 가죽끈을 잡을 때 ...................................83

함수 컨텍스트 설정 ...........................................84

클로저 소개 ..................................................85

3.1.3 객체 생성자와 메서드 ..........................................87

생성자 정의 ..................................................87

메서드 추가 ..................................................88

프로토타입(prototype) 정의 ....................................90

클래스 메서드 생성 ...........................................93

3.1.4 자바스크립트 클래스 작성: 버튼 ................................95

버튼 생성자 ..................................................96

클래스 레벨의 멤버 변수 .......................................103

마우스 이벤트 핸들러 ..........................................104

활성화된 상태 메서드 ..........................................105

Button 클래스 테스트 .........................................107

3.2 Prototype 라이브러리 .........................................111

3.2.1 일반적으로 유용한 함수와 확장 기능 .............................112

DOM 요소 참조 획득 ..........................................112

Page 7: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

vii

폼 컨트롤의 값 얻기 ...........................................113

3.2.2 배열 확장 ...................................................114

$A() 함수 ....................................................115

Enumerable 클래스와 메서드 ...................................115

3.2.3 Hash 클래스 .................................................117

3.2.4 컨텍스트 객체와 함수의 결합 ...................................118

3.2.5 객체지향 Prototype ...........................................120

Prototype으로 클래스 생성 .....................................121

Prototype으로 객체 병합 .......................................122

Prototype으로 클래스 확장하기 .................................123

3.2.6 Prototype으로 Button 클래스 재코딩 .............................129

3.3 요약 ........................................................132

4장 오픈소스Ajax툴킷

4.1 Dojo 툴킷 ...................................................137

4.1.1 Dojo로 비동기 요청 처리 .......................................137

문제 ........................................................137

솔루션 ......................................................138

토론 ........................................................141

4.1.2 Dojo를 이용한 자동 폼 마샬링 ..................................142

문제 ........................................................142

솔루션 ......................................................142

토론 ........................................................144

4.2 Prototype ...................................................144

4.2.1 Prototype을 사용하여 비동기 요청 ...............................144

문제 ........................................................145

솔루션 ......................................................145

토론 ........................................................151

4.2.2 Prototype을 사용한 자동 업데이트 ...............................151

문제 ........................................................151

솔루션 ......................................................152

토론 ........................................................154

4.2.3 Prototype을 사용한 주기적인 업데이트 ...........................154

문제 ........................................................154

Page 8: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

viii

솔루션 ......................................................154

토론 ........................................................156

4.3 jQuery ......................................................156

4.3.1 jQuery 기본..................................................157

jQuery 래퍼..................................................157

jQuery 연산을 연결하기 ........................................159

jQuery와 Prototype을 함께 사용하기 .............................160

4.3.2 jQuery를 사용한 비동기 로딩 ...................................161

문제 ........................................................161

솔루션 ......................................................161

토론 ........................................................165

4.3.3 jQuery를 사용하여 동적 데이터 가져오기 .........................166

문제 .......................................................166

솔루션 ......................................................166

토론 ........................................................170

4.4 DWR .......................................................171

4.4.1 DWR을 이용한 웹 리모팅(Remoting) .............................172

문제 ........................................................173

솔루션 ......................................................173

토론 ........................................................180

4.5 요약 ........................................................181

2부 Ajax실전사례

5장 이벤트다루기

5.1 이벤트 처리 모델들 ...........................................187

5.1.1 기본 이벤트 처리 등록 .........................................187

5.1.2 고급 이벤트 핸들링 ...........................................191

5.2 이벤트 객체와 이벤트 전파 .....................................194

5.2.1 Event 객체 ..................................................195

5.2.2 이벤트 전파 ..................................................196

이벤트 전파 중단 .............................................200

기본 동작(default action) 막기 ..................................200

Page 9: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

ix

5.3 이벤트 처리를 위해 Prototype 사용하기 ..........................201

5.3.1 Prototype 이벤트 API ..........................................202

5.4 이벤트 타입 ..................................................204

5.4.1 마우스 이벤트들 ..............................................204

5.4.2 키보드 이벤트 ................................................206

5.4.3 change 이벤트 ...............................................209

5.4.4 페이지 이벤트 ................................................211

5.5 이벤트 실전배치 ..............................................213

5.5.1 서버 측에서 텍스트 필드 검증하기 ...............................214

문제 ........................................................214

솔루션 ......................................................214

토론 ........................................................218

5.5.2 페이지 전송을 하지 않고 폼 전송하기 ............................219

문제 ........................................................219

솔루션 ......................................................219

토론 ........................................................221

5.5.3 변경된 요소만 전송하기 ........................................222

토론 .......................................................225

5.6 요약 ........................................................226

6장 폼검증과전송

6.1 클라이언트 측 검증 ...........................................228

6.1.1 클라이언트 측에서 검증하기 ....................................229

문제 ........................................................229

솔루션 ......................................................229

토론 ........................................................233

6.1.2 즉각적인 검증 ................................................234

문제 ........................................................235

솔루션 ......................................................235

토론 ........................................................236

6.1.3 교차필드 검증 ................................................237

문제 ........................................................237

솔루션 ......................................................237

토론 ........................................................243

Page 10: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

x

6.2 데이터 전송하기 ..............................................245

6.2.1 POST 해부하기 ...............................................245

6.2.2 서버로 데이터 전송하기 ........................................247

문제 ........................................................247

솔루션 ......................................................247

토론 ........................................................250

6.2.3 서버로 폼 전송하기 ...........................................251

문제 ........................................................251

솔루션 ......................................................251

토론 ........................................................254

6.2.4 데이터 변경 감지하기 ..........................................255

문제 ........................................................255

솔루션 ......................................................255

토론 ........................................................261

6.3 요약 ........................................................261

7장 컨텐트네비게이션

7.1 네비게이션의 원리 ............................................264

7.1.1 건초 더미에서 바늘 찾기 .......................................264

7.1.2 더 나은 검색 만들기 ...........................................267

7.1.3 네비게이션과 Ajax ............................................268

7.2 전통적인 웹 기반의 네비게이션 .................................270

7.2.1 간단한 네비게이션 메뉴 ........................................270

문제 ........................................................270

솔루션 ......................................................270

토론 ........................................................272

7.2.2 DHTML 메뉴 .................................................273

문제 ........................................................273

솔루션 ......................................................273

7.3 데스크탑 애플리케이션의 네비게이션 빌리기 ......................277

7.3.1 qooxdoo 탭 뷰 ...............................................278

문제 .......................................................278

솔루션 ......................................................278

토론 .......................................................280

Page 11: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

xi

7.3.2 qooxdoo 툴바와 윈도우 ........................................281

문제 ........................................................281

솔루션 ......................................................281

토론 ........................................................284

7.3.3 qooxdoo 트리 위젯 ...........................................285

문제 ........................................................285

솔루션 ......................................................285

토론 ........................................................289

7.4 데스크탑과 웹 사이 ...........................................290

7.4.1 OpenRico 아코디언 컨트롤 .....................................290

문제 ........................................................291

솔루션 ......................................................291

토론 ........................................................294

7.4.2 HTML 위주의 트리 컨트롤 만들기 ................................294

문제 ........................................................295

솔루션 ......................................................295

토론 ........................................................301

7.5 요약 ........................................................301

8장 뒤로가기,새로고침,실행취소처리하기

8.1 브라우저 네비게이션 기능에 대한 접근 막기 .......................304

8.1.1 툴바 제거하기 ................................................304

8.1.2 키보드 바로 가기 가로채기 ....................................306

8.1.3 오른쪽 마우스 버튼 클릭으로 나타나는 컨텍스트 메뉴 막기 ..........306

8.1.4 네비게이션 히스토리와 새로고침 막기 ...........................307

문제 ........................................................307

솔루션 ......................................................307

토론 ......................................................310

8.2 브라우저 네비게이션 컨트롤 사용하기 ............................311

8.2.1 자바스크립트의 history 오브젝트 사용하기 .......................311

8.2.2 해시를 북마크로 사용하기 .....................................312

문제 .......................................................312

솔루션 ......................................................313

토론 ......................................................314

Page 12: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

xii

8.2.3 RSH(Really Simple History) 프레임워크 소개 .......................314

8.2.4 클라이언트 수준의 상태를 관리하기 위해 RSH 사용하기 ............315

문제 ........................................................315

솔루션 ......................................................316

토론 ........................................................319

8.2.5 RSH를 사용하여 서버에서 상태를 관리하기 ........................320

문제 ........................................................320

솔루션 ......................................................320

토론 ........................................................324

8.3 실행취소 동작 ................................................325

8.3.1 언제 실행취소 기능을 제공할 것인가? ............................326

8.3.2 undo 스택 구현하기 ...........................................326

문제 ........................................................327

솔루션 ......................................................327

토론 ........................................................332

8.3.3 한층 복잡한 애플리케이션을 위한 undo 스택 확장 .................332

문제 ........................................................333

솔루션 ......................................................333

토론 ........................................................342

8.4 요약 ........................................................342

9장 끌어다 놓기(Drag and drop)

9.1 자바스립트 끌어다 놓기 프레임워크들 ............................347

9.2 Ajax를 위한 끌어다 놓기 .......................................348

9.2.1 끌어다 놓기 가능한 Ajax 장바구니 ...............................348

문제 ........................................................349

솔루션 ......................................................350

토론 ........................................................355

9.2.2 목록들의 데이터 조작 ..........................................356

문제 ........................................................357

솔루션 ......................................................357

토론 ........................................................361

9.2.3 ICEfaces를 사용한 Ajax 장바구니 ................................362

문제 ........................................................362

Page 13: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

xiii

솔루션 ......................................................363

토론 ........................................................371

9.3 요약 ........................................................371

10장 사용자편의성

10.1 네트워크 지연 극복하기 ........................................375

10.1.1 지연시간에 대처하는 피드백 ....................................375

문제 ........................................................375

솔루션 ......................................................376

토론 ........................................................382

10.1.2 진행상태 표시 ................................................383

문제 ........................................................383

솔루션 ......................................................383

토론 ........................................................389

10.1.3 Ajax 요청 타임아웃 ...........................................390

문제 ........................................................390

솔루션 ......................................................390

토론 ........................................................393

10.1.4 여러 번 클릭 방지 .............................................394

문제 ........................................................394

솔루션 ......................................................394

토론 ........................................................397

10.2 입력오류 감지하고 방지하기 ....................................397

10.2.1 훨씬 더 적극적으로 문맥 도움말 표시하기 .........................398

문제 ........................................................398

솔루션 ......................................................398

토론 ........................................................404

10.2.2 폼 입력 검증 .................................................405

문제 ........................................................405

솔루션 ......................................................406

토론 ........................................................413

10.3 포커스와 레이어의 순서 ........................................414

10.3.1 포커스 순서 ..................................................414

문제 ........................................................415

Page 14: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

xiv

솔루션 ......................................................415

토론 ........................................................420

10.3.2 겹치는 순서 관리 .............................................421

문제 ........................................................421

솔루션 ......................................................421

토론 ........................................................426

10.4 요약 ........................................................427

11장 클라이언트상태관리와캐시

11.1 클라이언트 상태 관리 ..........................................431

11.2 서버 데이터 캐싱 .............................................434

11.2.1 자바 클래스 데이터의 교환 ....................................435

문제 .......................................................436

솔루션 ......................................................436

고객 데이터 표시 .............................................442

토론 .......................................................444

11.2.2 데이터 미리 가져오기 ..........................................444

문제 ........................................................445

솔루션 ......................................................445

토론 ........................................................447

11.3 클라이언트 상태의 유지 ........................................449

11.3.1 JSON을 이용한 사용자 상태의 저장 및 접근 .......................449

문제 ........................................................450

솔루션 ......................................................450

토론 ........................................................452

11.3.2 AMASS를 이용한 JSON 문자열의 유지 ............................453

문제 ........................................................453

솔루션 ......................................................453

토론 ........................................................455

캐시 데이터의 변경 확인 .......................................456

11.4 요약 ........................................................457

12장 오픈 웹 API와 Ajax

Page 15: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

xv

12.1 야후 개발자 네트워크 ..........................................461

12.1.1 야후 지도 ...................................................461

문제 ........................................................462

솔루션 ......................................................462

토론 ........................................................466

12.1.2 크로스 서버 프록시 ...........................................466

문제 ........................................................467

솔루션 ......................................................467

토론 .......................................................475

12.1.3 야후 지도 지오코딩(Geocoding) .................................476

문제 ........................................................477

솔루션 ......................................................477

토론 ........................................................480

12.1.4 야후! 트래픽(Yahoo! Traffic) ....................................483

문제 ........................................................483

솔루션 ......................................................483

토론 ........................................................487

12.2 구글 검색 API ................................................490

12.2.1 구글 검색 ...................................................490

문제 .......................................................491

솔루션 ......................................................491

토론 ........................................................503

12.3 플리커 사진 ..................................................503

12.3.1 플리커 아이디 ................................................504

문제 .......................................................505

솔루션 ......................................................505

토론 ........................................................508

12.3.2 플리커 사진과 썸네일 .........................................509

문제 .......................................................509

솔루션 .....................................................509

토론 ........................................................514

12.4 기다려라! 그들이 말하길, 더 많은 것이 있다. .....................514

12.4.1 아마존(Amazon) 서비스 ........................................514

12.4.2 이베이(eBay) 서비스 ..........................................515

Page 16: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

xvi

12.4.3 맵퀘스트(MapQuest) ..........................................515

12.4.4 NOAA/국립 기상정보 서비스 ...................................515

12.4.5 더, 더, 더... ...............................................515

12.5 요약 ........................................................516

13장 Ajax기반매시업(Mashup)제작

13.1 여행기록 공유 애플리케이션의 소개 .............................518

13.1.1 애플리케이션 목적 ............................................518

13.1.2 애플리케이션 개요 및 요구사항들 ...............................519

13.2 여행기록 공유 서비스의 데이터 파일 ............................520

13.2.1 어떤 형식을 사용해야 할 것인가? ...............................520

13.2.2 여행 데이터 형식 .............................................521

13.2.3 플리커 사진 세트 설정하기 .....................................523

13.3 TripomaticDigester 클래스 .....................................524

13.3.1 의존성 체크 ..................................................525

13.3.2 TripomaticDigester 생성자 .....................................526

13.3.3 여행 정보 해석하기 ...........................................527

13.3.4 관심 지점 로드하기 ...........................................529

13.3.5 요소 텍스트 수집하기 .........................................530

13.4 Tripomatic 애플리케이션 클래스 ................................531

13.4.1 Tripomatic 클래스와 생성자 ....................................532

13.4.2 컨텐트 요소 생성하기 .........................................535

13.4.3 여행 데이터 채우기 ...........................................538

13.4.4 지도 보여주기 ...............................................540

13.4.5 썸네일 로드하기 .............................................542

13.4.6 사진 보여 주기 ..............................................545

13.5 여행 기록 공유 애플리케이션 페이지 ............................546

13.5.1 trip-o-matic.html 문서 ........................................546

13.5.2 스타일과 함께 살펴보기. ......................................548

13.6 요약 .......................................................550

최신 뉴스 ...................................................551

찾 아 보 기 .........................................................552

Page 17: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

xvii

이 책은 Ajax 분야의 최고 베스트셀러였던 ‘Ajax 인 액션’을 저술한 데이브 크레인(Dave

Crane)과 6명의 저자들이 공동으로 집필한 Ajax 실용서이다. 데이브 크레인은 Ajax와

웹 어플리케이션 개발 분야의 저명한 저술자이자 개발자로서 지난 10년간 주로 Perl, 자

바 기반의 웹 개발을 해왔다. 이 책의 필자진은 ‘Prototype & Scriptaculous 인 액션

(위키북스, 2008)’, ‘jQuery in Action’을 저술한 Java Ranch(자바 개발 리소스 웹 사

이트)의 스탭인 베어 바이볼트(Bear Bibeault), 구글의 조드 손네벨드(Jord Sonneveld),

ClearNova사의 크리스 그레이(Chris Gray), JBoss의 제품 메니저 램 벤카타라맨(Ram

Venkataraman), 전 세계적으로 가장 널리 사용되는 오픈소스 프레임워크 중의 하나인

DWR의 제작자 조 워커(Joe Walker), 그리고 JavaServer Faces 기반의 오픈소스 프레임

워크인 ICEfaces의 개발자 테드 고다드(Ted Goddard)이다

저 자 에 대 해

Page 18: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

xviii

데이브 크레인이나 DWR의 제작자 조 워커(Joe Walker) 등 저명한 필자들의 글을 옮기게

되어 한편으로는 조금 부담스러웠지만, 매우 기쁜 마음으로 작업할 수 있었다.

이 책은 2006년 아마존의 컴퓨터 인터넷 부분 1위의 데이브 크레인의 ‘Ajax 인 액션’의

명성을 그대로 느낄 수 있는 책이다. 데이브 크레인이 Ajax 분야의 저명한 6명의 필자와

함께 저술한 이 책은 ‘Ajax 인 액션’과 달리 상당히 실질적인 문제들에 대한 해결책들을

담고 있다.

6명의 다른 저자들이 나누어 썼음에도 불구하고, 책 전체의 논지와 일관성이 매우 뛰어

나다. 특히, 소스코드에 불필요한 군더더기 없이 정말 필요한 최소한의 내용만을 기술하

고 있어 핵심을 파악하기에 좋다.

역자 역시 지난 몇 년간 Ajax 분야의 개발을 해왔고, 현재도 Ajax 기반의 솔루션을 제

작하는 일을 하고 있다. 이 지난 2년 동안 Prototype을 비롯하여 DWR 등 오픈소스 라이

브러리들을 많이 써왔는데, 실전에서 닥치는 문제들은 라이브러리 외적인 문제들도 상당

히 있었다. 이 책은 이러한 문제들을 체계적으로 정리하고 있다. 예를 들어, 웹 페이지의

상태의 유지 문제라든가, 히스토리 관리문제 등 실제 접했던 문제들을 명확하게 풀어주

고 있다.

가장 널리 사용되는 다양한 오픈소스 라이브러리들의 사용방법을 설명하고, 예제에 적

용하여 구현하고 있어 라이브러리 선택을 고민하는 독자들에게 적지 않은 도움을 줄 것

이다. 특히, Open API에 대한 소개와 실전에 바로 적용할 만한 예제와 코드들은 이 책의

제목대로 ‘프랙티스(Practice)’를 제공한다.

역자는 이 글을 옮기면서 Ajax 애플리케이션 개발 전체를 한번에 체계적으로 정리하는

느낌을 받았다. 독자 여러분도 역시 이 책을 통해 Ajax 전체를 정리하는 느낌을 얻기 바

란다. 자! 이제 실전 Ajax의 세계로 여행을 떠나 보자!

옮 긴 이 글

Page 19: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

xix

이 책을 옮기는 데 많은 분들이 수고해 주셨다. 오픈 API 부분을 맡아 초벌 번역을 해주

고 내용을 꼼꼼하게 챙겨준 김경윤 과장님, 전체적인 내용들을 리뷰해주신 김진수 차장님,

정위현, 심규봉, 이규범 대리님께 감사를 전한다. 그리고 내용의 어려운 부분에서 도움

을 주신 블루다임의 황원철 사장님, 응원을 아끼지 않았던 친구 김양욱에게 고마움을 표

하고 싶다. 바쁘신 시간을 쪼개어 공역에 참여해 주신 최용호 사장님에게 감사하며, 좋은

책을 옮길 기회를 만들어주시고 미진한 원고를 챙겨주신 위키북스 관계자 분들께도 감사

의 마음을 전한다. 그리고 마지막으로 아내 은정에게 언제나 감사하고 있다는 마음을 전

하고 싶다.

2007년 10월, 이승준

Page 20: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

xx

웹은 항상 혁신의 온상이었고, 그 짧은 역사를 통해 우리는 원래 발명자의 의도를 넘어서

다시 제안되고 재사용되는 많은 발명 사례들을 보아왔다. 네트워크 기반의 문서 검색 프

로토콜은 CGI(Common Gateway Interface)에 의해 무너져 내려, 데이터 베이스에서 가져

온 데이터를 전달하는 동적 생성 문서를 제공함으로써 전세계 어디서나 자신의 데이터에

온라인으로 접근할 수 있도록 해주었다.

HTTP 헤더는 상태정보를 유지 하지 않는 프로토콜(stateless protocol) 위에 사용자 세

션의 연속성을 제공하여, 상태 정보를 유지(stateful)하는 예약 시스템과 온라인 상거래와

같은 애플리케이션으로 가는 문을 열어 주었다.

암호화 레이어는 핵심 프로토콜 위에 세워져 새로운 온라인 상점의 고객들과 비즈니스

애플리케이션 사용자들에게 신뢰를 심어 주었다.

이것들은 웹의 사용 방법을 영원히 바꾸어 놓을 진짜 혁신적인 기술들이었다. 오늘날

서버 페이지, 세션, SSL은 평범한 부품이 되어 모든 웹 개발자의 도구를 구성하고 있고,

당연하게 받아들여지고 있다.

변혁의 발걸음은 여전히 가혹하다. 그럼에도 불구하고 새로운 웹 프레임워크가 실제

거의 매주 등장하고 있다. 최근 몇 년 사이 웹 개발에 불어 닥친 가장 큰 파괴적인 혁신은

Ajax이다. 이전의 모든 혁신을 통해 기본적인 웹 사용자 인터페이스–클릭, 요청, 응답,

새로고침–는 1999년 5월 마이크로소프트가 인터넷 익스플로러 5와 함께 조용히 소개한

XMLHttpRequest(XHR) 객체가 등장하기 전까지 사실상 크게 바뀌지 않았었다. 이것은

아웃룩 웹 액세스(Outlook Web Access) 메일 클라이언트를 위해 사용되었었다.

2005년 세계는 갑자기 흥분하고 주목하기 시작했다. 구글이 메일, 지도, 추천 애플리

케이션과 함께 그들의 깃발을 Ajax 돛대에 올렸다. 어탭티브패스사의 제시 제임스 가렛

트(Jesse James Garrett)는 이 새로운 것이 무엇인지, 그리고 이것을 가지고 무엇을 할 수

있는지, 우리들이 모여 정확하게 토론할 수 있도록 최초의 표제어 “Ajax”를 만들었다.

서 문

Page 21: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

xxi

이 기술은 마치 이름을 기다렸던 것 같다. 이름을 얻자마자 활발한 돌풍이 연속해서 일

어났고, 사람들은 Ajax라는 시대의 조류에 뛰어 들었다. Ajax가 새롭고 다른 웹 애플리

케이션 개발 방식으로 소개되었다. 새로운 필요성들이 제기되어, 지난 2년 동안 웹 개발

커뮤니티는 이 새롭고 마음을 들뜨게 하는 내용을 가지고 어떻게 할지, 일찍이 볼 수 없

었던 활발한 혁신들이 일어났다.

Ajax의 기반은 XMLHttpRequest 객체와 마찬가지로 서버 페이지, 세션 그리고 SSL

을 포용하고 있다. 웹 개발 커뮤니티의 집단적 무의식은 Ajax의 기반 기술에 대해 서로의

마음을 터놓았다. 그리고 이 기술을 사용할 때 발생하는 광범위한 이슈들에 대한 이야기

로 옮겨가고 있다.

이 이슈들에 대해 이야기하기 위해 우리는 ‘Ajax 인 프랙티스’를 쓰기로 했다. 이 책에

대한 우리의 미션은 Ajax를 바탕으로 자신만의 성공적인 Ajax 애플리케이션을 제작할

수 있도록 숙련된(너무 많이 숙련되지 않은) 웹 개발자들에게 도움을 주는 것이다.

이 책은 2세대 Ajax 책이라고 할 수 있다. 1세대 책이 Ajax가 무엇인지를 보여주었다

면 2세대 책은 Ajax를 가지고 무엇을 할 수 있는지 보여준다. 이 책은 Manning 출판사

가 스티브 벤필드(Steve Benfield)에게 Ajax에 대한 2세대 책의 편집을 맡아 줄 것을 부

탁하면서 시작되었다. 데이브 크레인(Dave Crane)의 유명한 저서 ‘Ajax 인 액션’의 후

속 편으로 기획한 것이다. 나중에 조드 소네벌드(Jord Sonneveld), 베어 바이볼트(Bear

Bibeault), 그리고 데이브 크레인이 여러분에게 이 책을 선사하기 위해 팀을 이루었다.

여러분이 서문을 다 읽었을 때 우리는 우리의 미션을 완수했으므로 뒷자리에 앉아 음

료수를 나눠 마실 자격이 있다고 생각한다.

우리가 쓰면서 즐겼던 것처럼, 여러분이 이 책을 읽으면서 즐기기를 바란다!

데이브, 베어 그리고 조드

Page 22: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

xxii

여러분이 가지고 있는 이 책은 실제 많은 전문가들이 참여하고 협력하여 만들어진 결과물

이기 때문에, 이 섹션은 항상 놀라우리만큼 긴 이름들의 목록을 포함하게 된다. 우리는 많

은 것을 배웠다. 비록 많은 시간을 키보드 앞에서 보내지만, 저자는 혼자 작업하지 않는다.

책이 최상의 상태가 되도록 하기 위해 매 단계마다 Manning 출판사의 발행인과 편집

자가 우리와 함께 작업했으며, 그들의 격려와 품질에 대한 고집과 세밀한 곳까지 챙겨

준 것에 감사드린다. 보이지 않는 곳에서 많은 사람들이 작업을 했으며 그들에게 이 자리

를 빌어 감사의 뜻을 전한다. 발행인 Marjan Bace 와 편집자 Mike Stephens과 Karen

Tegtmayer, Howard Jones, Liz Welch, Dottie Marsico, Katie Tennant, Mary

Piergies, Gabriel Dobrescu, Ron Tomich, 그리고 Olivia DiFeterici.

우리의 검토자들은 작업하는 동안 원고에 크고 작은 많은 공헌을 했다. 코드의 에러

를 잡아내고, 텍스트의 오타를 찾고, 어떻게 각 장을 구성할지 제안해 주었다. 원고는 여

러 번 검토되어 결과적으로 좋은 책이 만들어졌다. 바쁜 일정에도 불구하고 많은 시간

을 할애해 원고를 읽어준 다음 검토자들에게 감사를 전한다: Curt Christianson, Anil

Radhakrishna, Robert W. Anderson, Srinivas Nallapati, Ernest Friedman-Hill,

Jeff Cunningham, Christopher Haupt, Bas Vodde, Bill Fly, Ryan Lowe, Aleksey

Nudelman, Lucas Carlson, Derek Lakin, Jonas Trindler, Eric Pascarello, Joel

Webber, Jonathon Esterhazy, 그리고 Benjamin Gorlick.

이 책의 테크니컬 편집자 Valentin Crettaz에게 특히 감사의 말씀을 전한다. 그는 코

드를 확인하고 각 장들을 여러 번 다시 읽어가며 최종 검수를 진행했다. 그의 노력에 감

사 드린다. 마지막으로 테드 고다드, 크리스 그레이, 램 벤카타라맨, 그리고 조 워커에게

각 분야의 전문가로서 이 책을 위해 헌신한 가치 있는 공헌에 감사한다. 이 분들이 이번

프로젝트에 많은 협조를 해주신데 대해 감사를 전한다.

감 사 의 글

Page 23: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

xxiii

데이브 크레인(Dave Crane)

나의 동료인 Historic Futures의 Simon Warrick, Tim Wilson, Susannah Ellis,

Simon Crossley, Rob Levine, 그리고 Miles Wilson에게 이번 프로젝트에 보낸 지지에

감사를 전하고 싶다. 또 Skillsmatter의 Wendy, Nic, Graeme와 팀에게도 감사를 전한

다. 이 책에 대한 나의 생각을 다듬고 어떻게 써가야 할지에 대해 도움을 준 동료들, 그리

고 나의 재능 있는 학생들에게 감사한다. 끝으로 내가 두 권 이상의 프로그래밍 책을 동시

에 쓰는 동안 격려해준 Crane 가족들-Chia, Ben, and Sophie–에게 감사한다. 나의 어

머니, 아버지 그리고 고양이들, 늦은 밤 글을 쓰는 동안 내 랩탑 컴퓨터에서 나오는 뜨거

운 열기를 잘 견뎌준 점에 대해 감사 드린다.

베어 바이볼트(Bear Bibeault)

감사를 드려야 할 분들이 너무 많이 생각난다. 내가 책 쓰기에 관심을 가졌을 때 격려해준

javaranch.com의 친구이자 동료 직원들: Ernest Friedman-Hill, Ben Souther, Max

Habibi, Mark Herschberg 그리고 Kathy Sierra에게 감사한다. 특히 멋진 사이트를 만

들어 주시고 직원들에게 신뢰를 주신 javaranch.com의 사장님 Paul Wheaton에게 감사

드린다. 그리고 Manning 출판사에 나를 추천해 준 Eric Pascarello에게 감사한다. 내가

글과 코드를 쓰는 동안 나의 발 근처에서 친근감을 보여준 나의 개 Gizmo, Cozmo 그리

고 Little Bear, 특히 Cozmo는 내가 타이핑하는 동안 키보드를 눌러 이상한 글자들을 타

이핑하게 해준 점에 특히 감사한다. 편집자들의 친절에 감사 드린다. 그리고 긴 시간 동안

두 개의 책을 동시에 진행하면서 인터넷 익스플로러와 워드에 큰 소리치며 참아준 그리고

나의 노력에 격려를 아끼지 않았던 나의 파트너 Jay에게 감사한다.

조드 손네벨드(Jord Sonneveld)

작업 과정의 마지막 부분에 많은 짐을 짊어진, 나의 공저자 데이브와 베어에게 특별히 감

사를 전한다. 그들의 엄청난 노력이 없었다면 이 책은 만들어지지 못했을 것이다. 나의 부

모 그리고 조부모님, 내 첫 컴퓨터를 사주셔서, 그리고 내가 이 책으로 바쁜 동안 지지해

주셔서 감사 드린다. 마지막으로 내 UPS에 합선을 일으킨 나의 고양이, 그리고 UNIX를

파고 있는 존경스러운 여자친구 Mallory에게 감사한다.

Page 24: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

xxiv

Aajx가 웹 개발자들에게 사용자 중심의 인터넷 애플리케이션에 대한 가능을 제시하며 웹

개발 커뮤니티에 엄청난 반향을 몰고 왔다. 하지만, Ajax는 애플리케이션에 높은 수준의

복잡성과 정교함을 더 해준다. ‘Ajax 인 프랙티스’는 수많은 활용 기법과 개발자가 Ajax

솔루션을 개발하고자 할 때 직면하게 될 이슈들에 대한 많은 양의 재사용 가능한 코드를

제공함으로써, Ajax에 정면으로 태클을 걸고 있다.

Ajax 개요를 살펴본 후, 여러 가지 수행되는 예제들을 독자들이 가져다 쓰기 편하게 솔

루션 형식으로 보여준다.

독자들은 풍부한 사용자 인터페이스를 어떻게 구현할 수 있는지 배우게 될 것이다. 끌

어다 놓기, 네비게이션 제어, 이벤트 처리, 폼 입력 검증, 상태관리, Ajax 라이브러리 선택,

오픈 API와 인터페이스를 포함하여 다양한 기법들을 살펴보게 된다.

전통적인 활용서와 달리, ‘Ajax 인 프랙티스’는 각 기술들에 대한 깊이 있는 해설을 담

고 있고 개별 컴포넌트를 사용해서 강력한 솔루션을 구축하는 방법까지 알려준다. 이 책

에는 ‘매시업’을 설명하는 흥미로운 내용이 포함되어 있다. 이 책을 통해 흥미로운 예제들

과, 재미 그리고 그 이상의 ‘실용성’을 만날 수 있을 것이다. 여러분은 이 책을 통해,

Ajax를 넘어서 실전에 Ajax를 어떻게 활용할지 배우게 된다.

사용자 인터페이스와 사이트 네비게이션에 대한 다양한 기술들을 소화하게 된다.

전문적인 수준의 재사용 가능한 Ajax 코드로 실전 문제들에 대한 솔루션을 설계해 보자.

이 책의 독자

이 책은 Ajax 기술을 활용하여 만드는 애플리케이션이 최고 수준의 사례가 되길 원하는

웹 개발자를 대상으로 하고 있다. Ajax를 처음 시작하는 독자들은 처음 두 개의 장을 통

해 비동기 요청(asynchronous request)의 세계에 입문하는데 도움을 받을 수 있을 것이다.

이 책은 최소한 기본적인 웹 애플리케이션 개발 지식을 가지고 있고 자바스크립트를 사

용하여 클라이언트 코딩을 해본 개발자들을 대상으로 하고 있다. 풍부한 사용자 인터페

이 책 에 대 해

Page 25: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

xxv

이스의 새로운 세계에서, 클라이언트 측 코드는 크게 증가하므로 서버와 거의 동일한 수

준의 관리 방법이 동원되어야 한다. 이 책에서 소개하는 고급 자바스크립트 기술들은 클

라이언트 코드를 조직화하고 Ajax를 효과적으로 사용하는 데 도움을 줄 것이다.

만일 독자 여러분이 자신의 코딩 기술을 확장하려는 웹 개발자라면 새로운 기술뿐만 아

니라, 이 기술들을 제대로 잘 활용하기 위한 디자인 패턴(design pattern)에도 관심을 가

지기 바란다. 이 책을 읽어가면서 이러한 필요성을 발견하게 될 것이다. 여러분이 숙련된

개발자이건 혹은 이제 막 웹 애플리케이션의 풍부한 사용자 인터페이스를 시작하는 개발

자이던, 이 책이 여러분에게 뭔가 특별한 것이 되기를 희망한다.

로드맵

이 책은 크게 두 개의 부분을 나뉘어 있다. 1부는 ‘Ajax 기본’은 2부 내용을 최대한 잘 활

용하기 위해 필요한 내용을 담은 4개의 장으로 구성되어 있다. 2부 ‘Ajax 실전 사례’는 클

라이언트 측 프로그래밍을 위한 다양하고 실무적인 주제들을 다루고 있다. Ajax를 직접

활용하는데 초점을 맞추고 있으며, Ajax 애플리케이션에서 잘 동작하는 실질적인 예제와

동작하는 원리를 설명하고 있다.

1장은 Ajax가 다른 기술들과 어떻게 다른지부터 설명하고 있다. 다양한 브라우저들에

서 Ajax를 사용하기 위한 접근법을 설명하고, Ajax가 생성하는 응답을 어떻게 다루는지

살펴본다. 마지막으로 Prototype 라이브러리를 활용하여 훨씬 더 견고하게 만드는 방법

도 간략하게 살펴본다.

2장에서는 JSON, XML, XSLT를 포함하는 다양한 Ajax 통신 방법을 검토한다. 또,

SOAP 웹 서비스를 Ajax로 이용하는 방법을 면밀하게 조사할 것이다.

3장은 객체지향 자바스크립트의 개념을 소개한다. 전형적인 Ajax 애플리케이션을 포

함해서 양이 많아지는 클라이언트 측 코드를 관리하는 데 적용할 수 있다. 객체지향의 주

요한 개념들인 객체 생성, 퍼스트 클래스로서의 함수, 클래스 메서드로서의 함수, 함수

컨텍스트 그리고 클로저에 대한 설명을 객체지향 기술과 연관 지어 설명한다. 3장의 마지

막 부분에서 Prototype 라이브러리를 사용하여 손쉽게 자바스크립트 클래스를 생성하는

방법도 살펴본다.

4장에서는 Ajax 자바스크립트 라이브러리인 Prototype, Dojo 툴킷, jQuery 그리고

DWR에 대해 자세히 알아 본다. 이 라이브러리가 제공하는 모든 기능을 다 설명하지는

Page 26: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

xxvi

못하지만, Ajax를 활용하는데 특별히 관심을 가지고 봐야 할 부분들을 집중적으로 다룬다.

각 라이브러리들을 실제 적용하는 예제들도 함께 살펴본다.

5장에서는 이벤트 처리에 대한 내용을 살펴본다. 다양한 이벤트 모델을 브라우저 간

호환성 이슈와 함께 살펴보고 Prototype 라이브러리를 활용하여 어떻게 호환성을 지원

하는지 알아본다. 가장 널리 사용되는 이벤트 타입들에 대해 알아보고, 이벤트 타입들이

Ajax 애플리케이션에 어떻게 적용되는지 논의한다.

6장에서는 폼의 데이터 입력 검증과 5장에서 알아본 이벤트 처리를 어떻게 결합하는지

살펴본다. Prototype과 jQuery 라이브러리를 이용하는 장점을 최대한 살린 예제를 선보

이는데, 전체 페이지를 ‘새로고침’ 하지 않도록 하기 위해 폼 전송을 가로채서 Ajax 요청

으로 전송하는 방법을 살펴본다.

7장에서는 컨텐트 네비게이션에 대해 알아본다. 간단한 메뉴를 만들어 보고, 보다 정교

한 네비게이션을 위해 트리뷰, 아코디언 컨트롤, 탭뷰 그리고 툴바를 적용한다. 이 장에

서는 OpenRich와 qooxdoo 라이브러리를 활용한다.

8장은 뒤로가기와 새로고침을 할 때 발생하는 필드에 관한 문제를 다룬다. 이런 기능을

제거하고 동일한 기능을 제공한다. 8장에서는 애플리케이션에 실행취소(undo) 기능을

추가하는 방법도 함께 살펴본다.

9장에서는 끌어다 놓기 조작을 구현한다. 끌어다 놓기 조작의 순서를 살펴보고 자바스

크립트 라이브러리를 활용하여 어떻게 이 기능을 지원할지 알아본다. Script.aculo.us를

사용하여 목록을 조작하는 방법을 알아보고 Script.aculo.us와 ICEfaces를 사용하여 장

바구니를 구현해 본다.

10장에서 네트워크 지연 이슈와 관련하여 Ajax를 사용하여 사용성을 개선하거나 최소한

사용자의 불편을 경감할 수 있는 방법에 대해 토론한다. 서버의 도움을 받아 사용자에게

미리 도움말을 제공하고 폼 검증을 수행하는 방법을 알아본다.

11장은 상태관리에 대한 것이다. 클라이언트 상태관리를 어떻게 하는지 살펴보고, 데이

터를 미리 가져오는 방법과 클라이언트 상태를 저장하는 방법을 탐험한다. 또, AMASS

라이브러리를 사용하여 대량의 데이터를 다루는 방법도 살펴본다.

12장에서는 오픈 API의 세계에 대한 조사를 한다. 다른 원격 서버에 요청을 전송하기

위해 ‘Ajax 보안 샌드박스’ 문제를 어떻게 피해갈 수 있는지 살펴본다. 야후 지도, 지도

Page 27: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

xxvii

코딩, 트래픽 그리고 구글 검색엔진, 플리커 사진 서비스와 같은 오픈 API 사용법에 대해

알아본다.

13장은 이 책의 하일라이트 부분인데 12장에서 공부한 내용을 적용하여 오픈 API를 적

용한 ‘매시업’ 애플리케이션를 어떻게 제작하는지 살펴본다. 또, 이 책에서 소개한 모든

기법을 동원하여 실제 동작하는 완전한 매시업 애플리케이션을 제작해 본다.

코드 다운로드

이 책의 동작하는 예제 소스 코드는 http://www.manning.com/crane2 혹은 위키북

스 홈페이지 http://wikibook.co.kr에서 다운로드 할 수 있다.

저자 온라인

‘Ajax 인 프랙티스’를 구매한 독자들은 자유롭게 Manning 출판사에서 제공하는 포럼

에 접근할 수 있다. 여기에 책에 대한 댓글을 남길 수 있으며 기술적인 질문도 할 수 있

고 저자와 다른 독자들에게 도움을 받을 수도 있다. 포럼에 가입하려면 브라우저에서

http://www.manning.com/crane2 혹은 http://www.manning.com/AjaxinPractice

를 방문하여 등록하면 된다. 그러면, 관련 도움말 포럼의 운영 등에 대한 정보를 얻을 수

있다. Manning은 독자들 사이에 그리고 독자와 저자 사이에 의미 있는 대화가 이루어질

수 있도록 하고 있다. 책의 포럼에 대한 기여는 자원봉사로 이루어진다. 저자들이 관심을

잃지 않도록 저자들에게 도전적인 질문을 하기 바란다. 저자 온라인 포럼과 이전 토론 내

용은 출판사의 웹 사이트에서 찾아 볼 수 있다.

위키북스 오픈소스 & 웹 시리즈 에디터 일래스틱 온라인 ㅣ http://web2.0business.or.kr/

위키북스 오픈소스 & 웹 시리즈 에디터인 일래스틱의 ‘http://web2.0business.or.kr/

category/위키북스시리즈’에서도 관련 내용을 계속 업데이트할 예정이다.

Page 28: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

xxviii

‘Ajax 인 프랙티스’의 표지의 그림은 술탄 왕가의 여성 구성원인 ‘술타나(Sultana)’이다.

그의 아내와 어머니가 그러한 이름으로 명명되었을 것이다. 그림은 런던 올드 본드의 윌

리엄 밀러(William Miller)가 1802년 1월 1일에 출간한 오스만 제국(Ottoman Empire)의 의

상 컬렉션에서 인용한 것이다.

이 컬렉션 표지가 손실되어 지금까지 발견되고 있지 않다. 이 책의 목차는 영어와 불어

로 쓰여 있으며, 모든 그림을 작업한 두 명의 아티스트들의 이름이 기술되어 있고, 두 명

모두 컴퓨터 프로그래밍 책의 표지를 장식했다는데 놀랄 것이다… 2백 년이 지난 후에.

이 컬렉션은 Manning 출판사의 한 편집자가 맨하탄 웨스트 26번가 게러지(Garage)에 있

는 골동품 벼룩시장에서 구매한 것이다. 판매한 사람은 터키 앙카라 출신 미국인이었으며

거래는 그날 당일 이루어졌다. Manning의 편집자는 개인적으로 그 책을 구매하기에 충분

한 현금을 가지고 있지 못했으며 신용카드나 수표는 사용할 수 없었다.

판매자가 앙카라로 돌아가려 하는 상황이었고, 저녁때 상황은 더욱 안 좋아졌다.

해결책이 뭐였을까? 구두로 약속하고 악수로 도장 찍는 낡은 방식이 최선의 방책이었다.

판매자는 나중에 돈을 송금해줄 것을 제안했고, 편집자는 계좌 번호를 적고, 컬렉션을 들

고 나왔다. 물론 다음날 돈을 부쳤다. 우리는 기뻤고, 낯선 사람에게 신뢰를 보여준 이름

모를 사람에게 깊은 인상을 받았다.

이 컬렉션은 아주 오래 전의 있었던 일을 회상하게 한다.

표지의 다른 그림들과 마찬가지로 오스만 컬렉션에서 인용한 이 그림은 2백년 전 부유

하고 다채로웠던 의상을 보여준다. 이 그림들은 우리의 너무나 바쁜 일상과 동떨어진 시

간의 거리를 느끼게 해준다. 그토록 풍요로웠던 시대가 지난 후, 의상 코드는 지역마다

다르게 변하고 사라졌다. 이제는 한 대륙의 사람을 다른 대륙의 사람들과 구분하기 어렵

다. 좀 더 긍정적으로 생각해 본다면, 우리는 좀 더 다양한 개인의 삶을 위해 혹은 다양하

표 지 그 림 에 대 해

Page 29: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

xxix

고 흥미로운 지적, 기술적 생활을 위해 문화와 시각적인 다양성을 교류하고 있는 것이다.

우리는 이 컬렉션의 그림을 가져와 생기를 불어 넣었다-2세기 전 특정 지역의 풍요로

운 다양성을 보여주는 책의 표지를 통해 창의성, 통찰 그리고 컴퓨터 비즈니스의 재미를

세상에 알리고자 한다.

Page 30: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

01부

1장 기존에 사용되고 있는 기술들과 Ajax가 어떻게 다르며, 이 책의 나머지

장들에서 다룰 내용이 무엇인지를 설명한다. 그리고 여러 종류의 브라우저에

서 Ajax를 어떻게 사용할 수 있으며, 자바스크립트 코드에서 비동기 응답

(asynchronous response)이 어떻게 처리되는지를 논의한다. 또한 널리 사용되

고 있는 자바스크립트 라이브러리인 Prototype을 잠깐 살펴볼 것이며, 이 책에서

는 여러 장에 걸쳐 Prototype이 계속 나올 것이다.

2장 Ajax 요청으로 생성될 수 있는 응답 형식들인 평문(plain text), HTML,

JSON(JavaScript Object Notation), XML, SOAP 문서를 살펴본다.

3장 Ajax 개발자라면 모두가 알고 있어야 하는 자바스크립트 고급 기법을 분석

한다. 자바스크립트 객체와 함수를 살펴보고, 이들 객체와 함수를 사용해서 자바

스크립트 클래스를 어떻게 생성할 수 있는지 그 방법을 설명한다. 이와 같이 객체

지향 기법의 사용에 관련된 내용을 설명하는 이유는 Ajax에서 요구되고 있으면서

Page 31: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

Ajax 기초

그 사용량이 급격히 늘어나고 있는 클라이언트 측 코드를 자유자재로 구사할 수

있기 위해서다. 또한 3장을 읽으면서 자바스크립트 함수가 얼마나 많이 복잡하며,

일반적으로 알려진 것보다 얼마나 다양한지를 알게 될 것이다.

4장 Ajax가 지원하는 다양한 자바스크립트 라이브러리들을 살펴본다. 먼저 오

랫동안 사용되고 있는 Prototype 라이브러리들을 비교적 자세히 설명하고, 다용

도로 사용되는 Dojo 툴킷을 살펴본다. 그리고 Ajax 분야에서 새로운 열풍을 일으

키고 있는 jQuery를 소개한다. 마지막으로, DWR 프레임워크에서 Ajax를 전송

메커니즘으로 사용하여 RPC(remote procedure calling)와 유사한 기능을 어떻게

이루는지 그 방법을 보여준다.

이 책의 기획 의도는 Ajax 웹 애플리케이션을 심도 있게 살펴보는 것이다. 이와 관련하여 본문에서는 실제 코

딩에 재사용할 수 있는 예제를 많이 제시할 것이며, 이들 예제를 통해서 실제 애플리케이션에 활용할 수 있는

실용 기법을 설명할 것이다. Ajax 세계로의 놀라운 여행을 시작하려면 1부의 여러 장들을 자세히 학습해야 하

며, 1부는 2부를 학습하기 위한 준비 과정에 해당한다.

Page 32: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

2

Page 33: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

3

Ajax를 포용한 개발자들

: Ajax의 고유한 특징

: XMLHttpRequest의 기본 활용

: 라이브러리를 활용하여 Ajax 단순화하기

01장

Page 34: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

Ajax 기초1부

Ajax는 2006년부터 급격히 성장해 왔다. 이 책을 집필하고 있는 지금, Ajax가 그 모습을

세상에 드러낸 지 이미 1년 반이 되어가고 있다. 물론 상당수의 기본 기법은 수년 전부터

사용되고 있었지만 이들 기술이 하나의 통합된 이름으로 불려진 것은 2년이 채 되지 않는

다. Ajax의 태동에 관련된 이야기는 Microsoft Web Outlook의 XMLHttpRequest라고

하는 ActiveX 컨트롤로 거슬러 올라가며, 2005년 2월 제시 제임스 가렛이 Ajax라는 용어

를 처음으로 만들어내기까지 Ajax 관련 기술들에 대한 이야기는 이미 여러 번 회자되었다.

최근 들어서는 구글의 추천(Suggest), 메일(Gmail), 지도(Maps) 애플리케이션에 집중적으

로 사용되면서 이들 기술에 대한 관심이 폭발적으로 증가하였다.

현대 세계에서 모든 아이들은 계속해서 자라며, 아이들의 이러한 성장에는 가끔씩 고

통이 따르기 마련이다. 이와 마찬가지로, 현재 우리가 보는 Ajax도 1년이나 반년 전에 보

았던 모습과는 많이 달라져 있으며, 그 이면에는 성장통이 뒤따랐다. 지금, Ajax 기술은

성숙되었다. 일례로 Ajax 기술을 논의할 때 나오는 용어가 성숙해졌으며, Ajax 개발 업

무에 사용할 수 있는 툴들 역시 완숙한 상태에 이르렀다. Ajax의 이러한 성숙도를 1.4절

에서 확대하여 논의할 것이며, 4장에서는 Ajax를 더 쉽게 사용할 수 있게 하는 새로운 종

류의 프레임워크와 라이브러리들을 심도 있게 살펴볼 것이다.

Ajax의 성숙으로 인해 일어난 가장 큰 변화는 Ajax로 무엇을 할 수 있는지에 대한 개

발자들의 이해력이 늘어났다는 점이다. 개발자들은 “Ajax로 무엇을 할 수 있지?”와 같

은 기본적인 질문을 넘어서 더 깊고 폭넓은 쟁점에 대해 고민하고 있다. 가령, 개발자들

은 이제 “비동기 통신을 어떻게 관리할 수 있을까?”, “지금 내가 만들고 있는 애플리케이

션 아키텍처에 Ajax를 활용하면 어떤 영향이 미칠까?”, “Ajax를 우리 회사의 사업 모델

에 어떻게 활용할 수 있을까?”와 같이 진보된 새로운 질문들을 스스로에게 던지고 있다.

결론적으로, 개발자들은 Ajax를 포용하였으며, 최고의 발명품인 것처럼 새롭고도 흥미

로운 방식으로 Ajax를 사용하고 있다. Ajax를 활용하여 온라인 지도(online map)와 웹메

일(webmail)을 성공적으로 사업화한 구글은 근본적인 혁신을 가져올 많은 프로젝트를 계

속 진행하고 있다. 최근에 관심을 끌고 있는 매시업(mash-up: 여러 웹 사이트에 있는

컨텐트를 1개의 페이지로 믹싱하는 것) 역시 Ajax와 태생적으로 가까운 관계에 있다.

필자들은 실무에서 애플리케이션을 개발할 때 Ajax를 활용하였으며, 이때의 실제 경

험을 축적해왔다. 이 책을 저술한 목적은 우리가 현업에서 축적한 Ajax 관련 실무 경험

을 선별하여 보여주는 것이며, 이를 위하여 개념 증명에 필요한 기본 코드들을 제시하면

Page 35: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

Ajax를 포용한 개발자들 1장

서 실제 개발에서 Ajax로 무엇을 할 수 있고, 또 무엇을 할 수 없는지를 보여주고자 한다.

이 책에서는 현재 Ajax와 관련하여 제기되고 있는 심도 있고 폭넓은 질문들을 중점적으

로 다룰 것이다.

1.1 혁신 기술로서의 Ajax

Ajax는 혁신적인 기술이다. 즉, Ajax가 출현하면서 기존에 통용되던 온라인 애플리케이

션의 제작 및 배포 방법에 일대 혁신이 일어나고 있으며, 웹 애플리케이션에 대한 일반인

들의 인식 방법과 활용 방안도 변하고 있다.

가장 좁은 의미에서 볼 때 Ajax가 하는 일은 단순히 ‘서버로 비동기 요청을 보내는 것’

이다. 비동기(asynchronous)라는 것은 요청이 이루어질 때 사용자 인터페이스는 아무런

영향을 받지 않고, 요청이 백그라운드에서 처리된다는 것을 의미한다. Ajax 애플리케이

션을 코딩할 때 서버로의 비동기 호출 작성 및 응답 처리에 많은 시간을 들이지 않고, 나

머지 시간에 CSS(Cascading Style Sheet), DOM(Document Object Model), 브라우저 이

벤트 모델과 같은 안정된 기술을 사용한다. 요약하면, Dynamic HTML이라고 하는 기

술을 사용하고 있으며, 이 기술은 2년 전에 실제로는 사장되어서 화려한 네비게이션 메

뉴와 팝업 광고 창 제작용으로만 사용되었다. 그러나 비동기 HTTP 기능이 추가되면서

Dynamic HTML 기술에 새로운 활력을 불어넣게 됨에 따라, 널리 사용할 만한 새로운

이유를 갖게 되었다. 그다지 많지 않은 Ajax 기술이 이렇게 큰 반향을 일으키는 이유가

무엇인가? 답은 의외로 간단하며, 2장에서 그 답을 볼 것이다.

1.1.1 사용자의워크플로우재정의

웹 개발에서 Ajax가 만들어낸 영향력을 이해하는 열쇠는 사용자 워크플로우(user workflow)

에 있다. 워크플로우는 사용자가 애플리케이션과 상호 작용하는 방법을 의미하며, 더 넓

은 의미에서 보면, 애플리케이션에 대한 사용자의 경험이라고 볼 수 있다. 일반적으로 브

라우저와 서버 사이에서 작업을 분할한다, 라는 관점에서 웹 애플리케이션을 이야기하지만,

간단하게 말해서 웹 애플리케이션은 사용자의 머리 속에서 예견되는, 즉 다음에 진행되었

으면 하는 중요한 일을 돕는 것 같지만 실상은 방해하는 역할을 맡고 있다. 좋은 애플리케

이션은 사용자의 작업 패턴을 지원하여 사용자의 생산성을 높이지만, 애플리케이션 자체

에 기술적인 한계가 있어서 이 한계를 기반으로 사용자의 작업을 지시한다면, 그 애플리

Page 36: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

6

Ajax 기초1부

케이션은 결국 사용자의 생산성을 저하시킨다. 그림 1.1은 Ajax가 도입되기 전의 전통적

인 웹 애플리케이션에서 워크플로우가 어떻게 진행되는지를 보여준다.

그림 1.1의 워크플로우는 작업-대기(work-wait) 패턴을 따른다. 즉, 시간 흐름상 어느

시점에서 브라우저 측 애플리케이션은 사용자에게 정보를 제시하거나 서버로부터 응답이

반환되기를 기다리며 대기한다. 사용자 관점에서 볼 때 사용자는 작업 흐름이 매우 자주

끊어지는 것을 경험한다. 사용자는 대기하는 중에 웹 애플리케이션과 상호 작용할 수 없

으며, 할 수 있는 것이라고는 곧 이루어질 서버 응답에 의해 다른 내용으로 채워질 현재

페이지의 내용을 읽는 것밖에 없다.

그림 1.1 전통적인 웹 애플리케이션에서의 사용자 상호 작용 모델인 작업-대기 패턴

유용성 관점에서 볼 때 이 방식에는 문제가 매우 많다. 각 대기 시간동안 사용자의 연

속적인 생각은 중단된다. 또, 아직까지는 대기 시간이 자주 발생할 수밖에 없다. 왜냐하

면 대다수의 웹 애플리케이션은 서버와 자주 접촉해야 할 것이기 때문이다. 브라우저 기

반 애플리케이션에 많은 장점이 있는 것은 사실이다. 그럼에도 불구하고 복잡한 문제를

해결해야 하는 작업에는 이 모델이 매우 부적절하다. DHTML에는 편이성과 응답성이 높

은 사용자 인터페이스 구현에 필요한 모든 요소가 들어 있으며, 아마도 DHTML을 활용

하기만 하면 클라이언트 머신에 다른 것을 설치하지 않고도 웹 애플리케이션의 배치와

유지보수를 매우 쉽게 처리할 수 있을 것이다.

그림 1.2에서는 Ajax를 활용할 경우 사용자 워크플로우가 어떻게 바뀌는지를 보여준

다. 애플리케이션이 앞에서와 동일한 요청을 서버로 보내지만, 여기서는 이 요청을 Ajax

로 처리한다. 이렇게 Ajax로 처리하면 서버가 작동하는 동안 사용자 인터페이스는 액티

브 상태를 계속 유지하므로 사용자의 작업 흐름이 자주 끊어지는 현상은 없어진다.

대기

작업 작업 작업

브라우저

작업

서버

대기

작업 작업 작업

브라우저

작업

서버

Page 37: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

7

Ajax를 포용한 개발자들 1장

그림 1.2 Ajax 애플리케이션에서의 사용자 상호 작용 모델인 작업-작업 패턴

비즈니스 관점에서 볼 때 이 방식의 중요성을 작다고 말할 수 없다. Ajax는 웹 개발뿐

만 아니라 씩 클라이언트(thick client) 1 의 데스크톱 애플리케이션 분야에도 혁신을 가져

왔으며, 브라우저 기반의 애플리케이션 관련 시장을 새롭게 열었다. 기업에서의 Ajax 기

반 솔루션 채택이 늘고 있다. 그리고 작년에는 공개 인터넷에서 돌아가는 중량급의 Ajax

기반 사무용 애플리케이션이 여러 개 개발되었으며, 웹 기반 OS도 개발되고 있다. 이러

한 것들이 아직 주류로 자리를 잡지는 않았지만 개발 진행 속도는 매우 빠르다.

이렇게 해서 Ajax는 애플리케이션 시장에서 의미 있는, 즉 혁신적인 결과를 가져왔으며,

이것은 개발자들에게 있어서 도전이요 기회로 다가왔다. 그러나 전문적인 기술 영역에서

볼 때 Ajax의 혁신성을 다른 곳에서 찾을 수 있으며, 이에 대해서는 다음 절에서 논의할

것이다.

1.1.2 웹애플리케이션아키텍처재정의

웹 애플리케이션 아키텍처는 항상 흥미로운 분야였다. 작업-대기라는 웹의 기본적인 환경

에서 사용자의 워크플로우를 적절하게 유지해야 하기 때문에 서버에서 웹 애플리케이션을

체계화하는 방법은 지속적으로 발전해 왔다. 그래도 비즈니스 계층(business tier)과 프리젠

테이션 계층(presentation tier) 사이에는 어떤 규약 같은 것이 정해져 있어서 각 계층이 책

임지고 처리할 일이 구분되어 있었다. 그림 1.3은 기존의 웹 애플리케이션 아키텍처가 어떻

게 설계되었는지, 또한 이 설계에 Ajax가 적용되면 어떤 영향이 미치는지를 보여준다.

1 씩 클라이언트(thick client): 일반적으로 웹 브라우저 자체 혹은 웹 브라우저 상에서 HTML과 JavaScript만으로 수행되는 클라이언트 애플리케

이션을 씬 글라이언트(thin client)라고 한다. 이와 달리 풍부한 기능을 가진 설치형 클라이언트 프로그램을 씩 클라이언트(thick client)라고 하는데,

비주얼 베이직이나 파워빌더로 제작한 클라이언트 프로그램이 대표적인 예이다.

작업 작업

브라우저

서버

작업 작업

브라우저

서버

Page 38: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

8

Ajax 기초1부

그림의 좌측에 있는 것은 Ajax가 적용되지 않았을 때의 아키텍처로서, 여기에서 모든

행위는 서버에서 일어나며, 브라우저는 단순한 단말기의 역할을 수행하면서 HTML 컨텐

트만을 받는다.

중간 그림은 애플리케이션에 비교적 간단한 Ajax를 넣었을 때 어떤 효과가 발생하는지

를 표현하였다. 여기서도 서버가 여전히 모든 워크플로우를 제어한다고 볼 수 있지만, 하

이퍼링크와 폼이 화면 전체를 ‘새로고침(refresh)’ 하지 않고 일부 화면의 업데이트에 사용

된 HTML 컨텐트만을 요청한다. 서버에서 온 응답은 자바스크립트 코드에 의해 처리되

는데, 자바스크립트는 응답을 읽고, DOM을 적절하게 재정렬한다. 그림을 보면 브라우저

의 프리젠테이션 계층이 왼쪽 그림보다 조금 더 두꺼워졌음을 알 수 있다. 그 이유는 서

버에서 수신된 HTML 컨텐트를 처리하기 위하여 자바스크립트가 추가되었기 때문이다.

이에 반해서, 서버의 프리젠테이션 계층은 조금 더 얇아졌다. 왜냐하면 서버에서는 매번

전체 페이지를 조립하지 않고 간소화된, 꼭 필요한 응답만을 만들기 때문이다.

그림 1.3 n 계층 웹 애플리케이션의 설계 아키텍처와 Ajax 도입시 아키텍처에 미치는 영향

코딩이 잘 되어 있는 기존의 웹 애플리케이션은 응답을 모듈식으로 생성할 것이므로,

Ajax 기능을 일부 넣는다고 해서 코드를 전체적으로 다시 작성하는 일은 없을 것이다. 그

러나 시간이 지나면서 서버 요청과 응답의 패턴이 변할 가능성이 있으므로, 브라우저에 새

Ajax 도입 전 간단한 Ajax 도입 Ajax 애플리케이션

프리젠테이션

프리젠테이션 프리젠테이션 프리젠테이션

프리젠테이션 프리젠테이션

데이터베이스

도메인 모델 도메인 모델 도메인 모델

도메인 모델

퍼시스턴스 퍼시스턴스 퍼시스턴스

브라우저

서버

Ajax 도입 전 간단한 Ajax 도입 Ajax 애플리케이션

프리젠테이션

프리젠테이션 프리젠테이션 프리젠테이션

프리젠테이션 프리젠테이션

데이터베이스

도메인 모델 도메인 모델 도메인 모델

도메인 모델

퍼시스턴스 퍼시스턴스 퍼시스턴스

브라우저

서버

Page 39: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

9

Ajax를 포용한 개발자들 1장

로운 프리젠테이션 계층을 도입해야 하며, 여기에 자바스크립트를 사용하면 된다. Ajax를

이와 같은 방식으로 도입하면 개발 팀은 혼란에 빠지지 않을 것이며, 개발자들은 다시 한

번 생각을 하게 될 것이고, 새로운 기술들을 점차 받아들일 것이다.

Ajax에 의존하는 비율이 점점 높아지면서 새로운 사업군의 웹 애플리케이션에서 Ajax

를 허용하는 움직임이 나타나고 있으며, 이로 인해 아키텍처상에서 계층의 변경 범위가

늘어나고 있다. 그림 1.3의 오른쪽 그림에서는 Ajax 기반 애플리케이션이 최대한으로 활

용되는 것으로 묘사되고 있으며, 여기서는 브라우저의 자바스크립트 코드가 매우 복잡해

져서 그 자체를 별도의 계층으로 분리해 놓았다. 이 경우에 클라이언트 측 프리젠테이션

계층은 사용자의 워크플로우를 통제한다. 또한 클라이언트 측 코드는 주요 도메인 엔티

티의 일부 모델을 유지하며, 따라서 자바스크립트 프리젠테이션 계층은 서버와 직접 통

신하지 않고 도메인 엔티티들과 통신할 것이다.

그림에서 서버 측의 프리젠테이션 계층이 많이 줄어든 것을 알 수 있다. 서버 측 프리

젠테이션 계층의 핵심 기능은 애플리케이션의 주된 유스 케이스(use case)를 정의하는 도

메인 모델의 상단에 위치하여 단순한 외부 인터페이스를 제공하는 것이다. 또한 서버 측

프리젠테이션 계층은 HTTP 인터페이스를 지나다니는 데이터의 마샬링(marshaling)과 언

마샬링(unmarshaling)을 제어한다. 그리고 흐름 제어와 컨텐트의 시각적인 표시는 클라

이언트 측 자바스크립트 계층에게 대폭 맡겨졌다.

모든 Ajax 애플리케이션이 이 방법을 완벽하게 따르지는 않을 것이며, 그렇게 하는 것

이 적절하지도 않다. 웹 애플리케이션의 아키텍처에 관련된 문제가 명쾌하게 확정되어서

해결되지 않았다는 이야기를 언급한 바 있으며, 따라서 개선해야 할 문제점이 아직도 많

이 남아 있다. Ajax가 모든 환경에 적용될 수 있는 유일한 솔루션을 제공하기보다는 새로

운 방향으로 개선시켜 나감으로써 웹 아키텍처 지형을 혁신시켰다. 그림 1.3은 연속적으

로 이어져 있는 하나의 스펙트럼 상에서 세 개의 지점을 제시하고 있다. 이 그림을 근거

로 볼 때, 기존의 애플리케이션에 약간의 Ajax 기능이 강화되었다면 이 애플리케이션은

중간 지점에 더 가까이 있는 것이 되고, 기업에 중요한 LOB(line-of-business) Ajax 애플

리케이션이라면 우측으로 더 붙어 있을 것이다.

지금까지는 이 책이 전반적으로 어떤 내용을 담을 것인지 살펴보았으며, 뒤에 나오는

예제를 통해서 관련 내용을 계속 설명할 것이다. 이제 첫 번째 코딩 연습에 들어갈 것이며,

여기서 Ajax 요청이 어떻게 만들어지는지 볼 것이다. 일단 몇 가지 쟁점 사항, 즉 자바스

Page 40: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

�0

Ajax 기초1부

크립트나 HTTP와 같은 핵심 기술이 함께 어우러지는 방법을 강조하기 위해서라도 한 번

쯤 코딩 연습을 진행하는 것이 필요하다. 그 후에 라이브러리를 통해서 낮은 수준의 기능

을 속도감 있게 조금 살펴볼 것이며, 그 다음에 더 높은 수준의 주요 사안으로 넘어갈 것

이다. 먼저 XMLHttpRequest와 이것으로 무엇을 할 수 있는지 살펴보자.

1.2 Ajax의 기본 특징

Ajax가 어떻게 작업을 수행하는지 그 방법을 이미 잘 알고 있다면 1장을 그냥 넘어가도

괜찮다. 그렇지 않거나 한 번 더 생각을 되짚어 보고 싶을 경우, 1장을 읽는다면 Ajax 애

플리케이션 코딩에 필요한 핵심 기능들을 이해하게 될 것이다. Ajax가 하나의 특정 제품

은 아니다. 그리고 브라우저에도 Ajax에 관련된 특정한 기능이 있지도 않다. 그 대신에 1

장을 읽으면 알겠지만 Ajax는 자바스크립트 이벤트와 DHTML(dynamic HTML; DOM

manipulation이라고도 함)이 결합된 XMLHttpRequest라고 하는 자바스크립트 객체를

사용한다. 이 절에서는 XMLHttpRequest 객체를 잠깐 살펴볼 것이고, 이것의 기본 능력

을 파악할 것이다.

1.2.1 XMLHttpRequest소개

전통적인 웹 애플리케이션을 코딩할 때 브라우저와 서버 사이의 통신에 HTTP 프로토콜

을 사용한다. 이 때 사용자 상호 작용의 주요 수단은 하이퍼링크와 HTML 폼이며, 이 둘

모두 브라우저에서 HTTP 요청을 실행시킨다. 하이퍼링크와 HTML 폼의 한계는 요청에

대한 응답시 현재 페이지, 즉 현재 페이지의 프레임을 자동으로 집어넣는다는 점이다. 즉,

이 둘은 웹에서 컨텐트를 다시 찾아서 가져오는 용도로 설계되었다.

조금 더 복잡한 클라이언트 애플리케이션을 만들어야 할 경우, 컨텐트보다 데이터를

검색해야 하거나, 혹은 현재 페이지에 삽입하기 위해 잘 걸러진 컨텐트를 검색해야 할 수

있다. XMLHttpRequest 객체(이후로는 줄여서 XHR이라고 함)는 이 문제의 해결책으로

서 즉, 프로그램에서 HTTP 요청을 더 잘 제어할 수 있기 위해서 개발되었다.

앞 절에서도 이야기한 바와 같이 XHR 객체를 이용하면 서버로의 HTTP 요청 전송 및

응답 수신 작업을 프로그램에 직접 코딩하는 방식으로 처리할 수 있다. 이것은 브라우저

가 응답 결과를 새로운 페이지로서 자동으로 보여주던 기존의 방식과 다르다. 클라이언

트 측 코드 관점에서 이를 이루기 위해서는 여러 가지 작업을 해야 하며, 이를 그림 1-4

Page 41: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

��

Ajax를 포용한 개발자들 1장

에 요약해 놓았다.

첫 번째로 할 일은 XHR 객체를 생성하는 것이다❶. 그런 다음에 요청 작성에 필요한

정보를 XHR 객체에 제공한다❷. 마지막으로 응답이 돌아오면 그 응답을 처리한다❸. 요

청을 보내고 응답을 받는 사이에 서버에서 처리되어야 할 작업도 있다. 그리고 환경에 따

라서 PHP, 자바, .NET으로 코드를 작성해야 한다. 여기서 주된 관심을 두는 곳은 클라

이언트 측 코드다. 서버 측 머신에서 간단한 Ajax 요청을 처리하지만 이것은 Ajax 도입

이전의 웹 프로그래밍과 크게 다르지 않다. 나중에 이 책의 다른 곳에서 서버 측 코드 예

제를 제시할 것이며, 지금은 클라이언트가 어떻게 작업하는지를 자세히 살펴볼 것이다.

이후 각 단계를 설명하면서 그림 1.4를 계속 참고할 것이다.

그림 1.4 XHR 객체를 이용하여 Ajax 요청을 만드는 주요 단계

가장 먼저 해야 할 일은 XHR 객체를 인스턴스화하는 것이다.

1.2.2 XMLHttpRequest의인스턴스화

XHR 객체는 4개의 주요 브라우저 계열인 인터넷 익스플로러, 파이어폭스/모질라/넷스케

이프, 사파리, 오페라에서 지원된다. XHR 객체를 사용하려면 XHR 객체 인스턴스를 생성

하고, 서버로 전송될 요청의 셋업에 필요한 몇 개의 매개변수를 넣고, 요청을 전송하도록

명령을 내린 다음에, 마지막으로 결과를 처리할 것이다. 리스트 1.1은 1단계인, XHR 객체

를 인스턴스화하는 예제 소스이며, 여러 브라우저를 지원하도록 만들어졌다.

XMLHttpRequest 객체

인스턴스화

서버로 갈 요청 만들기

클라이언트에서 응답 파싱

요청

응답

서버브라우저

XHR 객체

XMLHttpRequest 객체

인스턴스화

서버로 갈 요청 만들기

클라이언트에서 응답 파싱

요청

응답

서버브라우저

XHR 객체

Page 42: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

�2

Ajax 기초1부

리 스 트 1.1 | XHR 객체의 인스턴스화

var xhr; if (document.XMLHttpRequest) { XHR 객체 찾기

xhr = new XMLHttpRequest(); 네이티브 객체 생성} else { xhr = new ActiveXObject("Microsoft.XMLHTTP");

ActiveX 컨트롤 생성} else { alert("cannot use Ajax"); }

이 코드가 복잡한 이유는 크로스 브라우저 비호환성(cross-browser incompatibility; 경험

이 많은 웹 개발자들에게는 전혀 놀라운 문제가 아님) 때문이다. 인터넷 익스플로러(버

전 7 이전)는 네이티브 XHR 객체를 지원하지 않고, XHR을 ActiveX 객체로 구현하고 있

다. 이러한 이유 때문에 사용자가 “Safe ActiveX” 스크립팅 옵션을 꺼놓았으면 Ajax가

적용된 애플리케이션을 실행시킬 수 없을 것이다.(이렇게 만든 Microsoft를 비난하기 전

에 Microsoft XHR 객체를 1990년대 후반에 이미 개발하였으며, XML 파싱 모듈로 구현

하여 이를 인터넷 익스플로러와 함께 시장에 선보이기 시작했다는 점을 기억하기 바란다.

이에 반해서 다른 주요 브라우저에서 XHR 지원 기능을 추가한 것은 최근의 일이라는 것

도 유념하기 바란다.)

오래된 브라우저들 중에서 XHR 객체를 지원하지 않는 브라우저로는 어떤 것이 있는지

점검하고, 애플리케이션이 해당 브라우저에서 실행되지 않을 것이라는 내용의 경고 메시

지를 뿌려줄 필요가 있다. 코드가 어떤 브라우저에서 실행되느냐에 따라서 진행 경로가

달라질 것이며, 여기에 if() 문을 사용하고, 마지막에는 XHR 객체에 대한 참조를 넣으

면 된다. 참조 대상이 네이티브 객체(native object)거나 ActiveX 컨트롤일 수 있으며, 어

떤 종류의 XHR이든 상관없이 이제 그것을 사용할 수 있게 된다. 그리고 XHR 종류가 무

엇인지에 상관없이 이 순간 이후부터는 해당 객체의 메서드(method)와 속성(property)은

완전히 똑같아진다.

1.2.3 요청전송

그림 1.4를 잠깐 다시 보자. 이제 XHR 객체의 인스턴스화가 끝났고, 두 번째 단계인 요청

전송 단계를 살펴볼 차례다. XHR 객체가 요청을 어떻게 전송하는지 살펴보기 전에 서버

Page 43: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

�3

Ajax를 포용한 개발자들 1장

호출에 필요한 기본 정보를 살펴보자. 다음의 정보가 필요할 것이다.

서버의 URL

HTTP 요청 종류. 일반적으로 GET이나 POST 중 하나

서버에서 필요로 하는 매개변수들

서버에서 반환된 결과를 해석할 자바스크립트 함수

이들 항목을 한 개씩 살펴보자. 처음 두 항목, 어떤 경우에 세 번째 항목까지는 open()

메서드 호출 시 메서드의 인자로 셋팅돼 서버로 전달된다 . open() 메서드는 특정 URL

로 가는 연결을 초기화한다. open() 메서드의 형식은 세 가지다.

open(http_method, url)

open(http_method, url, asynchronous)

open(http_method, url, asynchronous, userid, password)

이 메서드는 대개 GET이나 POST가 되며, 이외에 서버에서 지원하는 HTTP 메서드인

PUT, DELETE, HEAD 등이 될 수도 있다. asynchronous의 값이 참(true)일 경우, 요

청은 백그라운드에서 실행될 것이며, 이 상태에서는 XHR 요청이 처리되는 도중에 사용자

가 다른 작업을 할 수 있다. 반대로 거짓(false)이면 요청은 동기적으로 처리되어서 요청이

종료될 때까지 사용자는 차단될 것이다. 이것은 전통적인 작업-대기 웹 애플리케이션과

거의 동일한 방식이다.

이 세 번째 인자는 예전에 사용되던 XHR(범용 ActiveX 컨트롤)을 반영하고 있다. 일

부 애플리케이션에서 동기 요청(synchronous request)을 만드는 것이 필요할 수 있다. 그

러나 자바스크립트 인터프리터는 본질적으로 단일 스레드(single thread) 방식이다. 그리

고 동기 요청을 만들면 응답이 반환되기 전까지 모든 사용자는 브라우저와 상호 작용할

수 없다. Ajax 애플리케이션에서는 요청을 항상 비동기로 만드는 것이 좋다.

userid와 password는 서버와의 연결에 사용된다. 이것은 NT 도메인 기반 인증과 달

리 패스워드를 평문으로 전송하는 HTTP 인증만 지원하므로, HTTPS를 이용하는 보안

소켓상에서 운용되지 않을 경우 조심스럽게 다루어야 한다.

한 URL로 연결하기 위하여 다음과 같이 코딩할 수 있다.

xhr.open(‘GET’, ‘servlets/ajax/getItem?id=321’, true);

여기서는 HTTP GET 메서드를 사용하기 때문에 서버에 대한 매개변수들을 질의 문자열

Page 44: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

��

Ajax 기초1부

로서 넘긴다. 만약 POST를 사용하면 매개변수들을 HTTP 요청 바디(request body)에서

넘겼을 것이며, 이것에 대해서는 곧 설명할 것이다.

XHR 객체를 준비하는 두 번째 단계는 응답을 수신할 콜백 핸들러(callback handler)를

할당하는 것이다. 현재 시점에서 이 함수의 기능을 알 필요는 없고, 다음과 같이 할당만

하기로 한다.

xhr.onreadystatechange = parseResponse;

여기서 참조를 함수 객체로 넘긴다는 점에 주목하기 바란다. parseResponse 함수 뒤에

괄호가 없는 것을 보면, 이 함수가 호출되지 않는다는 것을 알 수 있다. 그러나 이렇게 하

더라도 응답이 돌아올 때 이 함수가 자동으로 호출될 것이라는 것을 XHR은 안다. 이 콜

백 할당은 onclick이나 onmouseover와 같은 UI 이벤트 핸들러(UI event handler)를 셋

팅하는 것과 동일하다.

세 번째 단계는 send() 메서드를 호출하는 것이다. send() 메서드는 실제로 서버 호

출을 실행하며, URL에 명시되지 않은 추가 데이터 전송에 사용된다. send() 메서드에

는 요청 바디에 전송될 추가 데이터가 인자로 들어간다. 일반적으로, POST 요청에만 바

디가 있으며, GET 요청의 경우에는 다음의 예와 같이 빈 문자열만 넘긴다.

xhr.send(‘’);

바로 이것이다! 요청은 이제 서버로 갈 것이며, 응답이 돌아오기 전까지 클라이언트 코드

에서 할 일은 없다. 다음 절에서 이에 대한 결과를 더 자세히 살펴볼 것이다.

1.2.4 응답처리

서버에 요청이 접수되면, 서버는 이에 합당한 작업을 수행하여 응답을 보내려고 할 것이

다. 그림 1.4를 다시 보면, 이제 해야 할 일은 브라우저로 돌아오는 응답을 수신하고 이것

을 꺼내는 것이다. 앞 절에서 이 작업에 필요한 준비를 이미 하였다. XHR 객체에 콜백 핸

들러 함수를 할당한 것이 이에 해당한다. 이번 절에서는 콜백이 호출될 때 어떤 일이 일어

나는지 살펴볼 것이다.

XHR이 단순히 응답 도착 시점을 알린다고 생각할 수 있지만, 사실 XHR은 응답이 시

작되어 끝나기까지 여러 지점에서 응답의 상태를 알린다. 가끔은 이것이 매우 유용한 정

보가 되기도 하지만, 일반적으로는 정신을 산만하게 만든다.

Page 45: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

��

Ajax를 포용한 개발자들 1장

앞 절에서 onreadystatechange라는 콜백 핸들러를 할당하였다. 이 함수는 XHR

객체의 준비 상태에서 최소한 한 번은 호출될 것이다. onreadystatechange에서

readyState 속성을 점검할 필요가 있으며, 이렇게 하는 이유는 요청이 현재 진행되고

있는지, 그리고 최종 결과를 처리할 수 있는지를 확인하기 위해서다. readyState에는

미리 정의되어 있는 아래의 값들 중 하나가 들어갈 것이다.

값 상태 설명

0 초기화되지 않았음 open()이 호출되지 않았다.

1 로드되고 있음 open()이 실행되었다.

2 로드되었음 send()가 실행되었다.

3 상호 작용 서버가 데이터를 반환하였다.

4 완료 요청이 완료되었고, 서버도 데이터 전송을 완료하였다.

readyState가 4인지 점검하면 된다. readyState가 4라는 것은 요청이 끝났다는 것을

의미한다. 따라서 전형적인 콜백 함수는 다음과 같은 형태일 것이다.

xhr.onreadystatechange = function(){

var ready = xhr.readyState;

if (ready == 4){

parseCompletedResponse(xhr);

}

};

즉, readyState 속성의 값이 4인지를 확인하고, 값이 4라는 것은 응답이 완전히 도달하

였으며 파싱될 수 있다는 것을 나타낸다. 값이 4일 경우, 파싱 함수(parsing function)로

넘어간다. 응답을 파싱할 때 가장 먼저 알아야 할 것은 요청이 제대로 처리되었는지 여부다.

status 속성에는 요청의 HTTP 상태가 포함된다. 요청된 URL이 제대로 처리되었으

면 유효한 HTTP GET이나 POST는 대개 200을 반환한다. URL이 없으면 404를 반환한

다. 일반적으로 결과 코드가 200과 299 사이라면 성공을 나타내고, 이외의 다른 코드는

오류이거나 브라우저에서 추가 액션이 이루어짐을 나타낸다. readyState와 status를

결합하면 요청이 제대로 완료되었는지 확인할 수 있다. 함수를 다음에 제시된 예와 같이

수정할 수 있다.

xhr.onreadystatechange = function(){

var ready = xhr.readyState;

if (ready == 4) {

var status = xhr.status;

Page 46: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

�6

Ajax 기초1부

if (status >= 200 && status < 300) {

parseCompletedResponse(xhr);

} else {

parseErroredResponse(xhr);

}

}

};

응답이 제대로 왔다고 가정하자. 응답은 두가지 속성으로 제공된다. 하나는 responseText

고 다른 하나는 responseXML이다. responseText는 응답을 일반 문자열로 표현하고,

responseXML은 응답을 파싱된 XML 문서로 제시한다. 이 둘에 대해서는 이번 장과 다음

장의 예제들에서 더 자세히 살펴볼 것이다.

지금까지 Ajax 요청과 응답이 전체적으로 어떻게 이루어지는지 간단하게 살펴보았다.

객체를 확보하고, 요청을 하고, 응답을 파싱함에 있어서 사소한 작업을 많이 처리해야 했

다. 지금까지 낮은 수준의 작업을 자세히 이야기하였으므로, 이후에는 본문에서 이러한

사소한 작업에 대해 이야기하지 않을 것이다. 왜냐하면 그렇게 하지 않아도 우리 대신 어

려운 일을 처리할 좋은 프레임워크와 라이브러리가 많이 있기 때문이다.

그러나 XHR이 어떻게 작업하는지 아는 것은 유용하다. 왜냐하면 XHR의 작업 방법을

알면 Ajax 라이브러리로 무엇을 할 수 있고 무엇을 할 수 없는지 이해하는데 도움이 되기

때문이다. 따라서 라이브러리나 프레임워크와 같은 높은 수준의 내용을 살펴보기 전에

XHR 객체의 메서드와 속성을 몇 개 더 설명할 것이다.

1.2.5 다른XMLHttpRequest메서드와속성

그다지 많이 사용되지 않는 XHR 메서드들이 몇 개 있다. 일반적인 경우에는 이들 메서드

를 몰라도 된다. 그러나 이들 메서드가 일부 특수한 작업에는 매우 유용할 수 있다.

abort()

abort()는 가능하다면 현재 요청을 무시한다. send() 메서드가 이미 호출된 경우,

abort()는 클라이언트 측에서만 요청을 무시하며, 서버는 HTTP 요청을 받고서 결과를

처리할 것이다. 그러나 브라우저는 결과를 무시하고 진행을 멈춘다.

Page 47: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

�7

Ajax를 포용한 개발자들 1장

setRequestHeader(header, value)

이 함수를 이용하여 HTTP 요청을 위한 헤더 값을 지정할 수 있으며, 요청 바디의 컨텐트

타입을 지정할 때 가장 일반적으로 사용된다. 유효한 HTTP 헤더 값을 모두 사용할 수 있다.

이 함수를 사용하여 여러 가지 작업을 할 수 있으며, 일례로 아래와 같이 코딩하여 요청의

MIME 타입을 x-www-form-urlencoded로 지정할 수 있다.

xhr.setRequestHeader(

'Content-type',

'application/x-www-form-urlencoded'

);

Ajax에서는 여러 개의 키-값 쌍(key-value pair)을 서버로 보낼 수 있다. 그리고 XML 페

이로드(payload)를 전송할 수 있으며, 이 경우에 XML을 전송한다는 것을 서버에게 알릴

수 있다.

xhr.setRequestHeader(

'Content-type',

'application/xml; charset=UTF-8'

);

Ajax에서의 XML 사용 방법을 2장에서 더 자세히 설명할 것이다. 또한 2장에서는 응답

처리시 사용할 수 있는 몇 가지 방법도 살펴볼 것이다.

getResponseHeader(header)/getAllResponseHeaders()

일반적으로 HTTP 응답에는 많은 헤더가 포함되며, 각 헤더는 키-값 쌍으로 되어 있다.

XHR 객체는 getAllResponseHeaders()를 사용하여, 모든 헤더 이름을 나열할 수 있

으며, 인자로 헤더 이름이 들어가는 getResponseHeader()을 사용하여 헤더 값을 읽을

수 있다. 예를 들어, 서버가 Microsoft IIS 서버인지를 파악하기 위하여 다음과 같이 코딩

할 수 있다.

if (xhr.getResponseHeader("Server")

.indexOf("Microsoft-IIS") != -1 ) {

alert("The server is a Microsoft IIS server.");

}

지금까지 XHR 객체의 사용 방법을 자세히 살펴보았다. 이제 더 흥미로운 질문으로 관심

Page 48: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

�8

Ajax 기초1부

을 돌릴 수 있다. 이 장의 나머지 부분에서는 Ajax의 사용을 더 쉽게 만드는 Prototype

라이브러리의 헬퍼 객체(helper object)들을 소개할 것이며, 일련의 예제들을 통해서 서버

에서 비동기 요청을 할 수 있음으로써 무엇을 할 수 있는지 살펴볼 것이다.

1.3 프레임워크를 사용하여 Ajax를 단순하게 만들기

앞 절에서 XHR 객체를 활용하여 Ajax 요청을 어떻게 만드는지 기본 방법을 살펴보았다.

그리고 전체 페이지를 새로 고치지 않고도 서버로부터 데이터를 불러오는 방법을 익혔다.

이제 서버에게 무엇을 알려주어야 하며, 서버가 어떤 종류의 응답을 제공할 것인지 살펴

볼 차례다.

HTTP 프로토콜에서 규정한 기본 규칙은 매우 느슨하다. 모든 통신은 클라이언트의 요

청으로 시작되고, 서버의 응답으로 완료되어야 하며, 텍스트 기반이어야 한다. 그 이상은

별다른 상관이 없다. 여기서는 Ajax를 이용하여 넘겨질 수 있는 여러 유형의 데이터를 살

펴볼 것이며, 애플리케이션에서 브라우저와 서버 사이의 통신을 구성하기 위하여 Ajax를

어떻게 사용할 것인지 그 방법을 살펴볼 것이다.

여기서 두 번째로 살펴볼 내용은 라이브러리와 프레임워크 코드다. 라이브러리와 프레

임워크를 잘 활용하면 코딩 작업이 쉬워질 것이다. 가공하지 않은 XHR 객체를 사용할 경

우 크로스 브라우저 문제를 처리하기 위하여 많은 코드를 작성해야 하며, HTTP 요청 및

응답에 관련한 모든 세부 사항을 일일이 조정해야 한다. HTTP의 작동 원리를 학습할 때

는 이 방법이 좋았지만 실제 코드를 작성할 때는 애플리케이션 상태와 로직에 관련된 높은

수준의 문제 해결에 더 많이 집중해야 하며, 낮은 수준의 사소한 작업은 제외되어야 한다.

다행히 Ajax에서 사용할 수 있는 괜찮은 프레임워크와 라이브러리가 많이 있으며, 여

기서는 이들 프레임워크와 라이브러리들 중 일부를 사용할 것이다. 일부 프레임워크는 4

장에서 정식으로 살펴볼 것이며, 여기서는 내용 설명과 관련하여 소개하는 수준에서 그

칠 것이다.

이 장에 나오는 예제들에서는 클라이언트와 서버 사이의 데이터 전송 방법을 중점적으

로 살펴볼 것이다. 따라서 이 장에서는 “Hello World”와 같은 종류의 예제를 제시할 것

이다. 이 장에서 제시되는 예제들의 백 엔드에서는 JSP(JavaServer Pages)를 사용하였으

며, 톰캣(Tomcat) 웹 서버에서 테스트하였다. 이 책에 나오는 모든 예제는 .war 파일 형

Page 49: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

�9

Ajax를 포용한 개발자들 1장

태로 제공하고 각각의 예제들에 대한 실행 페이지 또한 함께 제공한다. 이를 그림 1.5에

서 확인할 수 있다.

그림 1.5 1장과 2장에 있는 예제들의 실행 페이지

이제 다른 말을 더 이상 하지 말고, 서버와 통신하기 위해 Ajax를 사용하는 첫 번째 예제

를 살펴보자.

앞 절에서 본 것처럼 Ajax 요청을 만드는 것이 매우 간단하지만 이와 관련하여 고려

해야 할 사항이 많다. 실제 웹 애플리케이션을 만들 때 서버로 비동기 호출을 하는 것은

최후의 수단이다. 도메인 모델 계층과 통신할 때마다 readyState, HTTP 헤더, URL-

encoded 질의 문자열에 집중해야 하는 것은 지루하고도 괴로운 일일 것이다.

모든 소프트웨어 개발에서와 같이 특정 태스크에 관련된 문제를 해결하고 나면 해당

문제에 대한 해결책을 헬퍼 객체나 함수에 일단 캡슐화하는 것이 좋다. 이렇게 하면 다음

수준의 문제에 집중할 수 있다. 개발자들은 Ajax 표준 요청을 만들어 놓고, 몇 줄의 코드

로 응답을 처리하기를 원한다. 이렇게 해두면 표준 요청이나 응답 처리 코드가 필요할 때

가져와서 사용할 수 있다.

Page 50: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

20

Ajax 기초1부

XHR 객체를 캡슐화하기 위하여 자신만의 헬퍼 라이브러리를 작성하거나, 아니면 이

미 누군가가 힘들게 만들어 놓은 서드파티 라이브러리를 사용할 수 있다. 이 절에서는

Prototype 라이브러리의 Ajax 헬퍼 클래스들을 살펴볼 것이고, 이들 클래스를 활용하면

Ajax가 얼마나 간소해지는지 볼 것이다. 먼저, 요청을 어떻게 만드는지 그 방법을 살펴본다.

1.3.1 Prototype의Ajax.Request객체로요청만들기

1.2절의 예제에서 서버로 Ajax 요청을 보낼 때 성가신 문제들에 직면하였다. 첫째, 모든

브라우저를 지원하도록 XHR 객체를 생성해야 했다. 둘째, URL, HTTP 메서드, POST

바디를 제공하고, HTTP 헤더들을 지정하기 위하여 XHR 객체에서 여러 개의 메서드를

불러들여야 했다. 이것을 처리하기 위해서는 HTTP 프로토콜에 대한 실제 지식이 요구된

다. 기본적인 것에 대하여 실제 지식을 갖추는 것은 좋은 일이지만, 서버에 대한 콜백을

만들 때마다 상세한 것까지 빼놓지 않고 생각해야 하는 불편함이 있다.

Prototype의 Ajax.Request와 같이 좋은 래퍼 객체는 크로스 브라우저 문제를 자동화

할 것이다. 또한 이 객체를 이용하면 집중해야 할 정보에만 주의를 기울일 수 있으며, 개

발자가 명시적으로 제공하지 않는 모든 매개변수에 대하여 적절한 기본 값을 자동으로

제공받을 수 있다.

문제

XHR 객체로 작업하려면 낮은 수준의 많은 세부사항에 집중해야 한다. 예를 들면 크로스

브라우저 방식으로 객체를 획득하는 것과 응답이 도착하는 동안 readyState의 정교한

변경에 반응하는 것이 있다.

솔루션

Ajax 요청 생성을 간소화하려면 프레임워크를 사용하기 바란다. 간단한 애플리케이션을

먼저 살펴보자. 살펴볼 애플리케이션의 UI는 그림 1.6과 같다.

그림 1.6 Hello World 애플리케이션 버전 1의 사용자 인터페이스

Page 51: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

2�

Ajax를 포용한 개발자들 1장

여기서는 텍스트 입력 박스와 확인 버튼을 넣었다. 확인 버튼이 클릭되면 입력 박스의 텍

스트는 서버로 전송될 것이고, “Hello, stranger” 문구는 서버에서 반환된 이름으로 대체

될 것이다. 이 경우에 서버는 이름과 관련하여 실제로는 아무 것도 하지 않으며, 단순히

받은 이름을 뿌려주기만 한다. 그러나 여기서 주된 관심사는 클라이언트에서 응답을 받는

것이다. 물론 서버에서도 다양한 종류의 처리작업이 발생할 것이다. 먼저 클라이언트 측

코드를 살펴본다.

클라이언트 측 코딩

리스트 1.2는 이번 예제의 클라이언트 측 코드다.

리 스 트 1.2 | hello1.html

<html><head><title>Hello Ajax version 1</title><style type='text/css'>* { font-family: Tahoma, Arial, sans-serif; }#helloTitle{ color: #48f; font-size: 1.5em; }</style><script type='text/javascript' src='prototype.js'> </script>

b Prototype 라이브러리 포함

<script type='text/javascript'>window.onload=function() { document.getElementById('helloBtn') .onclick = function(){ var name = document.getElementById('helloTxt') .value; new Ajax.Request(

c Ajax.Request 객체 생성

"hello1.jsp?name = "+encodeURI(name),

d URL 제공 (필수) { method:"get", onComplete:function(xhr){ document.getElementById('helloTitle') .innerHTML = xhr.responseText;

e 옵션 매개변수 제공

} } ); };};</script></head><body>

Page 52: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

22

Ajax 기초1부

<h1 id='helloTitle'>Hello, stranger</h1><p>Please introduce yourself by enteringyour name in the box below</p><input type='text' size='24' id='helloTxt'></input>&nbsp;<button id='helloBtn'>Submit</button></body></html>

가장 먼저 해야 할 일은 페이지에 Prototype 라이브러리를 포함시키는 것이다❶.

Prototype은 하나의 파일로서 포함되며, 한 줄로 이를 처리할 수 있다.

window.onload 이벤트 핸들러에서 버튼 객체를 참조하며, 이것에 클릭 이벤트 핸들

러를 할당한다. 이벤트 핸들러에서는 텍스트 입력 박스에 입력된 이름을 읽고❷, 그런 다

음에 Ajax.Request 객체를 생성한다. 이 객체에는 두 개의 인자가 있다. 첫 번째 인자는

서버 자원의 URL로서 필수다❸. 그리고 두 번째 인자는 자유로운 형식의 자바스크립트

객체로서, 여기에는 임의로 정해진 추가 설정 옵션들이 포함될 수 있다❹. 추가 설정 옵

션으로는 HTTP 동사(HTTP verb), 헤더, 요청 바디, 다양한 콜백 옵션, 기타 특징이 포함

될 수 있다. 이번 예제에서는 두 개의 옵션만을 넘긴다. 첫째, HTTP 메서드를 GET으로

설정한다. 왜냐하면 Ajax.Request의 기본 값이 POST이기 때문이다. 둘째, 콜백 함수를

제공한다.

1.3절에서 보았지만 XHR 객체에는 readyState의 값이 변경될 때마다 자동으로 처

리되는 콜백이 있다. Ajax.Request가 XHR 객체를 내부에서 생성할 때 세부 사항을 처

리할 내부 콜백을 정의한다. 라이브러리의 최종 사용자인 개발자는 onComplete와 같이

각자의 즉각적인 요구사항에 더 잘 부합하는 더 높은 수준의 콜백을 직접 만들어 사용할

수 있다. 비교적 드문 경우기는 하지만, readyState의 다른 상태들도 통고 받기를 원한

다면 상태의 변경 정보를 확보하기 위하여 콜백 함수를 추가로 만들 수도 있다.

콜백 함수는 매우 단순하며, 그림 1.7에서 볼 수 있는 바와 같이 페이지의 제목을 수정

한다. 이름을 입력하고 확인 버튼을 클릭하기만 하면 제목이 수정된다.

그림 1.7 Hello World 버전 1: Ajax 응답 처리 후의 실행 화면

Page 53: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

23

Ajax를 포용한 개발자들 1장

지금 살펴본 것은 이번 예제의 구현에 사용된 클라이언트 측 코드다. 다음 절에서는 서버

측 코드를 살펴볼 것이다.

서버 측 코딩

이번 예제에 대한 서버 측 코드는 리스트 1.3에서 볼 수 있는 것처럼 매우 간단하다.

리 스 트 1.3 | hello1.jsp

<jsp:directive.page contentType="text/plain"/><%String name = request.getParameter("name");%>Hello, <%=name%>

앞에서 언급한 것처럼 이번 예제를 위해 서버 측 코드를 가능한 한 간단하게 만들었다. 간

단하게 만든 이유는 클라이언트 측 코드에 초점을 맞추기 위해서다. 여기서 제시된 JSP는

간단하다. 그러나 간단한 JSP에 사용된 원리를 이용하여 n 계층의 복잡한 애플리케이션

을 구성할 수도 있다.

토론

Prototype에 있는 Ajax.Request 클래스를 이용하면 Ajax 요청을 쉽게 만들 수 있다.

Ajax 요청을 만들기 위해 URL, HTTP 메서드, 콜백 함수만 있으면 된다. 내부적으로 보면,

Ajax.Request는 XHR 객체를 어떻게 만들 것인지 계획을 세우고, 요청을 구체화할 때 이

에 필요한 것을 채워 넣는다. 또한 Ajax.Request는 응답 완료 시 한 번만 호출되고, 애플

리케이션 로직만 처리하면 되는 함수를 만들 수 있도록 하여, 콜백 구조를 상당히 단순화

시켰다.

Prototype은 Ajax 헬퍼 클래스보다 더 많은 것을 제공한다. 이번 예제에서는 잘 설계

된 래퍼 객체 예로서 Ajax.Request를 사용하기 때문에 다른 특징들을 사용하지 않아도

된다. 다른 유명한 Ajax 라이브러리들에는 Ajax.Request만큼 호출 기법이 간단한 래퍼

객체들이 많다. Dojo에는 dojo.io.Request 클래스가 있으며, MochiKit에는 MochiKit.

Async가 있고, jQuery에는 $.ajax() 함수가 있다. 어떤 라이브러리를 사용할 것인지

에 따라서 Ajax 래퍼의 정확한 능력은 다양하겠지만, 어떤 것을 사용하더라도 많은 시간

을 절약할 수 있을 것이다.

Page 54: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

2�

Ajax 기초1부

이번 예제에서 응답 처리에 제공된 콜백 함수는 매우 간단하다. 다음 예제에서는 Ajax

를 기반으로 더 풍부한 컨텐트를 생성하기 위해 무엇이 필요한지를 살펴볼 것이다.

1.3.2 Ajax응답단순화

앞의 예제에서 innerHTML 속성을 사용하였으며, 이는 서버 컨텐츠를 페이지의 DOM 요

소로 직접 작성하기 위해서다. 위 예제의 경우, 서버에서 온 응답은 간단한 텍스트였다.

그러나 이 예제와 달리 실제로 많은 경우에는 서버로부터 더 복잡한 정보를 받아야 하며,

가끔은 정보의 내부 구조까지 받아야 한다. 2장에서는 서버와 클라이언트 사이에서 구조

화된 정보를 어떻게 받을 수 있는지 그 방법을 살펴볼 것이다.

구조화된 데이터는 대다수 웹 애플리케이션의 중심부를 이룬다. 일반적으로, 서버에

있는 데이터는 관계형 데이터베이스에 저장된다. 이에 반해서 클라이언트쪽에서 데이터

는 사용자 인터페이스나 보고서 형태로 표시된다. 서버와 클라이언트 사이에서 오고 가

는 도중에 데이터는 애플리케이션의 로직에 의해 조작되거나 어떤 결과를 만들어낼 수

있다. 전통적으로, 이 작업은 전적으로 서버에서 이루어졌으며 클라이언트는 단순한 단

말기의 기능을 수행하였다. 그러나 Ajax를 도입하면, 클라이언트나 서버 중 한 곳에서 혹

은 클라이언트와 서버 두 곳 모두에서 로직을 실행할 수 있다.

먼저 단순한 단말기 형태의 방법이 어떻게 적용되는지 살펴보자. 서버는 애플리케이

션 데이터를 처리하여 풍부한 내용이 들어간 보고서를 생성한다. 그리고 화면을 출력하

기 위하여 해당 보고서를 클라이언트로 보낸다. 클라이언트는 서버로부터 온 정보가 무

슨 의미인지 알 필요가 없으며, 해당 정보의 화면 출력 방법만 알면 된다. 이 예제에 사용

할 응답 내용에 약간의 재미를 더하기 위하여 제목 아래에 이번 예제의 기능과 상관이 없

는 내용을 넣어두었다. 페이지에 들어갈 전체 응답 예제는 다음의 그림 1.8과 같다.

그림 1.8 Ajax 응답에서 HTML을 반환한 결과

Page 55: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

2�

Ajax를 포용한 개발자들 1장

문제

서버는 간단한 텍스트가 아니라 애플리케이션 상태에 맞추어서 시각적으로 뛰어난 보고서

를 보내며, 이 보고서는 사용자 인터페이스에 통합된다.

솔루션

이 문제의 해결책은 매우 간단하며, 이를 처리하기 위해서는 약간의 자바스크립트 코딩이

필요하다. 클라이언트에서 변경해야 할 내용은 많지 않으며, 응답을 문서로 붙여넣기 위하

여 innerHTML 속성을 사용해도 된다. 리스트 1.4는 이번 예제의 클라이언트 측 코드다.

리 스 트 1.4 | hello2.html

<html><head><title>Hello Ajax version 2</title><style type='text/css'>* { font-family: Tahoma, Arial, sans-serif; }#helloTitle{ color: #48f; }</style><script type='text/javascript' src='prototype.js'> </script><script type='text/javascript'>window.onload=function(){ $('helloBtn').onclick = function(){ var name = $('helloTxt').value; new Ajax.Request( "hello2.jsp?name = "+encodeURI(name), { method:"get", onComplete:function(xhr){ $('helloTitle').innerHTML = xhr.responseText; } } ); };};</script></head><body><div id='helloTitle'><h1>Hello, stranger</h1></div>

Page 56: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

26

Ajax 기초1부

<p>Please introduce yourself by entering your name in the box below</p><input type='text' size='24' id='helloTxt'></input>&nbsp;<button id='helloBtn'>Submit</button</body></html>

이번 예제에서는 서버쪽을 주로 변경해야 한다. 리스트 1.5와 같이 JSP를 수정하면 된다.

리 스 트 1.5 | hello2.jsp

<jsp:directive.page contentType="text/html"/><%String name=request.getParameter("name");%><h1>Hello <%=name%></h1><p>I used to know someone called <b><i><%=name%></i></b>. Are yourelated?</p>

여기서는 응답의 MIME 타입을 text/html로 지정하였다. 이것이 필수 사항은 아니지만

계획서 역할을 한다. 일부 Ajax 라이브러리는 응답의 MIME 타입에 민감하므로 가급적이

면 MIME 타입을 지정하는 것이 좋다.

응답의 바디에서는 입력 매개변수의 값에 따라 약간의 컨텐트를 생성한다. 여기서는

사용자가 입력한 이름을 그대로 표시하는 것 이외에 어떤 작업도 수행하지 않는다. 이렇

게 하는 이유는 백 엔드로 수행될 작업을 간소화하기 위해서다. 그러나 실제 코딩에서는

프론트 컨트롤러, 도메인 객체, 데이터베이스 등을 포함해서 적절한 코드를 작성해야 할

것이며, 이를 위해서 요청 매개변수를 지정하고 응답을 생성해야 할 것이다. Ajax 메커

니즘이 적용되어 있으면 결과는 이번 예제와 동일할 것이며, 클라이언트로 HTML 단락

이 반환될 것이다.

토론

Ajax 웹 애플리케이션을 개발할 때 서버에서 HTML 단락을 만드는 것은 Ajax 성장에 도

움을 주는 전략임에 틀림이 없으며, 이 특징을 활용하면 사람들이 필요로 하는 모든 것을

제공할 수 있다. 브라우저로 넘어갈 HTML을 서버에서 만드는 이 전략으로 인해 많은 개

발자들이 전통적인 웹 애플리케이션과 프레임워크를 사용하지 않고 Ajax 웹 애플리케이

Page 57: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

27

Ajax를 포용한 개발자들 1장

션을 사용하고 있으며, 그 수는 확연히 늘어나고 있다.

이번 예제에서는 기존 페이지에 새로운 단락을 삽입하기 위해 innerHTML을 사용했

다. 어떤 요소에 있는 기존의 컨텐트를 완전히 지우고, 새로운 컨텐트로 교체할 때 이 방

법은 대부분의 경우에 효과적이다. insertAdjacentHTML()이나 createContextua

lFragment()와 같은 다른 DOM 메서드를 사용하면 더 정교하게 제어할 수 있지만, 이

들 메서드들 중 상당수는 크로스 브라우저를 지원하지 않는다. Prototype 라이브러리는

Insertion 객체 형식으로 크로스 브라우저 래퍼를 제공하며, 다른 라이브러리들도 이와

유사한 특징을 갖는다.

innerHTML을 사용할 때 몇 가지 주의 사항이 있다. 첫째, 브라우저는 innerHTML에

의해 페이지에 포함된 <script> 태그를 무시할 것이다. 둘째, innerHTML에서 하나의

셀(즉, <TD> 태그)을 제외한 다른 HTML 테이블 요소의 속성은 읽기 전용이 된다.

마지막으로, Prototype 라이브러리가 특수한 Ajax.Request 서브클래스를 제공하며,

이것을 이용하면 앞에서 이야기한 작업을 더 쉽게 처리할 수 있다는 점을 염두에 두기 바

란다. 이것이 가능한 이유는 응답을 DOM 요소의 innerHTML 속성으로서 자동 할당하

기 때문이다. Prototype을 사용하고 있고 HTML 단락을 서버에서 보내고 싶으면 Ajax.

Updater를 살펴보기 바란다. 그러나 여기서 이것을 사용하지는 않을 것이다. 왜냐하면

Ajax.Updater를 사용하면 여기서 보여주고 싶은 기본 구조 중 많은 것을 이야기할 수 없

게 되며, 논의의 폭도 좁아지기 때문이다.

1.4 요약

1장의 서두에서는 현재 Ajax가 어디에 머무르고 있는지 살펴보았다. 기술은 빠르게 성숙

하고 있으며, 이와 함께 몇 가지의 흥미로운 일들이 일어나고 있다. 1장에서는 먼저, 일반

적인 동향 관점에서 두 가지 사항을 이야기했다. 첫 번째로 살펴보아야 할 것은, 처음에는

Ajax 요청을 어떻게 만드는지 그 방법을 설명하였지만 점차 Ajax로 무엇을 할 수 있을 것

인지로 이야기의 비중이 옮아 갔다는 점이다. 논의가 진행되면서 웹 애플리케이션 아키텍

처 관점에서 재미있는 쟁점들이 나왔으며, 비즈니스 모델 측면에서도 Ajax가 어떤 가능성

을 새롭게 열어 놓았는지 생각하게 되었다.

주목해서 보아야 할 두 번째 사항은 Ajax 프레임워크와 라이브러리가 성숙해졌다는 점

Page 58: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

28

Ajax 기초1부

이다. 감사하게도, 크로스 브라우저를 지원하기 위하여 일일이 코딩하던 시절은 점차 멀

어져 가고 있으며, Prototype, Dojo, Rico, DWR 등과 같은 라이브러리에 괜찮은 적용

예제들이 많이 추가되고 있다.

사실, 이 두 쟁점은 이 책에서 전반적으로 다룰 주제기도 하다. 이 책에서는 Ajax 개발

과 관련하여 더 높은 수준의 쟁점들을 논의하고, 또한 이들 쟁점을 해결하기 위하여 최고

의 툴킷을 활용하면 개발자의 코딩 업무가 얼마나 더 편안해질 수 있는지를 보여주고자

한다. 이와 함께 실제 개발 작업에서 Ajax를 제대로 활용하기 위해 꼭 갖추어야 할 실질

적인 지식도 제시할 것이다.

물론, 직접 코딩하는 일이나 낮은 수준의 세부 작업을 완전히 버릴 수는 없다. 이 장

의 후반부에서는 XHR 객체의 메커니즘을 살펴보았다. 그런 다음에 래퍼 객체(여기서는

Prototype의 Ajax.Request)를 사용하면 작업이 얼마나 더 쉬워지는지 보았다. 그리고

마지막 예제에서는 그 다음 수준의 애플리케이션 설계가 어떠해야 하는지를 살펴보았으며,

이와 관련하여 서버가 어떤 종류의 데이터에 응답할 수 있는지 요청해 보았다. 여기서는

가장 간단한 방법을 사용했는데, 서버로부터 HTML 단락을 검색했으며, 이것을 기존의

페이지에 삽입하였다.

이 방법이 여기서는 괜찮았으며, 비교적 간단한 자바스크립트만으로 Ajax의 많은 이점

을 확보할 수 있었다. 그러나 클라이언트에서 복잡한 작업을 처리해야 할 경우 이 방법은

높은 수준의 응답성을 제공할 수 없다. 왜냐하면 모든 중요한 결정에는 서버와의 통신이

필요하기 때문이다. 이러한 이유 때문에 몇 가지 핵심 기능을 클라이언트로 옮길 필요가

있다. 다음 장에서는 이 작업을 처리할 수 있는 다양한 방법을 살펴볼 것이며, 이 때 자바

스크립트, JSON, XML을 활용할 것이다.

Page 59: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

29

Ajax와의 통신 방법

: Ajax의 주요 방언(dialects) 확인

: 자바스크립트 및 JSON과 Ajax의 사용

: XML, XPath, 웹 서비스 활용 방법

02장

Page 60: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

30

Ajax 기초1부

Ajax는 용광로와 같으며, 여기에는 여러 가지의 애플리케이션 설계 방법과 무수한 방언이

녹아 들어가 있다. 1장에서는 Ajax의 중심을 이루고 있는 XHR 객체의 메커니즘과 헬퍼

객체에서의 래핑 방법을 살펴보았다. 서버와 클라이언트를 잇는 코드를 일일이 모두 작성

해야 하는 산만함이 없다면 보다 더 흥미로운 이슈인 서버와 클라이언트 사이의 통신 구조

화 작업에 한층 더 집중할 수 있다. 이제, 여러 범주의 Ajax 통신을 살펴보고, 일련의 방

언에서 Ajax와 어떻게 대화할 수 있는지 그 방법을 알아볼 차례다.

2장에서도 1장에 나왔던 Hello World 예제와 문제/솔루션 형식으로 설명을 계속 진행

할 것이다. 또한 하위 수준의 Ajax 주요 관심사를 처리하기 위해 프레임워크들을 계속 사

용할 것이고, 관심을 끌고 있는 몇 가지 쟁점 사항들을 자유롭게 살펴볼 것이다. 여러 예

제에서는 Prototype의 Ajax.Request 객체를 계속 사용할 것이다. 이외에, Sarissa와 웹

서비스 클라이언트 툴킷도 살펴볼 것이다. 먼저, 자바스크립트를 통신 매개체로써 어떻

게 활용할 수 있는지 살펴보는 것으로 이야기를 진행해 보자.

2.1 서버 측 자바스크립트 생성

Ajax 요청에 대해서 서버가 HTML을 반환할 때 복잡한 사용자 인터페이스를 생성할 수

있지만, 여기서는 그렇게 하지 않는다. 애플리케이션과의 상호작용이 많아지면 서버와 더

많은 통신을 해야 한다. 대부분의 경우에는 이것이 문제가 되지 않는다. 그러나 또 다른

경우에는 컨텐츠뿐만 아니라 행위(behavior)를 전달해야 한다. 클라이언트 측의 모든 행위

는 자바스크립트에 의해 처리되므로, 적절한 자바스크립트를 생성해야 한다.

2.1.1 서버에서생성된코드수행

서버에서 생성된 HTML을 처리할 때 innerHTML만 사용할 수 있다. 그리고 서버에서 생

성된 자바스크립트를 다룰 때 eval() 메서드를 사용할 수 있다. 자바스크립트는 인터프

리트형 언어이므로, 모든 텍스트는 코드로서 수행될 수 있다. 다음 예제에서는 Ajax 처리

경로의 일부로서 eval() 메서드를 어떻게 사용하는지 그 방법을 살펴볼 것이다.

2장에서 Hello World 애플리케이션을 계속 활용할 것이다. 첫 번째 예제에서는 응답

을 받아서 제목(title)을 수정할 것이다. 이를 그림 2.1에서 확인할 수 있다.

Page 61: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

3�

Ajax와의 통신 방법 2장

그림 2.1 서버에서 생성된 자바스크립트의 수행 결과

문제

Ajax 요청에 대해서 서버가 자바스크립트 코드를 반환한다. 코드가 수신될 때 수신된 코

드를 실행해야 한다.

솔루션

eval() 메서드를 사용하는 것이 innerHTML을 사용하는 것만큼 간단하다. 리스트 2.1은

세 번째로 수정된 Hello World 애플리케이션이다.

리 스 트 2.1 | hello3.html

<html><head><title>Hello Ajax version 3</title><style type='text/css'>* { font-family: Tahoma, Arial, sans-serif; }#helloTitle{ color: #48f; }</style><script type='text/javascript' src='prototype.js'> </script><script type='text/javascript'>window.onload=function(){ $('helloBtn').onclick=function(){ var name=$('helloTxt').value; new Ajax.Request( "hello3.jsp?name="+encodeURI(name), { method:"get", onComplete:function(xhr){ eval(xhr.responseText);

b 응답 수행 } } ); };

Page 62: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

32

Ajax 기초1부

};</script></head><body><div id='helloTitle'><h1>Hello, stranger</h1></div><p>Please introduce yourself by entering your namein the box below</p><input type='text' size='24' id='helloTxt'></input>&nbsp;<button id='helloBtn'>Submit</button></body></html>

앞에 나온 솔루션과 리스트 2.1을 비교해서 살펴보면 아주 조금만 변경되었다는 것을 알 수

있다. 여기서도 XHR 객체의 responseText 속성을 사용하여 응답 바디(response body)

를 읽을 수 있고, 그런 다음에 eval() 메서드로 바로 넘긴다❶.

여기서는 응답이 도착할 때 페이지의 제목 부분을 수정하고자 한다. 이를 처리하기 위

하여 DOM 조작을 수행할 필요가 있다. 리스트 2.2에서 볼 수 있는 바와 같이 메서드 호

출은 서버에서 직접 이루어질 수 있다.

리 스 트 2.2 | hello3.jsp

<jsp:directive.page contentType="text/plain"/><%String name = request.getParameter("name");%>document.getElementById('helloTitle').innerHTML = "<h1>Hello, <b><i>"+name+"</i></b></h1>";

일반적으로 MIME 타입을 설정하는 것이 좋지만, 여기서는 그렇게 하지 않았다. 왜냐하면

Prototype은 text/javascript MIME type을 충분히 인식할 수 있으며, 상황에 따라

서 그것을 자동으로 수행할 것이기 때문이다. 여기서는 Prototype의 강력한 성능을 보여

주기 위해서가 아니라 몇 가지 일반적인 원칙을 보여주기 위하여 수행 작업을 수동으로 처

리할 것이다.

Page 63: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

33

Ajax와의 통신 방법 2장

토론

이번 예제에서는 서버에서 클라이언트로 자바스크립트를 넘기는 원리를 제시하였다. 그

러나 그 과정 중에 몇 가지 흥미로운 문제가 드러났다. 이들 문제를 다음 예제에서 해결할

것이지만, 이들 문제의 성격이 어떠한지는 여기서 살펴보고자 한다.

첫 번째 문제는 서버 코드와 클라이언트 코드가 너무 밀접하게 결합되어 있다는 점이다.

JSP는 처리할 DOM 요소의 id 속성을 알아야 한다. 즉, 사용자 인터페이스에서 HTML

을 변경할 경우 서버 코드도 같이 수정해야 한다. 여기에서와 같이 코드가 작으면 큰 짐

이 되지 않지만, 코드가 조금 더 커지면 감당할 수 없게 된다.

앞에서 제시된 솔루션에서 두 번째 문제가 드러났다. 즉, innerHTML을 사용하면 더

이상 우아하고 간단하게 문제를 해결할 수는 없다. 페이지에서 하나의 요소를 업데이트

할 때마다 응답을 사용하는 한 여기서 드러난 문제점을 해결할 수 없다.

이 두 가지 문제를 다음 예제에서 집중해서 다룰 것이다. 다시 말해, 여러 개의 요소를

한 번에 업데이트하는 방법과 계층들 사이에서 결합의 밀접 정도를 줄이는 방법을 강구

할 것이다.

2.1.2 좋은코드생성규정활용하기

서버에서 자바스크립트를 생성할 때 코드 생성을 이용한다. 코딩 규약과 기본 규칙이 제

대로 만들어져 있을 경우 코드 생성은 재미있는 주제다. 코드 생성의 기본적인 규칙은 가

능한 한 가장 상위 레벨에서 코드를 생성하는 것이다.

다음 예제에서는 Hello World 애플리케이션이 조금 더 복잡하게 될 것이며, 코드 생성

의 강화 방법을 보여줄 것이다.

문제

서버에서 낮은 수준의 자바스크립트를 작성하면 서버 코드와 클라이언트 코드 사이에는

용인될 수 없을 정도의 밀접한 결합이 일어난다. 이렇게 되면 애플리케이션을 확장하기 어

려워지며, 불안정성도 높아진다.

또, 페이지의 종전 방문자 목록을 유지하고, 현재 방문자 이름도 보여주고자 한다. 서

버는 방문자들의 이름을 길게 혹은 짧게 분류할 것이며, 긴 이름과 짧은 이름에 대하여

Page 64: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

3�

Ajax 기초1부

별도의 목록을 제공할 것이다(다시 한 번 이야기하지만, 이것이 실제 업무 논리와는 맞지

않을 수 있으며, 이번 장에서 서버 코드를 간소화하기 위하여 이렇게 한다).

또한 데이터가 들어올 때 경고 메시지를 팝업으로 띄울 것이다. Hello World 애플리케

이션의 수정된 UI는 그림 2.2와 같다.

앞의 예제에서와 같이, 폼이 서버로 전송될 때마다 현재 이름은 제목 요소에 표시될 것

이다. 또한 방문자 목록이 좌측의 두 박스(box) 요소에 나누어서 들어갈 것이다. 그림 2.3

은 네 번째 Hello World이며, 여러 방문자가 다녀간 후의 화면이다.

그림 2.2 네 번째 Hello World의 UI. 폼 옆에 방문자 목록이 표시될 것이다.

그림 2.3 네 번째 Hello World의 UI. 여러 사람이 방문한 후의 화면이다. 여기서는 제목이 수정되었고,

좌측 목록이 업데이트되었으며, 경고 메시지가 떠 있음을 볼 수 있다. 이 모든 것이 서버에

서 생성된 한 번의 호출로 처리되었다.

Page 65: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

3�

Ajax와의 통신 방법 2장

솔루션

서버에서 응답이 올 때 클라이언트를 새로운 정보로 업데이트하고자 한다. 서버에서 보내

는 코드는 단순히 일부 데이터를 운반하는 수단이다. 따라서 서버에서 생성되는 자바스크

립트를 단순화하여, updateName() 함수만을 호출할 것이며, 데이터에서 인수를 넘기는

형식으로 처리할 것이다.

클라이언트 측에서는 리스트 2.3에서 볼 수 있는 바와 같이 직접 작성된 자바스크립트

로서 updateName() 함수를 정의할 필요가 있다. UpdateName() 함수가 추가된 모든

요구사항을 처리할 것이다.

리 스 트 2.3 | hello4.html

<html><head><title>Hello Ajax version 4</title><style type='text/css'>* { font-family: Tahoma, Arial, sans-serif; }#helloTitle{ color: #48f; }.sidebar{ background-color: #adf; color: navy; border: solid blue 1px; width: 180px; height: 200px; padding: 2px; margin: 3px; float: left;}</style><script type='text/javascript' src='prototype.js'> </script><script type='text/javascript'>window.onload=function(){ $('helloBtn').onclick = function(){ var name=$('helloTxt').value; new Ajax.Request( "hello4.jsp?name = "+encodeURI(name), { method:"get", onComplete:function(xhr){ eval(xhr.responseText); 응답 수행

} }

Page 66: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

36

Ajax 기초1부

); };};

function updateName(name,isLong){ API 정의

$('helloTitle').innerHTML= "<h1>Hello, <b><i>"+name+"</i></b></h1>"; var listDivId=(isLong) ? 'longNames' : 'shortNames'; $(listDivId).innerHTML+=name+"<br/>"; alert("Hey, we've got a visitor called '" +name+"' here");}

</script></head><body>

<div id='shortNames' class='sidebar'><h5>People I've met with short names</h5><hr/></div><div id='longNames' class='sidebar'><h5>People I've met with long names</h5><hr/></div><div><div id='helloTitle'><h1>Hello, stranger</h1></div><p>Please introduce yourself by entering your namein the box below</p><input type='text' size='24' id='helloTxt'></input>&nbsp;<button id='helloBtn'>Submit</button></div></body></html>

요구사항이 복잡해졌지만 서버 측 코드는 더 간단해졌다. 리스트 2.4의 JSP는 네 번째 예

제 애플리케이션에 필요한 데이터를 제공한다.

Page 67: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

37

Ajax와의 통신 방법 2장

리 스 트 2.4 | hello4.jsp

<jsp:directive.page contentType="text/plain"/><%String name = request.getParameter("name");boolean isLong = (name.length() > 8);%>updateName("<%= name %>",<%= isLong %>);

코드 길이나 처리하는 개념 개수 측면에서 JSP가 더 간단해졌다. 이 로직은 서버에서 사

용하기에 적절하며, 클라이언트와는 상위 수준의 API를 통해서 대화한다.

토론

이번 예제는 중요한 전환점으로서 한 번의 Ajax 호출로 UI의 여러 곳을 업데이트할 것이다.

이 시점에서, 예제 2에서 사용했던 간단한 innerHTML 방법은 더 이상 충분한 역할을 하지

못할 것이다. 이번 경우를 기준으로 보면, 요구사항들이 다소 부자연스러웠다. 그러나 실제

많은 애플리케이션에서는 여러 개의 업데이트 요구사항이 존재한다. 그 예를 들면 다음과 같다.

장바구니에 새로운 상품을 추가하면, 장바구니 목록에 1개의 행이 추가되고, 합계 금

액이 바뀌고, 배송비와 예상 배송일 등이 변경될 것이다.

데이터 그리드의 한 행이 업데이트되면 합계와 페이징 정보 등을 업데이트해야 할 수

도 있다.

왼쪽에 요약 목록이 있고 오른쪽에 선택된 상품의 세부 정보가 표시되는 2단 레이아

웃에서는 2개의 단이 너무 붙어있는 것처럼 보일 것이다.

자바스크립트 API를 정의하고 이 API에 대한 호출을 생성함으로써 여러 가지를 한꺼번에

업데이트해야 하는 쟁점 사항을 해결하였다. 여기서는 1개의 API 메서드를 정의하였고,

이 API를 한 번만 호출하였다. 그러나 더 정교한 애플리케이션에서는 API를 여러 번 호출

할 수 있고 여러 라인으로 구성된 스크립트를 만들어야 할 수 있다. DOM 요소 ID와 메서

드의 세부사항이 아닌 개념적인 용어로 말하는 원칙을 고수하는 한, 애플리케이션이 커지

더라도 이 전략은 제 기능을 수행할 수 있다.

서버에서 API 호출을 생성하는 것에 대한 대안으로, 원시 데이터(raw data)를 생성하

고 이것을 클라이언트로 넘겨서 파싱하는 방법이 있다. 이렇게 되면 리치 필드(rich field)

가 만들어지며, 이에 대해서는 이 장의 나머지 부분에서 자세히 다룰 것이다.

Page 68: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

38

Ajax 기초1부

2.2 JSON 소개

1장에서는 프로세싱을 서버에서 모두 처리하고, 미리 만들어진 HTML 내용을 브라우저

로 보내는 작업을 처리하면서 Ajax 기법을 살펴보았다. 2.1절에서는 HTTP 응답의 대체

페이로드(alternative payload)로서 자바스크립트를 보았다. 2.1절에서 중요한 것은 화면의

여러 부분을 한 번에 업데이트할 수 있었다는 점이었다. 동시에 클라이언트 측 코드와 서

버 측 코드 사이의 결합 정도를 낮은 수준으로 유지할 수 있었다.

처리 과정을 더 발전시킨다면, 계층마다 특정 기능을 맡아서 처리하도록 나눌 수 있다.

즉, 서버 측에서는 비즈니스 로직만 처리하고, 클라이언트 측에서는 애플리케이션 워크

플로우 로직만 처리하게 만들 수 있다. 이 설계가 씩 클라이언트(thick client) 아키텍처와

유사하지만, PC에 클라이언트를 설치하고 유지해야 하는 불편한 점은 없다.

이러한 유형의 설계에서 서버는 데이터(복잡하게 구조화될 가능성이 있음)를 클라이언

트로 전송할 수 있다. 이 장의 초반부에서 언급한 것처럼 데이터 형식을 상당히 자유롭게

유지할 수 있다. 현재, 두 가지의 주력 형식이 있는데, 하나는 JSON(JavaScript Object

Notation)이고, 다른 하나는 XML이다. 이 절에서는 JSON을 살펴보면서 데이터 중심의

Ajax가 무엇인지 설명할 것이다.

JSON 기초

몇 개의 예제를 살펴보기 전에 JSON을 먼저 소개할 것이다. JSON은 경량의 데이터 상호

교환 형식으로, 서버 측 여러 기술과 자바스크립트에서의 생성과 파싱이 쉽다. 완전한 데

이터 상호 교환이 이루어지기 위해서는 상호 교환 형식과 실제 객체 사이에서의 양방향 변

환이 진행되어야 한다. 이를 그림 2.4에서 설명하고 있다.

JSON의 반은 자바스크립트 언어 명세의 일부로서 무료로 제공되며, 다른 반은 서드파

티 라이브러리로서 사용될 수 있다. 이것이 무슨 말인지 이해가 잘 되지 않을 수 있다. 지

금부터 자세히 설명할 것이다.

먼저, JSON 선언이 어떻게 이루어지는지 살펴보자. 아래의 예제에서는 customers

변수를 선언하고, 이 변수에 details라는 이름의 배열 속성을 저장한다. 각 배열 요소는

각 고객 객체의 속성들의 모음이다. 여기서 각 고객 객체는 세 개의 속성, 즉 num, name,

city로 구성된다.

Page 69: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

39

Ajax와의 통신 방법 2장

var customers = { "details": [

{"num": "1","name":"JBoss","city":"Atlanta"},

{"num": "2","name":"Red Hat","city":"Raleigh"},

{"num": "3","name":"Sun","city":"Santa Clara"},

{"num": "4","name":"Microsoft","city":"Redmond"}

]

} ;

그림 2.4 라운드 트립 데이터 상호 교환 형식으로서의 JSON

여기서는 JSON 구문을 사용하여 변수를 간편하게 선언하였다. 함께 작성한 것이라고는 자

바스크립트 기본 구문뿐이다. 자바스크립트 객체(조합 배열과 같은 기능 수행)를 구분하기

위하여 중괄호({ })를 사용하였고, 자바스크립트 배열 객체를 구분하기 위하여 대괄호([ ])를

사용하였다. 자바스크립트 언어의 핵심 기술을 더 자세히 배우려면 4장에서 더 많은 내용

을 볼 수 있을 것이다.

일단, 변수를 선언하였으므로 자바스크립트 기본 구문을 사용하여 변수의 값을 쉽게

읽을 수 있다.

alert (customers.details[2].name);

이 코드는 “Sun”이라는 문자열을 경고 박스에 표시할 것이다. 지금까지 작업한 것이라고

는 자바스크립트 기본 구문을 코딩하고, 이것을 JSON으로 호출한 것뿐이다.

클라이언트 측 객체를

JSON으로 변환JSON을 서버 측 객체로 변환

서버 측 객체를 JSON으로 변환

JSON을 클라이언트 측 객체로 변환

서버 브라우저

클라이언트 측 객체를

JSON으로 변환JSON을 서버 측 객체로 변환

서버 측 객체를 JSON으로 변환

JSON을 클라이언트 측 객체로 변환

서버 브라우저

Page 70: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

�0

Ajax 기초1부

변수를 생성하기 위하여 문자열 변수를 만든 다음에 eval()을 사용하여 수행작업을

진행할 수 있다.

var customerTxt = "{ 'details': [ " +

"{'num': '1','name':'JBoss','city':'Atlanta'}, " +

" {'num': '2','name':'Red Hat','city':'Raleigh'}, " +

" {'num': '3','name':'Sun','city':'Santa Clara'}, " +

" {'num': '4','name':'Microsoft','city':'Redmond'}" +

"] }" ;

var cust = eval ('(' + customerTxt + ')');

alert (cust.details[0].city); //shows 'Atlanta'

문자열을 선언할 때 이와 같이 코드로 작성해야 할 이유는 없다. 그러나 문자열을 다른 방

법, 즉 Ajax 요청으로 응답하는 것과 같이 처리하면 멋진 데이터 형식을 가지게 된다. 이

데이터 형식으로는 복잡한 데이터 구조를 쉽게 표현할 수 있고, 자바스크립트 인터프리터

에 의해 데이터를 매우 쉽게 원래대로 되돌릴 수 있다.

이 시점에서 데이터 상호 교환 형식의 반을 확보하게 된다. 자바스크립트 기본 구문에

는 자바스크립트 객체를 JSON 문자열로 변환하는 방법이 없다. 그러나 http://www.

json.org에 가면 서드파티 라이브러리가 있으며, stringify()라는 함수를 사용하여 클

라이언트 측 객체를 JSON으로 변환할 수 있다. 또 JSON 라이브러리에 있는 parse()

메서드를 사용하면 eval() 사용을 훌륭하게 대체할 수 있다.

또 json.org에 가면 여러 서버 측 언어에서 JSON을 생성하고 사용하는 라이브러리를

발견할 수 있다. 이들 툴을 사용하면, 클라이언트와 서버는 웹 애플리케이션의 사용자 세

션 전체 과정상에서 구조화된 데이터를 JSON으로 이리저리 전송할 수 있다.

이제, Hello World 예제로 돌아가서, 클라이언트에서 JSON 응답을 어떻게 처리하는

지 그 방법을 살펴보자.

2.2.1 서버에서JSON생성하기

JSON에 대해서는 살펴볼 내용이 많으므로 JSON을 두 부분으로 나누어서 살펴보고자 한

다. 먼저, 브라우저에 내장되어 있는 기능을 사용하여 JSON 데이터를 파싱할 수 있다는

것을 보여줄 것이며, 그리고 일반적인 자바스크립트 응답을 JSON 객체 정의로 대체하는

방법을 살펴볼 것이다.

Page 71: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

��

Ajax와의 통신 방법 2장

문제

요청에 대해서 서버는 잘 구조화된 데이터로 응답해야 하며, 데이터의 제출 방법을 클라

이언트가 결정해야 한다.

솔루션

이번에도 종전과 같이 Hello World 예제를 사용할 것이며, 특별히 이번 예제에서는 이름

만이 아니라 몇 가지의 개인 정보도 반환할 것이다.

입력된 사람의 이니셜. 이것은 서버에서 문자열 조작에 의해 계산된다.

그 사람이 좋아하는 물건의 목록

그 사람이 좋아하는 요리. 목록은 조합 배열로 처리된다.

그림 2.5는 응답을 수신한 후의 애플리케이션이다.

종전의 예제들과 같이 서버 측 작업은 매우 조용하게 진행되며, 사실 모든 이름에 대해

서 동일한 데이터(이니셜은 빼고)가 반환될 것이다. 이것은 더미 데이터에서 실제 데이터

베이스에 이르기까지 모두 적용되는 간단한 방법이다. 그러나 자바 고유의 서버 측 특징

을 너무 많이 소개하여 범위를 좁히고 싶지는 않다. 왜냐하면 클라이언트 측 코드는 자바

뿐만 아니라 다른 많은 서버 측 기술을 활용할 수 있기 때문이다.

그림 2.5 JSON으로 처리된 Hello World 애플리케이션은 풍부한 데이터를 보여준다.

따라서, 여기서는 먼저 간단한 방법으로 처리하기 위하여 자바스크립트의 내장된 JSON

파싱 기능만을 사용할 것이다. 클라이언트 측 코드는 리스트 2.5와 같을 것이다.

Page 72: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

�2

Ajax 기초1부

리 스 트 2.5 | hello5.html

<html><head><title>Hello Ajax version 5</title><style type='text/css'>* { font-family: Tahoma, Arial, sans-serif; }#helloTitle{ color: #48f; }.sidebar{ background-color: #adf; color: navy; border: solid blue 1px; width: 180px; height: 200px; padding: 2px; margin: 3px; float: left;}</style><script type='text/javascript' src='prototype.js'> </script><script type='text/javascript'>window.onload=function(){ $('helloBtn').onclick = function(){ var name=$('helloTxt').value; new Ajax.Request( "hello5.jsp?name = "+encodeURI(name), { method:"get", onComplete:function(xhr){

JSON 응답 파싱

B var responseObj = eval("("+xhr.responseText+")"); update(responseObj); } } ); };};

function update(obj){ $('helloTitle').innerHTML = "<h1>Hello, <b><i>" +obj.name

C 파싱된 객체 사용 +"</i></b></h1>"; var likesHTML = "<h5>" +obj.initial +"likes...</h5><hr/>"; for (var i=0;i<obj.likes.length;i++){

Page 73: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

�3

Ajax와의 통신 방법 2장

likesHTML += obj.likes[i]+"<br/>"; } $('likesList').innerHTML = likesHTML; var recipeHTML = "<h5>" +obj.initial +"'s favorite recipe</h5>"; for (key in obj.ingredients){ recipeHTML += key +" : " +obj.ingredients[key] +"<br/>"; } $('ingrList').innerHTML=recipeHTML;}

</script></head><body>

<div id='likesList' class='sidebar'><h5>Likes</h5><hr/></div><div id='ingrList' class='sidebar'><h5>Ingredients</h5><hr/></div><div><div id='helloTitle'><h1>Hello, stranger</h1></div><p>Please introduce yourself by entering your name in the box below</p><input type='text' size='24' id='helloTxt'></input>&nbsp;<button id='helloBtn'>Submit</button></div></body></html>

이런 식으로 JSON을 이용하면 작업이 매우 간단해진다. JSON 응답을 파싱하기 위하여

eval()을 사용한다❶. 파싱하기 전에 문자열 주변에 괄호를 추가한다는 점을 기억하기

바란다. update() 메서드에서 파싱된 객체를 사용하는 것은 당연한 일이다❷. 왜냐하면

이것은 또 다른 자바스크립트 객체이기 때문이다.

Page 74: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

��

Ajax 기초1부

서버 측 코드를 살펴보면 조금 더 명확하게 이해할 것이다. 리스트 2.6은 다섯 번째

JSP 파일이다.

리 스 트 2.6 | hello5.jsp

<jsp:directive.page contentType="application/javascript"/>

<%

String name=request.getParameter("name");

%>

{

name: "<%=name%>",

initial: "<%=name.substring(0,1).toUpperCase()%>",

likes: [ "JavaScript", "Skiing", "Apple Pie" ],

ingredients: {

apples: "3kg",

sugar: "1kg",

pastry: "2.4kg",

bestEaten: "outdoors"

}

}

앞에서 이야기한 것처럼 여기서 생성된 대부분의 데이터는 더미 데이터다. 여기서 관심을

가져야 할 내용은 변수 값을 적절한 곳에 넣으면서 JSON 문자열을 얼마나 간단하게 생성

하였는가, 이다.

토론

이번 예제에서는 클라이언트에서 JSON을 파싱하는 것이 매우 쉬우며, 이 한 가지만으로

도 JSON을 사용해야 할 충분한 이유가 있다는 것을 보여주었다. 그러나 그림 2.4를 다시

보면, 클라이언트와 서버 사이에서 4단계에 걸쳐 이루어지는 전체 라운드 트립 중 하나인

‘JSON을 클라이언트 측 객체로 변환’하는 부분만 다루었다는 것을 알 수 있다. 이번 예제

와 같이 규모가 작은 애플리케이션의 경우 지금까지 한 것만으로도 충분하다. 그러나 애

플리케이션이 더 커져서 더 복잡한 데이터를 처리해야 할 경우 전체 과정을 자동으로 처

리하여 이로부터 자유로워져서, 서버 측에서는 비즈니스 로직에, 클라이언트 측에서는 전

송하는 코드에만 집중해야 할 필요가 있다. JSON에 관련된 예제를 1개 더 살펴볼 것이며,

이 예제에서는 클라이언트와 서버 사이에서 이루어지는 4단계의 전체 라운드 트립을 실행

한다.

Page 75: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

��

Ajax와의 통신 방법 2장

2.2.2 전체라운드트립에서JSON을사용하여데이터처리하기

클라이언트 콜백을 작성할 때 JSON을 많이 사용한다. 왜냐하면 이렇게 하면 모든 작업

을 아주 간단하게 처리할 수 있기 때문이다. 그러나 요청 데이터를 서버로 넘길 때 표준

HTTP 질의 문자열을 사용하였으며, 그런 다음에 JSON 응답을 직접 구성하였다. 브라우

저와 서버 사이의 모든 통신을 JSON으로 관리할 경우 코딩량을 많이 줄일 수 있다.

만족도를 더 높이기 위하여 몇 개의 서드파티 라이브러리를 사용해야 할 것이다. 일단,

코드를 살펴보면서 코딩 작업이 얼마나 편해졌는지 확인할 것이다.

문제

애플리케이션 계층들과 HTTP 사이의 모든 인터페이스에 JSON을 적용하고자 한다. 이렇

게 되면, 클라이언트 코드는 순수하게 자바스크립트 객체로 작성되고, 서버 코드는 순수

하게 자바(혹은 PHP, .NET, 혹은 다른 언어) 객체로 작성될 수 있다.

솔루션

설계에 어떤 차이가 있는지 확인하기 위하여 그림 2.4를 참고할 것이다. 브라우저에서 응

답 텍스트를 자바스크립트 객체로 변환하는 4단계를 이미 처리하였다. 그렇지만 클라이언

트에서 객체를 JSON으로 변환하는 것을 고려할 필요가 있다. 이렇게 하기 위하여 www.

json.org에 있는 json.js 라이브러리를 사용해야 할 것이다. 리스트 2.7은 이것의 처리 방

법을 보여준다.

리 스 트 2.7 | hello5a.html

<html><head><title>Hello Ajax version 5a</title><style type='text/css'>* { font-family: Tahoma, Arial, sans-serif; }#helloTitle{ color: #48f; }.sidebar{ background-color: #adf; color: navy; border: solid blue 1px; width: 180px; height: 200px;

Page 76: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

�6

Ajax 기초1부

padding: 2px; margin: 3px; float: left;}</style><script type='text/javascript' src='prototype.js'> </script><script type='text/javascript' src='json.js'> </script>

BJSON 라이브러리 인클루딩

<script type='text/javascript'>window.onload = function(){ $('helloBtn').onclick = function(){ var name = $('helloTxt').value; new Ajax.Request( "hello5a.jsp", { postBody:JSON.stringify({name:name}),

C

객체를 JSON으로 변환

onComplete:function(xhr){ var responseObj = JSON.parse(xhr.responseText);

DJSON을 객체로 변환

update(responseObj); } } ); };};

function update(obj){ $('helloTitle').innerHTML = "<h1>Hello, <b><i>"+obj.name+"</i></b></h1>"; var likesHTML = "<h5>"+obj.initial+" likes...</h5><hr/>"; for (var i=0;i<obj.likes.length;i++){ likesHTML+=obj.likes[i]+"<br/>"; } $('likesList').innerHTML=likesHTML; var recipeHTML="<h5>"+obj.initial+"'s favorite recipe</h5>"; for (key in obj.ingredients){ recipeHTML+=key+" : "+obj.ingredients[key]+"<br/>"; } $('ingrList').innerHTML=recipeHTML;}

</script></head><body>

<div id='likesList' class='sidebar'><h5>Likes</h5><hr/></div>

Page 77: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

�7

Ajax와의 통신 방법 2장

<div id='ingrList' class='sidebar'><h5>Ingredients</h5><hr/></div><div><div id='helloTitle'><h1>Hello, stranger</h1></div><p>Please introduce yourself by entering your name in the box below</p><input type='text' size='24' id='helloTxt'></input>&nbsp;<button id='helloBtn'>Submit</button></div></body></html>

첫 번째로 해야 할 일은 json.js 라이브러리를 포함시키는 것이다❶. json.js 라이브러리를

포함시킨 상태에서는 JSON.parse() 메서드를 사용하여 응답 처리 코드를 단순화할 수

있다❸. 더 중요한 것은, 요청 구성 방법을 다시 생각할 수 있다는 점이다.

지금까지 질의 문자열에서 데이터를 넘길 때 서버로 GET 요청을 보냈다. 데이터를 요

청할 때는 이것이 좋지만, 정보를 업데이트하거나 더 복잡한 요청을 서버로 보내고 싶을

때는 POST 요청을 사용하는 것이 더 좋을 수 있다. POST 요청에는 하나의 바디와 여러

개의 헤더가 들어가며, 바디를 원하는 텍스트에 넣을 수 있다. 여기서는 JSON을 사용할

예정이다.

요청 전송에 여전히 Prototype을 사용하고 있으며, 이제는 Ajax.Request 구성자에 대

한 옵션들과 함께 postBody 속성을 넘긴다. 이것의 값은 JSON.stringify()를 호출

한 결과다❷. stringify()의 인수로는 자바스크립트 객체가 들어가며, 이를 통해 순환

이 이루어지며, 이 가운데 JSON으로의 변환도 처리된다. 따라서 POST 바디에는 URL-

인코딩된 키-값 쌍이 포함되지 않을 것이며, HTML 폼이 아니라 JSON 문자열로부터 전

송되었다면 다음과 같이 될 것이다.

{ name: ‘dave’ }

이와 같이 간단한 규모의 구조적인 데이터의 경우, 이 방식이 과도하게 여겨질 수 있지만

매우 복잡한 데이터도 이 방식으로 처리할 가능성이 있으므로 알아두는 것이 좋다.

Page 78: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

�8

Ajax 기초1부

이제 클라이언트 측의 솔루션을 파악하였으므로 서버 측 솔루션으로 눈을 돌려보자. 여기

나온 예제들에서는 서버에서 자바를 사용하였으며, 자바는 JSON에 관해 알지 못한다. 자

바뿐만 아니라 대부분의 서버 측 언어들이 JSON을 알지 못한다. 따라서 전송된 응답을

처리하려면 서드파티 라이브러리를 사용해야 할 것이다.

서버 측 기술이 무엇이든지 상관없이, 해당 기술에 적합한 JSON 라이브러리를 www.

json.org(페이지의 하단에서 스크롤 다운)에서 찾을 수 있다. 여기서는 Json-lib를 선택

하였으며, 이것은 자바 라이브러리용으로 나온 도우 크록포드(Doug Crockford)의 오리지

널 JSON을 기반으로 하고 있다.

Json-lib를 사용하는 일은 간단하다. JSON은 구조적인 데이터를 매우 유연한 방법으

로 인코딩하고, 자바는 타입에 엄격한 언어이므로, 이 둘은 근본적으로 융합되지 않는다.

그럼에도 불구하고 Json-lib를 사용하면 큰 불편 없이 필요한 작업을 잘 처리하였다. 리

스트 2.8에서 자세한 내용을 살펴보자.

리 스 트 2.8 | hello5a.jsp

<jsp:directive.page contentType="application/javascript" import="java.util.*,net.sf.json.*" B JSON 클래스 임포트

/><%String json=request.getReader().readLine(); C POST 바디 읽기

JSONObject jsonObj=new JSONObject(json); D JSON 문자열 파싱

String name=(String)(jsonObj.get("name")); 파싱된 객체 읽기e

jsonObj.put("initial", name.substring(0,1).toUpperCase());

새로운 값들 추가f

String[] likes=new String[] { "JavaScript", "Skiing", "Apple Pie" };jsonObj.put("likes",likes);

Map ingredients=new HashMap();ingredients.put("apples","3kg");ingredients.put("sugar","1kg");ingredients.put("pastry","2.4kg");ingredients.put("bestEaten","outdoors");jsonObj.put("ingredients",ingredients);%><%=jsonObj%> g 객체를 JSON으로 쓰기

Page 79: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

�9

Ajax와의 통신 방법 2장

Json-lib 클래스를 사용하려면 net.sf.json 패키지를 임포트해야 한다. 이 임포트 작업은

<jsp:directive.page> 태그에서 처리한다❶. 이제 코드를 살펴보자.

처음으로 직면하는 문제는 POST 바디를 디코딩하는 것이다. 다른 많은 웹 기술처럼

자바 Servlet API는 HTML 폼에서 전송된 POST 요청을 쉽게 처리하도록 설계되었다.

JSON 요청 바디에서 HttpServletRequest.getParameter()를 사용할 수는 없

지만 java.io.Reader를 통해서 요청에 있는 JSON 문자열을 읽어야 할 필요가 있다

❷. 다른 기술들에 대해서도 이와 비슷한 특징을 사용할 수 있다. PHP를 사용할 경우,

$HTTP_RAW_POST_DATA 변수를 사용하면 된다. 그리고 .NET 라이브러리를 사용할 경

우, 자바 클래스들에 대하여 여기서 했던 것처럼 HttpRequest 객체에서 InputStream

을 확보하면 될 것이다.

이제 자바로 돌아가보자. JSON 문자열을 확보한 다음에는 이것을 객체로서 파싱한다

❸. 타입에 엄격하지 않은 JSON과 타입에 엄격한 자바가 기본적으로는 융합되지 않으므

로 Json-lib 라이브러리에서는 파싱된 JSON 객체를 표현하기 위하여 JSONObject 클

래스를 정의한다. 이제, get() 메서드를 사용하여 파싱된 객체를 읽어 들일 수 있고❹,

요청으로부터 이름을 추출할 수 있다.

들어온 JSON 객체를 변환하였으므로 이것을 적절하게 처리해야 하며, 그런 다음에 클

라이언트로 다시 보내야 한다. JSONObject 클래스는 다른 데이터를 객체로 추가하기 위

하여 스트링, 배열, 자바 Map(즉, 조합 배열)과 같은 간단한 변수 타입을 쓸 수 있다❺.

일단 객체를 수정하였으면, 이것을 다시 변환하며❻, 응답할 때에 브라우저로 다시 전송

한다.

이로써 모든 것이 끝났다! 이제 클라이언트로부터 객체를 전송하였고, 서버에서 객체

를 수정하였으며, 클라이언트로 다시 반환하였다.

토론

지금까지 나온 예제들 중에서 이번 예제가 가장 복잡했으며, 여기서는 텍스트 기반 HTTP

프로토콜 상단의 네트워크 상에서 구조적인 객체를 이리저리 통신하는 방법을 보여주었다.

라이브러리들을 활용함으로써 클라이언트와 서버 모두 JSON 구문을 이해할 수 있기 때

문에 파싱 코드를 작성하지 않아도 되었다. 그러나 앞에서 언급한 것처럼 JSON은 타입이

엄격하지 않은 스크립팅 언어와 사용하기에 적합하다. 따라서 약간의 해석이 일부 요구되

Page 80: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

�0

Ajax 기초1부

었다. 이와 같은 시스템의 목표는 네트워크상에서 도메인 객체를 적절하게 변환하는 것이

다. 도메인 객체 그래프가 자바나 C#과 같은 언어로 작성된다면 일반적인 해시와 배열로

직접 해석한 후에 JSON 변환 메서드로 넘겨야 한다. 라운드 트립 전체를 처리하는 코딩

에서 가장 힘든 부분은 JSP에 있었다. 여기서는 JSONObject용 데이터 목록과 Map을 조

립하였다. 자바의 경우에 이 문제가 특히 부각되었으며, Ruby나 PHP와 비교해서 자바에

는 조합 배열을 간단하게 정의할 수 있는 구문이 부족하다.

대괄호에서 꺽음 괄호까지 1

클라이언트와 서버 모두에서 이해될 수 있는 또 다른 텍스트 기반 형식으로 XML이 있다.

대부분의 서버 측 언어는 XML을 잘 지원한다. 따라서 서버에서 JSON보다 XML과 작업

하는 것이 더 쉽다는 것을 알게 된다. 다음 절에서는 XML과 Ajax를 볼 것이며, JSON보

다 작업하는 것이 더 쉬운지 확인할 것이다.

2.3 Ajax에서XML과 XSLT 사용하기

XML은 구조적인 데이터를 표현하는 성숙된 기술로서, 대부분의 프로그래밍 언어에서 해

당 언어의 핵심 부분으로서 아니면 안정된 라이브러리나 확장 기능을 통해서 XML을 지

원한다. 이 장의 나머지 부분에서는 얼마나 다양한 XML 기술들이 있는지, 그리고 Ajax의

기본적인 통신 기술들로는 어떠한 것들이 있는지 이야기할 것이다.

지금까지 앞에서 Ajax 요청에 사용해 온 XMLHttpRequest 객체에는 XML을 지원하

는 특수한 특징이 내장되어 있다. 지금까지, HTTP 응답의 바디를 텍스트로서 추출하고,

거기서 다시 파싱 작업을 했었다. 웹 브라우저의 자바스크립트에 대하여 사용할 수 있는

기본 XML 파서는 없다. 그러나 XHR 객체가 XML 응답을 파싱할 수 있으며, 이를 다음

예제에서 확인할 것이다.

2.3.1 서버에서생성된XML파싱하기

앞에 나왔던 여러 Hello World 애플리케이션에서는 HTML, 자바스크립트, JSON 응답을

1 JSON을 대괄호에, XML을 꺽음괄호에 비유하고 있다. JSON은 자바스크립트 문법의 대괄호 ‘[]’를 자주 사용하며, XML은 태그 표시로 꺽음괄호

(‘<>’)를 자주 사용한다는 의미이다.

Page 81: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

��

Ajax와의 통신 방법 2장

서버에서 생성했다. 이 모든 형식은 서버보다는 브라우저에 맞게 설계되었다. 이와는 달리,

XML은 서버 프로세스들 사이의 통신에 주로 사용되며, 여기에는 RSS 배포 피드부터 시

작해서 XML-RPC나 SOAP와 같은 웹 서비스 프로토콜에 이르기까지 다양한 기술이 활

용된다. 도메인 객체부터 클라이언트까지 정보를 전송할 경우, 서버 측에 관련된 많은 기

술은 객체 변환에 대한 지원을 XML로서 제공한다.

이들 시나리오를 서버 입장에서 본다면, 데이터를 XML로 송신하는 것이 쉽다는 것을

알 수 있다. 이것이 앞으로 유용한 방법으로 자리잡는다면, XML을 클라이언트에서 처리

할 필요가 있을 것이다. 먼저, XHR 객체 내부에서 XML을 어떻게 지원하는지 살펴볼 것

이다. JSON과 같이 XML은 구조적인 데이터의 교환 형식이다. 이 둘을 비교하는 가장

좋은 방법은 이 둘이 같은 작업을 처리하도록 해보는 것이다. 따라서 앞 절에서와 같은

방법을 따라서, 좋아하는 품목과 선호하는 메뉴 목록을 표시하도록 해볼 것이다(그림 2.6

참고).

그림 2.6 XML 응답을 파싱한 후의 Hello World 예제. 여섯 번째 예제

문제

서버는 구조적인 데이터를 XML로서 전송하며, 이 데이터를 클라이언트에서 파싱해야 한다.

솔루션

클라이언트 측에서 XML을 처리하는 첫 번째 단계는 XHR을 사용하여 응답을 구조적인

XML 문서로 파싱하는 것이다. 두 번째 단계는 DOM(Document Object Model)이라고 하는

W3C 표준을 사용하여 파싱된 XML 문서를 읽는 것(어쩌면 쓰는 것)이다. HTML 웹 페이

지와 작업하는 DOM 시스템을 자바스크립트 코드로 이미 만들었다. 좋은 소식은 Ajax에

Page 82: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

�2

Ajax 기초1부

서 전달된 XML 문서와 작업할 때 기존의 기법들을 활용할 수 있다는 것이다. 리스트 2.9

는 여섯 번째 Hello World 애플리케이션의 전체 소스다.

리 스 트 2.9 | hello6.html

<html><head><title>Hello Ajax version 6</title><style type='text/css'>* { font-family: Tahoma, Arial, sans-serif; }#helloTitle{ color: #48f; }.sidebar{ background-color: #adf; color: navy; border: solid blue 1px; width: 180px; height: 200px; padding: 2px; margin: 3px; float: left;}</style><script type='text/javascript' src='prototype.js'> </script><script type='text/javascript'>window.onload = function(){ $('helloBtn').onclick = function(){ var name=$('helloTxt').value; new Ajax.Request( "hello6.jsp?name="+encodeURI(name), { method:"get", onComplete:function(xhr){ var responseDoc = xhr.responseXML;

B 응답을 XML로서 읽기 update(responseDoc); } } ); };};

function update(doc){ var personNode = doc .getElementsByTagName('person')[0];

C DOM을 사용하여 데이터 추출

var initial = personNode .getAttribute('initial');

Page 83: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

�3

Ajax와의 통신 방법 2장

var nameNode = personNode .getElementsByTagName('name')[0]; var name = nameNode.firstChild.data; var likesNode = personNode .getElementsByTagName('likes')[0]; var likesList = likesNode .getElementsByTagName('item'); var likes = []; for (var i=0;i<likesList.length;i++){ var itemNode = likesList[i]; likes[i] = itemNode .firstChild.data; } var recipeNode = personNode .getElementsByTagName('recipe')[0]; var recipeNameNode = recipeNode .getElementsByTagName('name')[0]; var recipeName = recipeNameNode.firstChild.data; var recipeSuggestNode = recipeNode .getElementsByTagName('serving-suggestion')[0]; var recipeSuggest = recipeSuggestNode.firstChild.data;

C DOM을 사용하여

데이터 추출

var ingredientsList = recipeNode .getElementsByTagName('ingredient'); var ingredients = {}; for(var i=0;i<ingredientsList.length;i++){ var ingredientNode = ingredientsList[i]; var qty = ingredientNode.getAttribute("qty"); var iname = ingredientNode.firstChild.data; ingredients[iname] = qty; }

$('helloTitle').innerHTML = "<h1>Hello, <b><i>" +name +"</i></b></h1>"; var likesHTML = '<h5>' +initial +' likes...</h5><hr/>'; for (var i=0;i<likes.length;i++){ likesHTML += likes[i]+"<br/>"; } $('likesList').innerHTML = likesHTML;

d HTML 조립

var recipeHTML = "<h5>" +initial +"'s favorite recipe is "

Page 84: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

��

Ajax 기초1부

+recipeName +"</h5>"; for (key in ingredients){ recipeHTML += key+" : " +ingredients[key] +"<br/>"; } recipeHTML+="<br/><i>" +recipeSuggest +"</i>"; $('ingrList').innerHTML=recipeHTML;

d HTML 조립

}

</script></head><body>

<div id='likesList' class='sidebar'><h5>Likes</h5><hr/></div><div id='ingrList' class='sidebar'><h5>Ingredients</h5><hr/></div><div><div id='helloTitle'><h1>Hello, stranger</h1></div><p>Please introduce yourself by entering your name in the box below</p><input type='text' size='24' id='helloTxt'></input>&nbsp;<button id='helloBtn'>Submit</button></div></body></html>

이 소스에서 첫 번째 단계는 지금까지 나온 것 중에서 가장 쉽다. responseText가 아닌

responseXML 속성을 읽음으로써❶ 응답을 XML 문서 객체로서 간단하게 검색할 수 있다.

그 다음에 XML 객체를 수락하기 위해 update() 함수를 다시 썼다. 이제 XML 객체로부

터 개별 데이터 요소를 읽어 오고❷ 데이터를 HTML 컨텐츠로서 제출하면 된다❸.

실제로, 이들 단계 중 어떤 것도 어렵지 않다. 그러나 이들 단계는 오히려 더 길어졌

Page 85: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

��

Ajax와의 통신 방법 2장

다. getElementsByTagName(), getAttribute(), firstChild와 같은 DOM 메서

드와 속성을 사용할 경우, 원하는 데이터에 집중할 수 있지만, 이것을 단계별로 한 단계

씩 해야 할 필요가 있다. 이들 속성과 메서드는 HTML 문서로 작업할 때 사용하던 것과

동일하다. 따라서 이것들을 여기서 따로 다루지는 않을 것이다. HTML을 조작하기 위해

DOM을 사용했다면 모든 것이 비슷하게 보일 것이다. 그러나 DOM을 사용하지 않았다면

이들 메서드에 대한 정보를 인터넷에서 많이 얻을 수 있을 것이다.

일단 필요로 하는 데이터를 추출하였으므로, UI 업데이트에 필요한 HTML 컨텐츠를

단순히 조립한다.

서버에서 XML을 생성하는 것이 의미가 있다는 가정을 전제로 많은 시나리오를 논의하

였다. 이 예제에서 논의할 내용을 간소화하고 하나의 프로그래밍 언어에만 적용되는 기

술들을 너무 깊이 살펴보는 것을 방지하기 위하여 JSP에서 XML을 직접 생성하기로 한다.

이를 처리하는 JSP는 리스트 2.10과 같다.

리 스 트 2.10 | hello6.jsp

<jsp:directive.page contentType="text/xml"/><%String name=request.getParameter("name");%><person initial="<%=name.substring(0,1).toUpperCase()%>"> <name><![CDATA[<%=name%>]]></name> <likes> <item>JavaScript</item> <item>Skiing</item> <item>Apple Pie</item> </likes> <recipe> <name>apple pie</name> <ingredient qty="3kg">apples</ingredient> <ingredient qty="1kg">sugar</ingredient> <ingredient qty="2.4kg">pastry</ingredient> <serving-suggestion> <![CDATA[Best Eaten Outdoors! Mmm!]]> </serving-suggestion> </recipe></person>

여기서는 응답의 contentType를 text/xml로 설정하였다는 점에 주목하기 바란다. 다

Page 86: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

�6

Ajax 기초1부

른 모든 예제에서 이렇게 하고 있으며, 이것은 좋은 코딩 습관이다. 그러나 이번 예제

에서 이렇게 한 것에는 실제로 더 큰 이유가 있다. MIME 타입을 xml(text/xml이나

application/xml)로 설정하지 않았으면 XHR 객체의 responseXML 속성이 제대로 들

어가지 않았을 것이다.

JSP의 나머지 부분은 평범하다. 경험이 많은 자바나 XML 코더에게는 XML을 텍스트

로 작성하는 것이 아주 간단하게 보일 것이다. 더 견고한 솔루션은 XML 문서를 프로그

래밍 방식으로 생성하기 위해 JDOM과 같은 라이브러리를 사용하며, 실제 업무에서는

JDOM과 같은 라이브러리를 사용할 것을 권장한다. 그러나 여기서는 아주 간단하게 처

리할 것이며, 그 이유는 자바 고유의 라이브러리에 너무 깊이 들어가지 않고도 처리할 수

있는 방법을 보여주기 위해서다. 무엇보다도 이 책의 주된 목적은 클라이언트 측 기법을

가르치는 것이며, PHP, Ruby, .NET이 아닌 자바를 선택한 것에는 다른 특별한 이유가

없고, 그냥 그렇게 한 것이다.

코드로 다시 돌아가 보자. 대부분의 경우에 더미 데이터가 포함되는 XML 문서 템플릿

을 생성하였으며, 중간에 몇 개의 동적인 값을 추가하였다. 이 예제를 보면서 몇 가지 내

용을 점검해 보자.

토론

XML과 Ajax를 함께 사용하는 것이 지금보다 처음에 오히려 더 좋았다. 초기에 XHR 객

체에서 XML을 특별하게 지원하게 되었을 때 모든 것이 좋아 보였다. 그러나 DOM을 이

용하여 XML 응답을 처리하는 것은 지루하면서 감격스럽지도 않은 일이었다. 이러한 코딩

경험을 한 많은 개발자들은 XML을 떠나 JSON을 선호하기에 충분하였다.

DOM은 언어와 무관한 표준으로서, 자바, PHP, C++, .NET에서 구축할 수 있는 시

스템이며, 이미 익숙한 자바스크립트/웹 브라우저 버전도 있다. 웹 브라우저 외부에서의

XML 사용과 관련하여 DOM이 그다지 널리 사용되지는 않고, XML을 훨씬 더 적절하게

사용하게 만드는 다른 XML 기술들이 많이 있다. 다행히, 이들 기술을 브라우저에서도

사용할 수 있으며, 다음 절에서는 Ajax와 XML을 훨씬 더 잘 활용하기 위하여 이들 기술

을 어떻게 응용할 수 있는지 그 방법을 살펴볼 것이다.

Page 87: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

�7

Ajax와의 통신 방법 2장

2.3.2 XSLT와XPath를이용하여XML처리

앞 예제에서 보았던 XML 기법은 모든 XHR 객체 시스템을 통해서 무료로 사용할 수 있는

핵심 기능이다. DOM과 직접 작업하는 것은 즐거운 일이 아니다. 특히 다른 언어에서 최

신 XML 처리 기술을 사용해 본 경우에는 더욱 그러하다. 이러한 툴들 중에서 가장 일반

적인 것으로는 XPath 질의와 XSLT(Extensible Stylesheet Language Transformation) 트

랜스폼이 있다.

XPath는 XML 문서에서 데이터를 추출하는 언어다. 리스트 2.9에서는 한 번에 하나의

노드에 집중해야 했다. 그러나 XPath를 사용하면 하나의 라인으로 많은 노드를 처리할

수 있다. XSLT는 XML 기반의 템플릿 작성 언어로서, 이것을 사용하면 XML 문서에서

HTML과 같은 다양한 종류의 컨텐츠를 더 쉽게 생성할 수 있으며, 또한 지금까지 해왔던

것보다 프리젠테이션에서 로직을 더 잘 분리할 수 있다. XSLT 스타일 시트는 내부적으

로 XPath를 사용하여 데이터를 프리젠테이션으로 연결한다.

XSLT 트랜스폼과 XPath 질의를 파이어폭스나 인터넷 익스플로러와 같은 여러 브라

우저에서 사용할 수 있다. 더 좋은 것은 이것들이 자바스크립트 엔진에서 지원하는 네이

티브 객체라서 성능이 좋다는 점이다. 사파리는 아직도 네이티브 XSLT 프로세서를 제공

하지 못한다. 따라서 파이어폭스가 없는 Mac 사용자를 지원해야 할 경우 이것은 좋은 옵

션이 아니다.

다음 예제에서는 Prototype을 그냥 두고, Sarissa 라이브러리를 사용할 것이다. 이렇

게 해서 크로스 브라우저를 지원하는 간단한 XSLT와 XPath를 제시할 것이며, 이와 같

이 하면 XML 기반 Hello World 예제가 단순해질 것이다.

문제

Ajax XML 응답을 처리할 때 DOM을 사용하면 속도가 느려지고 일이 복잡해진다. Ajax

와 XML을 이용한 개발 작업을 더 쉽게 하기 위하여 최신의 XML 기술을 사용하고자 한다.

솔루션

작업을 간소화하기 위하여 XPath와 XSLT를 사용한다. 인터넷 익스플로러와 파이어폭

스 모두 이들 기술을 지원한다. 물론 지원하는 방식은 전혀 다르다. 대부분의 브라우저들

이 상호 호환되지 않으므로, 최선의 전략은 서드파티 라이브러리를 사용하는 것이다. 이

Page 88: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

�8

Ajax 기초1부

번 예제에서는 Sarissa(http://sarissa.sf.net)를 선택하였다. Sarissa는 브라우저에서의

XML 작업과 관련하여 여러 가지 점에서 크로스 브라우저 문제를 해결한다. 리스트 2.11

은 XSLT와 XPath가 적용된 애플리케이션의 클라이언트 측 코드다.

리 스 트 2.11 | hello7.html

<html><head><title>Hello Ajax version 7</title><style type='text/css'>* { font-family: Tahoma, Arial, sans-serif; }#helloTitle{ color: #48f; }.sidebar{ background-color: #adf; color: navy; border: solid blue 1px; width: 180px; height: 200px; padding: 2px; margin: 3px; float: left;}</style><script type='text/javascript' src='sarissa.js'> </script><script type='text/javascript' src='sarissa_ieemu_xpath.js'> </script> b Sarissa 라이브러리 임포트

<script type='text/javascript' src='sarissa_dhtml.js'> </script><script type='text/javascript'>

var xslDoc=null;

window.onload=function(){

xslDoc=Sarissa.getDomDocument(); c XSL 스타일 시트 로드

xslDoc.load("recipe.xsl");

document.getElementById('helloBtn') .onclick = function(){ var name = document.getElementById('helloTxt').value; var xhr = new XMLHttpRequest(); xhr.open("GET", "hello7.jsp?name=" +encodeURI(name),true);

d XHR 객체 생성

Page 89: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

�9

Ajax와의 통신 방법 2장

xhr.onreadystatechange = function(){ if (xhr.readyState == 4){ update(xhr.responseXML);

e 콜백 함수 할당

} }; xhr.send(""); };};

function update(doc){ var initial = doc.selectSingleNode( '/person/@initial' ).value; var name = doc.selectSingleNode( '/person/name/text()' ).nodeValue;

f 개별 노드 선택

document.getElementById('helloTitle') .innerHTML = "<h1>Hello, <b><i>" +name+"</i></b></h1>";

var likesList = doc .selectNodes('/person/likes/item');

g 여러 노드 선택

var likes = []; for (var i=0;i<likesList.length;i++){ var itemNode = likesList[i]; likes[i]=itemNode .firstChild.data; } var likesHTML='<h5>' +initial+' likes...</h5><hr/>'; for (var i=0;i<likes.length;i++){ likesHTML += likes[i]+"<br/>"; } document.getElementById('likesList') .innerHTML = likesHTML;

var personNode = doc.selectSingleNode('/person');

var xsltproc = new XSLTProcessor(); xsltproc.importStylesheet(xslDoc); Sarissa.updateContentFromNode( personNode, document.getElementById('ingrList'), xsltproc );

h XSLT 트랜스폼 호출

}

Page 90: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

60

Ajax 기초1부

</script></head><body>

<div id='likesList' class='sidebar'><h5>Likes</h5><hr/></div><div id='ingrList' class='sidebar'><h5>Ingredients</h5><hr/></div><div><div id='helloTitle'><h1>Hello, stranger</h1></div><p>Please introduce yourself by entering your name in the box below</p><input type='text' size='24' id='helloTxt'></input>&nbsp;<button id='helloBtn'>Submit</button></div></body></html>

처음으로 할 일은 Sarissa 라이브러리를 임포트하는 것이다❶. 핵심 라이브러리를 임포트

할 뿐만 아니라, 파이어폭스하에서 인터넷 익스플로러 스타일의 XPath를 제공하는 지원

라이브러리를 임포트하고, XSLT에서 생성된 컨텐츠를 웹 페이지로 삽입하기 위한 몇 개

의 컨비니언스 메서드(convenience method)를 제공하는 헬퍼 라이브러리를 임포트한다.

XSLT를 사용하는 컨텐츠를 생성하려면 서버로부터 두 개의 XML 문서를 받아야 하

며, 하나는 스타일 시트(즉, 템플릿)이고 다른 하나는 데이터다. 앞에서와 같이 데이터

는 임의로 가져올 것이지만, 스타일 시트는 애플리케이션이 로드될 때 미리 가져올 수 있

다❷. 이것을 처리할 때 XHR이 아닌 DomDocument 객체를 사용한다. 다시 말하지만,

Sarissa는 크로스 브라우저 래퍼를 제공한다.

XML 데이터를 로드하기 위하여 XHR 객체를 사용할 것이다. 이번 예제에서는

Prototype을 제외시켰으므로 XHR 객체를 직접 만들어야 하고❸, 콜백도 할당해야 한다

❹. 그럼에도 불구하고, 코드는 1장에서 보았던 것보다 더 간단해졌다. 왜냐하면 인터넷

익스플로러에서도 네이티브 XHR 객체에 접속할 수 있기 때문이다. 내부적으로 Sarissa

는 객체를 탐지하며, 네이티브 XHR 객체를 찾지 못하면 ActiveX 컨트롤을 생성하여 그

Page 91: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

6�

Ajax와의 통신 방법 2장

것을 사용하도록 할 것이다.

일단 XHR 객체를 찾으면 DOM 객체를 update() 함수로 넘길 수 있다. DOM을 사용

할 경우 지금부터 고난이 시작된다. XPath를 사용할 경우 한 줄의 코드에서 여러 계층의

DOM 노드를 처리할 수 있다. 예를 들어 XPath 질의인

/person/name/text()

는 문서 상단의 <person> 태그 아래에 직접 중첩되어 있는 <name> 태그의 내부 텍

스트를 선택한다. XPath는 여기서 깊이 다루기에 그 주제가 너무 크다. XPath와

XSLT를 처음 접한다면 http://zvon.org를 보면 좋을 것이다. DOM Node 메서드인

selectSingleNode()❺와 selectNodes()❻는 일반적으로 인터넷 익스플로러에서만

볼 수 있다. 그러나 여기서 로드한 두 번째 Sarissa 라이브러리는 파이어폭스/모질라용

구축 시스템을 제공했다. 여기서는 XPath를 이용하여 이름 데이터와 좋아하는 물건 목록

을 추출하며, 이 화면 구역에 대한 HTML 컨텐츠를 직접 구성한다. 메뉴 목록 부분은 더

복잡하므로 XSLT를 소개할 때 사용할 것이다.

마지막 단계는 XSLT 트랜스폼을 수행하는 것이다❼. XSLTProcessor 객체를 만든 곳

은 모질라이며, 인터넷 익스플로러의 경우 Sarissa에 의해 제공된다. 여기서는 이것을 스

타일 시트에 대한 참조로 넘긴 다음에, updateContentFromNode() 메서드를 호출한다.

로드된 세 번째 Sarissa 라이브러리에 의해 제공된 헬퍼 메서드는 XSLT 프로세서를 통

해서 데이터(즉, personNode)를 넘길 것이며, 이의 결과로 나온 HTML을 지정된 DOM

노드(즉, ingrList)로 쓴다.

물론 이렇게 하기 위해서는 XSL 스타일 시트를 제공해야 한다. 리스트 2.12에서 이것

을 볼 수 있다.

리 스 트 2.12 | recipe.xsl

<?xml version="1.0"?><xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/ Transform"><xsl:output method="xml"/>

<xsl:template match="/person"> <div> <h5><xsl:value-of select='@initial'/>'s favorite recipe is

Page 92: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

62

Ajax 기초1부

<xsl:value-of select='recipe/name'/></h5> <p><xsl:apply-templates select="recipe/ingredient" /></p> <p><i><xsl:value-of select='recipe/serving-suggestion'/></i></p> </div> </xsl:template>

<xsl:template match="ingredient"> <xsl:value-of select='@qty'/> : <xsl:value-of select='.'/><br/> </xsl:template>

</xsl:stylesheet>

XSL 스타일 시트는 아주 간단하다. 이것은 일반적인 XHTML 마크업이 섞인 것이며,

XSL 네임스페이스를 나타내는 특수한 태그인 xsl이 앞에 붙는다. 이렇게 xsl이 붙어 있으

면 명령을 처리하는 것으로 간주된다. <xsl:template> 태그는 match 어트리뷰트에서

XPath 질의와 일치하는 노드가 있을 때 출력될 컨텐츠 묶음을 나타낸다. <xsl:value.

of>는 일치된 노드들로부터 데이터를 인쇄하며, 이때 XPath 식을 사용한다. <xsl:

apply-templates> 태그는 더 많은 처리를 위하여 다른 템플릿 태그로 노드의 경로를

지정한다. 이 경우에 각각의 노드는 첫 번째 템플릿에서 두 번째 템플릿으로 넘어가는 식

으로 해서, 하나의 목록이 만들어진다.

여기서 XSLT 스타일 시트 규칙을 모두 살펴보기에는 지면이 짧다. 더 자세히 알고 싶

으면, http://zvon.org를 방문하기 바란다.

마지막으로, 서버 측을 잠깐 살펴보자. 이 예제에서 사용된 JSP는 앞 예제(리스트 2.10

참고)의 JSP와 같다. 클라이언트 코드만 앞의 예제와 달라서 여기서 설명하였다.

토론

XSLT와 XPath를 사용함으로써 클라이언트 측의 XML 처리 코드가 매우 간단해졌다. 더

복잡한 애플리케이션에서 이들 기술을 사용하면 DOM을 사용할 때보다 코딩 노력이 적게

들어갈 것이다. XML과 Ajax를 사용하려면 이들 기술을 꼭 조사해보기 바란다.

JSON을 설명할 때 클라이언트와 서버 사이에서 구조적 데이터를 라운드 트립하는 것

에 대해 논의하였다. Sarissa도 이 방법을 권장하며, 상호 교환 형식으로서 XML을 사용

한다. 또한 Sarissa는 XML 객체의 크로스 브라우저 변환을 지원한다. 앞에서 언급한 것

Page 93: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

63

Ajax와의 통신 방법 2장

처럼 서버 측에 속하는 거의 모든 기술도 XML의 상호 변환을 지원한다. 여기서 전체 예

를 살펴보지는 않을 것이다. 그러나 원칙은 JSON의 경우와 비슷하다. 자바에서 JSON

을 사용할 때 타입이 엄격하지 않은 JSON과 타입이 엄격한 자바 사이의 불일치로 인해

서 JSON 응답의 구성에 꽤 많은 수작업이 요구된다는 것을 앞에서 살펴보았다. 자바와

XML 사이의 변환에서도 동일한 이슈가 존재한다. 그러나 문제 영역은 한결 더 명확하며,

Caster이나 Apache XMLBeans와 같이 탁월한 솔루션도 있다.

Sarissa는 이들 기술에 대한 최고의 해결책이다. 물론 이것만이 유일한 방법은 아니

다. XPath 질의만을 원한다면 mozXPath.js 라이브러리(http://km0ti0n.blunted.

co.uk/mozXPath.xap)가 좋은 대안이 될 수 있으며, 이 라이브러리는 오페라 브라우저

도 지원한다. XSLT와 같은 것을 좋아하지만 사파리에서 작업을 처리해야 한다면 구글의

AJAXSLT를 사용할 수 있으며, 이것은 100% 자바스크립트 XSLT 엔진(http://goog-

ajaxslt.sf.net)이다. 그러나 AJAXSLT는 인터넷 익스플로러와 모질라의 네이티브 엔진

에 비해 느리며, XSL 네임스페이스 전체를 지원하지 않는다. 따라서 스타일 시트를 작성

할 때 라이브러리의 한계를 염두에 두어야 하며, 규모를 적절하게 조절해서 너무 크게 하

지 않아야 한다.

Ajax 기술을 개괄적으로 거의 다 살펴보았다. 마지막 절에서는 XML을 사용하는 또 다

른 인터넷 기술인 SOAP 웹 서비스를 살펴보고, 이 기술과 AJAX가 어떤 관련이 있는지

살펴볼 것이다.

2.4 Ajax와 웹 서비스 사용

이 절에서는 원격 서버에서 실행되는 웹 서비스를 SOAP상에서 호출하는 방법을 보여

줄 것이다. 아무튼, 웹 서비스가 무엇이고, 이리저리 넘겨지는 XML 데이터는 무엇인가?

XHR 객체는 이런 작업에 이상적으로 적합하며, SOAP상에서 원격 메서드를 호출한다.

물론, 이것이 보기보다는 쉬운 일은 아니다.

인터넷 익스플로러와 모질라에는 네이티브 객체들이 있으며, 이들 객체를 사용하여

웹 서비스를 호출할 수 있다. 불행하게도 이들 객체를 브라우저들 사이에서 이식할 수

는 없으며, 따라서 개발자들은 호출할 적절한 객체를 선택할 수 있는 프레임워크를 직

접 작성해야 한다. 마이크로소프트의 http://msdn.microsoft.com/workshop/author/

webservice/overview.asp에 가면 브라우저 측 SOAP 버전에 대해 자세히 알 수 있다.

Page 94: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

6�

Ajax 기초1부

마이크로소프트의 시스템은 자바스크립트와 VBScript를 기반으로 한다. 모질라는 브라

우저 측 SOAP 버전을 www.mozilla.org/projects/webservices/에서 다루고 있으며,

http://developer.mozilla.org/en/docs/SOAP_in_Gecko-based_Browsers에 가면

더 상세한 정보를 얻을 수 있다. 브라우저 측에서 구성될 수 있는 네이티브 객체를 통해

서 브라우저 측 SOAP 버전에 접근할 수 있다.

다행히, 또 다른 방법도 있다. 인터넷 익스플로러나 모질라 객체를 사용하는 상위 레벨

의 API를 작성하는 대신에 XML을 교환하기 위하여 XMLHttpRequest를 사용하는 자체

라이브러리를 생성할 수 있으며, SOAP 메시지를 파싱하고 생성할 수 있는 라이브러리도

만들 수 있다. 이러한 라이브러리를 사용하여 마이크로소프트나 모질라 SOAP API를 지

원하지 않고 XHR 객체를 가지고 있는 브라우저에서 코드를 실행할 수 있다. IBM에 있

는 친절한 사람이 이런 라이브러리를 만들었으며, 그 이름을 ws-wsajax라고 붙였다. 이

를 www.ibm.com/developerworks/webservices/library/ws-wsajax/에서 확인할 수

있다. 이 절의 뒷부분에서 이 라이브러리를 사용할 것이다.

이번 예제를 위해서 UI를 간소화하였으며, 그 일환으로 메뉴 목록 부분을 없앴다. 이름

을 넘기면 3개의 항목, 즉 이름, 이니셜, 선호 품목 리스트가 들어 있는 맵이 반환될 것이

다. 그림 2.7은 이번 예제의 UI다.

이 절에서는 SOAP와 SOAP-RPC를 어느 정도 알고 있다는 가정하에서 논의를 진행

한다. 한 번 더 말하지만 이 주제를 깊이 다루는 책들이 많이 있으며 인터넷에도 참고 자

료가 많이 있다.

그림 2.7 8번째 Hello World 예제. UI에서 메뉴 목록을 없애서 인터페이스를 간소화하였다.

Page 95: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

6�

Ajax와의 통신 방법 2장

문제

웹 브라우저에서 SOAP-RPC를 수행해야 한다. 그리고 실행 결과인 SOAP 응답을

HTML로 표시해야 한다.

솔루션

이 절에서는 Apache의 Axis 프레임워크(http://ws.apache.org/axis/)로 작성된 Hello

World SOAP 서비스에 접근하기 위해 IBM의 SOAP 툴킷을 사용하여 소규모의 클라이언

트를 작성할 것이다. 먼저 웹 서비스를 정의해 보자. Axis를 사용하면 웹 서비스의 프로토

타이핑이 매우 쉬워지며, 자바 클래스들을 파일 확장자가 .jws인 파일로 작성할 수 있다.

JSP와 같이 .jws 파일을 특수한 서블릿(여기서는 AxisServlet)으로 컴파일할 수 있으며,

상용 제품 제작에 사용할 정도로 충분히 견고하지는 않지만 간단한 데모용으로는 훌륭하

게 그 기능을 수행한다. 리스트 2.13은 Hello World 서비스에 사용할 간단한 .jws 파일

이다.

리 스 트 2.13 | HelloWorld.jws

import java.util.Map;import java.util.HashMap;

/** * class to list headers sent in request as a string array */public class HelloWorld {

public Map getInfo(String name) { String initial=name.substring(0,1).toUpperCase(); String[] likes=new String[] { "JavaScript", "Skiing", "Apple Pie" }; Map result=new HashMap(); result.put("name",name); result.put("initial",initial); result.put("likes",likes); return result; }

}

Page 96: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

66

Ajax 기초1부

이 클래스에는 하나의 메서드가 있으며, 이 메서드는 SOAP-RPC 함수로 매핑될 것이다.

이 함수에는 타입이 String인 1개의 인수가 있으며, 이 함수는 조합 배열(자바에서는 Map

이라고 한다)을 반환한다.

HelloWorld.jws가 실행되면 WSDL(Web Service Description Language) 파일이 반환

될 것이다. 그리고 IBM 라이브러리와 같은 SOAP 클라이언트에서 신호를 보내면 클라이

언트 측 스텁이 만들어지고, 서비스를 호출할 수 있을 것이다. 리스트 2.14는 이 클래스

에 의해 생성된 WSDL이다.

리 스 트 2.14 | HelloWorld.jws용 WSDL

<?xml version="1.0" encoding="UTF-8"?><wsdl:definitions targetNamespace="http://localhost:8080/AiP2/HelloWorld.jws" xmlns:apachesoap="http://xml.apache.org/xml-soap" xmlns:impl="http://localhost:8080/AiP2/HelloWorld.jws" xmlns:intf="http://localhost:8080/AiP2/HelloWorld.jws" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><!--WSDL created by Apache Axis version: 1.4Built on Apr 22, 2006 (06:55:48 PDT)--> <wsdl:types> <schema targetNamespace="http://xml.apache.org/xml-soap" xmlns="http://www.w3.org/2001/XMLSchema"> <import namespace="http://schemas.xmlsoap.org/soap/encoding/"/> <complexType name="mapItem"> <sequence> <element name="key" nillable="true" type="xsd:anyType"/> <element name="value" nillable="true" type="xsd:anyType"/> </sequence> </complexType> <complexType name="Map"> <sequence> <element maxOccurs="unbounded" minOccurs="0" name="item" type="apachesoap:mapItem"/> </sequence> </complexType> </schema> </wsdl:types> <wsdl:message name="getInfoResponse">

Page 97: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

67

Ajax와의 통신 방법 2장

<wsdl:part name="getInfoReturn" type="apachesoap:Map"/> </wsdl:message> <wsdl:message name="getInfoRequest"> <wsdl:part name="name" type="xsd:string"/> </wsdl:message> <wsdl:portType name="HelloWorld"> <wsdl:operation name="getInfo" parameterOrder="name"> <wsdl:input message="impl:getInfoRequest" name="getInfoRequest"/> <wsdl:output message="impl:getInfoResponse" name="getInfoResponse"/> </wsdl:operation> </wsdl:portType> <wsdl:binding name="HelloWorldSoapBinding" type="impl:HelloWorld"> <wsdlsoap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/> <wsdl:operation name="getInfo"> <wsdlsoap:operation soapAction=""/> <wsdl:input name="getInfoRequest"> <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://DefaultNamespace" use="encoded"/> </wsdl:input> <wsdl:output name="getInfoResponse"> <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://localhost:8080/AiP2/HelloWorld.jws" use="encoded"/> </wsdl:output> </wsdl:operation> </wsdl:binding> <wsdl:service name="HelloWorldService"> <wsdl:port binding="impl:HelloWorldSoapBinding" name="HelloWorld"> <wsdlsoap:address location="http://localhost:8080/AiP2/HelloWorld.jws"/> </wsdl:port> </wsdl:service></wsdl:definitions>

WSDL에는 함수들과 연결되는 각 RPC 호출의 인수 타입과 반환형에 대한 세부 정보가

있으며, 상호 교환의 특징을 명시하기 위해 클라이언트와 서버에서 필요로 하는 다른 세

부 정보도 들어 있다. 다행히, WSDL은 Axis에 의해 자동으로 생성되며, IBM 툴킷에 의

Page 98: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

68

Ajax 기초1부

해 처리된다. 따라서 코드 라인을 모두 이해할 필요는 없다.

클라이언트 측 코드를 살펴보자. 리스트 2.15는 8번째 Hello World 애플리케이션의 전

체 소스다.

리 스 트 2.15 | hello8.html

<html><head><title>Hello Ajax version 8</title><style type='text/css'>* { font-family: Tahoma, Arial, sans-serif; }#helloTitle{ color: #48f; }.sidebar{ background-color: #adf; color: navy; border: solid blue 1px; width: 180px; height: 200px; padding: 2px; margin: 3px; float: left;}</style><script type='text/javascript' src='prototype_v131.js'> </script> B 프로토타입 임포트

<script type='text/javascript' src='ws.js'> </script>

c IBM WS

라이브러리 임포트

<script type='text/javascript'>

window.onload=function(){ $('helloBtn').onclick = function(){ var name=$('helloTxt').value; var wsNamespace = '../axis/HelloWorld.jws'; d WSDL로부터 클라이언트 생성 var wsCall = new WS.Call(wsNamespace); var rpcFunction = new WS.QName('getInfo',wsNamespace); e RPC 함수 참조

wsCall.invoke_rpc( rpcFunction, [{name:'name',value:name}], f RPC 인수 넘기기

null, function(call,envelope){

콜백 정의g var soapBody = envelope.get_body(); var soapMap = soapBody .get_all_children()[1].asElement(); var itemNodes = soapMap

Page 99: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

69

Ajax와의 통신 방법 2장

.getElementsByTagName('item'); var initial = ""; var likes = []; for (var i=0;i<itemNodes.length;i++){ var itemNode = itemNodes[i]; var key = itemNode .getElementsByTagName('key')[0] .firstChild.data; if (key == 'initial'){ initial = itemNode .getElementsByTagName('value')[0] .firstChild.data; }else if (key == 'likes'){ var likeNodes = itemNode .getElementsByTagName('value')[0] .getElementsByTagName('value'); for (var j=0;j<likeNodes.length;j++){ likes[likes.length] = likeNodes[j] .firstChild.data; } } } update(initial,likes); } ); };};

function update(initial,likes){ h UI 업데이트

var content = "<h5>"+initial +" likes...</h5><hr/>"; for (var i=0;i<likes.length;i++){ content += likes[i]+"<br/>"; } $('likesList').innerHTML = content;}

</script></head><body>

<div id='likesList' class='sidebar'><h5>Likes</h5><hr/></div><div>

Page 100: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

70

Ajax 기초1부

<div id='helloTitle'><h1>Hello, stranger</h1></div><p>Please introduce yourself by entering your name in the box below</p><input type='text' size='24' id='helloTxt'></input>&nbsp;<button id='helloBtn'>Submit</button></div></body></html>

살펴볼 내용이 많다. 하나씩 살펴보자. 먼저, IBM 라이브러리를 임포트해야 한다❷. 이

라이브러리가 Prototype의 상단에서 만들어지기 때문에 이것을 인크루드한다. 여기서는

이전 버전의 Prototype(v1.3.1)를 사용하므로, 나머지 예제들과의 혼돈을 피하기 위하여

이름을 바꾸었다❶.

웹 서비스를 사용하기 위해 가장 먼저 해야 할 일은 WSDL을 참조하고, 이것을

WS.Call 객체로 넘기는 것이다❸. 그런 다음에 WS.QName 객체와 같은 특수한 함수로

참조를 추출한다❹. 이 객체를 호출하여 입력 매개변수들을 자바스크립트 객체로서 제

공하고(여기서는 JSON을 사용하여 정의하였음)❺, 그리고 콜백 함수를 호출하여 응답

을 파싱한다❻. 응답을 파싱하려면 많은 노드 탐색(node traversal)이 필요하다. 여기서

는 DOM 노드가 아닌 SOAP 노드로 작업한다. 그러나 SOAP 노드는 어느 시점에 가서

DOM 노드로 변환될 수 있다. 여기서는 예제를 간소화하기 위해 XPath를 사용하지 않

았다. 그러나 더 큰 SOAP 응답을 처리하려면 XPath를 사용하는 것이 확실히 도움이 될

것이다. 일단 응답으로부터 데이터를 추출하였으며, 그것을 여느 때와 같이 update()

함수로 넘긴다❼. 여기서는 설명의 편의를 위해 단순화시켰지만 필요하고 여건이 된다면

SOAP 응답에서 XSLT 트랜스폼을 사용하지 말아야 할 이유는 없다.

토론

Ajax에서 SOAP를 사용하는 것이 가능하다는 것을 살펴보았다. 물론 이를 위해서는

SOAP 서비스가 Ajax 클라이언트와 동일한 서버에서 와야 하며, 이와 같이 동일한 서버

에서 온 경우에 발생하는 브라우저의 보안 제약은 그대로 안고 가야 한다. 백엔드 시스템

에서 SOAP를 이미 생성한다면 SOAP를 사용함으로써 기존의 자원들을 재사용하는 것은

Page 101: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

7�

Ajax와의 통신 방법 2장

효과적인 방법이다. 그러나 신규 애플리케이션 개발용 아키텍처로서 SOAP를 이용하는

것은 불필요하게 복잡하다고 말하고 싶은 유혹을 떨쳐버릴 수 없다. 물론 외부 엔티티들

과의 상호 호환성이 필요하다면 이야기가 달라질 것이다.

IBM SOAP 툴킷을 사용하면 서비스를 호출하는 것이 아주 쉬워진다. 그러나 응답을

파싱하는 작업은 조금 어려워진다. SOAP-RPC 응답은 여러 개의 네임스페이스와 관련

이 있으며, 디코딩하기에도 복잡하다. 대개 Document/literal 스타일의 SOAP 바인딩이

더 간단한 응답을 제공하므로, 실제 애플리케이션을 제작할 때는 이 툴킷이 더 적절할 수

있다.

여느 때와 같이, 프로그래머로서 SOAP를 사용할 것인지는 고민해 보아야 할 문제다.

빠른 솔루션을 원한다면 SOAP의 사용은 정답이 아닐 수 있다. 그러나 더 큰 애플리케이

션을 만들게 되어서 업데이트와 확장이 많이 요구될 것으로 예상된다면, 또한 조직의 여

러 시스템과 통합해야 하며, 더 나아가서 이것들을 처리할 시간과 기술을 보유하고 있다

면 브라우저 측 SOAP는 분명히 도움이 될 것이다.

2.5 요약

1장의 끝부분에서 Ajax 요청을 어떻게 만드는지 살펴보았고, 서드파티 라이브러리를 사용

하여 프로세스를 단순화하는 방법도 설명하였다. 그 이후로 많은 내용을 다루었으며, 논

의의 중심도 단순히 요청을 만드는 것에서부터 애플리케이션의 생성부터 소멸에 이르기까

지 클라이언트와 서버 사이에서의 대화를 구조화하려면 어떻게 해야 하는가로 옮겨갔다.

이 장에서 여러 가지 기법을 살펴보았고, 각 기법의 강점과 약점도 평가해 보았다. 서

버에서 자바스크립트 코드를 생성하는 방법을 살펴보았고, 클라이언트와 서버 코드베이

스 사이에서의 과도한 혼란을 방지하기 위해 상위 수준의 API를 작성하는 것 대신에 생

성 코드를 작성하는 것에 어떤 이점이 있는지도 설명하였다.

그러고 나서 JSON을 살펴보고, 계속해서 XML을 설명한 다음에 클라이언트와 서버

사이에서 구조적인 데이터를 넘기는 방법을 설명하였다. 각 경우에, 서버로부터 도착하

였을 때 데이터를 파싱하는 방법을 살펴보았고, 그러고 나서 클라이언트와 서버 사이에

서 데이터의 전체 라운드 트립을 살펴보았다. 데이터를 라운드 트립하고 양쪽 끝에서 라

이브러리 코드를 변환함으로써 하위 수준의 코딩에 시간을 뺏기지 않고 비즈니스 코드

Page 102: Ajax 인 프랙티스 : 실전 예제를 통한 최신 Ajax 기법 마스터

72

Ajax 기초1부

작성에 집중할 수 있다.

JSON과 XML을 비교해 보면, JSON은 클라이언트 측에 더 친숙해 보인다. 처음에는

클라이언트 측 XML에서 많은 고민을 했지만 XPath와 XSLT를 선택한 후 작업이 한결

수월해졌다. 두 기술 중 어떤 것이 더 탁월한지는 알 수 없으며, 이에 대한 정답은 개인

취향에 따라 달라진다. 또한 통합해야 할 레거시 시스템이 근본적으로 JSON이나 XML

중 어떤 것과 더 궁합이 잘 맞는지에 따라 결정된다.

다음 장에서는 모든 Ajax 애플리케이션을 함께 묶는 프로그램 아교 역할을 하는 자바

스크립트를 살펴볼 것이다. 최근에 자바스크립트가 어떻게 진화하고 있으며, Ajax 애플

리케이션을 만드는 코드를 더 잘 구조화함에 있어서 자바스크립트가 어떻게 도움을 줄

수 있는지 논의할 것이다. 마지막 부분에서는 유용한 Ajax 프레임워크들을 몇 개 살펴볼

것이다.