본문 바로가기
이카루스의 날개/JSP

자바 개발자를 위한 AJAX FAQ

by 윙혼 2007. 6. 25.

자바 개발자를 위한 AJAX FAQ

글: Greg Murray
번역: 한국썬 6기 썬스타 김 미 영
감수:자바 챔피언 양 수 열

지금 AJAX를 사용하실 기회가 눈앞에 있습니다. 많은 사람들이 AJAX를 통해 새로운 세계를 내다보고 있습니다. 대부분의 개발자들이 AJAX를 기존의 프레임웍을 통하여 접하는 동안 여러분은 기존에 제공된 것 이상의 기능을 경험해보십시오. 본 FAQ는 애플리케이션에 AJAX 기능을 추가하기 원하는 자바 개발자들을 위해 제작되었습니다.


Java Studio Creator and AJAX [spacer]
  1. AJAX를 사용해야 할까요?
  2. AJAX는 Java와 호환 가능합니까?
  3. 지금 사용하고 있는 서버측 프레임웍이 AJAX를 제공해 주지 않을까요?
  4. 어디서부터 시작해야 할까요?
  5. AJAX 기능을 직접 생성하기 위해 알아야할 것은 무엇입니까?
  6. 꼭 java script를 배워야 하나요?
  7. 어떤 자바 스크립트 libraries와 프레임웍들이 사용 가능합니까?
  8. Return type으로 XML이나 text, 자바 스크립트, HTML을 사용해야 하나요?
  9. AJAX를 사용할 때 고려해야할 점은 무엇입니까?
  10. 자바 스크립트를 어떻게 디버깅하나요?
  11. AJAX 호출을 위해 HTTP GET 또는 POST를 사용해야 합니까?
  12. 어떻게 국제적인 AJAX 인터랙션을 개발하죠?
  13. 동시에 발생하는 AJAX request를 어떻게 처리해야 할까요?
  14. AJAX client와 interact하기 위해 server에서 하는 일은 무엇입니까?
  15. AJAX client의 상태를 어디에 저장하지요?
  16. form이나 form의 한 부분을 페이지를 새로고침하지 않고 삽입하는 방법은요?
  17. 컨트롤하는 것은 서버입니까 client입니까?
  18. AJAX와 관련된 보안 이슈는 무엇입니까?
  19. Synchronous와 synchronous request를 각각 어떤 때 사용하죠?
  20. 애플릿과 플러그인들은 어떻습니까?
  21. '뒤로'와 '앞으로' 버튼을 어떻게 처리하지요?
  22. AJAX를 사용해서 어떻게 이미지를 보낼 수 있습니까?
  23. AJAX 폴링을 하기 위한 쓰레드를 어떻게 생성하나요?

AJAX를 사용해야 할까요?

그 우수성으로 세간의 화제가 되고 있는 AJAX이지만, 어떤 환경에서는 사용이 어려울 수 있습니다. AJAX는 최신 버전의 브라우저에서만 작동하는 등 브라우저 호환에 취약점을 보이며, AJAX의 사용을 위한 새로운 SKILL-SET 습득을 필요로 합니다. AJAX의 세계에 본격적으로 뛰어들기 전에 Alex Bosworth의 블로그에서 몇가지 AJAX 실수에 대해 확인해보세요. AJAX Mistakes, by Alex Bosworth

비록 사용 환경상에 몇 가지 제약이 존재하기는 하지만, AJAX를 사용할 경우 시스템 응답 시간이 획기적으로 짧은 효과적인 쌍방향 웹 애플리케이션 개발이 가능합니다. AJAX 기반 애플리케이션이 정말로 더 빠른가에 대해서는 논란의 여지가 있지만, 데이타가 뒤에서 처리되고 있는 동안 화면에서는 바로 피드백이 이루어지므로 사용자는 시스템이 즉각적으로 반응한다고 느끼게 됩니다. 만약 브라우저 호환 문제를 처리할 수 있으며, 신기술에 밝은 얼리어답터이거나 좀더 실력을 높이고 싶은 개발자라면 AJAX 사용을 강력히 추천합니다. 애플리케이션을 AJAX화할 때는 작은 부분이나 컴포넌트(component)부터 시작하여 차근차근 진행하는 것이 현명할 것입니다. 새로운 테크놀로지는 언제나 매력적이지만, AJAX를 사용하는 목적은 애플리케이션 사용자를 편리하게 하는 것이지 어지럽게 하는 것이 아님을 기억합시다.

AJAX는 Java와 호환 가능합니까?

물론입니다. Java는 AJAX와 매우 잘 맞습니다. AJAX 클라이언트 페이지 제작, AJAX 리퀘스트의 처리, AJAX 클라이언트를 위한 server side state 설정, AJAX 클라이언트의 연결 등에 Java Enterprise Edition 서버를 사용할 수 있습니다. JavaServer Faces 컴포넌트 모델은 AJAX component를 정의하고 사용하는데 매우 적합합니다.

지금 사용하고 있는 서버측 프레임웍이 AJAX를 제공해 주지 않을까요?

당신은 AJAX를 이미 사용하고 있을지도 모릅니다. 현재도 많은 자바 기반 프레임웍들이 일정 수준의 AJAX 인터랙션을 제공하고 있으며, AJAX 기능이 더욱 강화된 새로운 프레임웍과 컴포넌트 라이브러리가 계속해서 개발되고 있습니다. AJAX를 제공하는 자바 프레임웍은 너무나 많고 다양하기 때문에 여기서 다 나열할 수는 없지만, www.ajaxpatterns.org/Java_Ajax_Frameworks에 있는 이 리스트가 좋은 참고가 될 것입니다.

아직 어떤 프레임웍을 쓸지 결정하지 않으셨다면, JavaServer Faces나 JavaServer Faces 기반의 프레임웍을 추천해 드립니다. JavaServer Faces components는 자바 스크립트나 AJAX 인터랙션s, DHML processing을 생성하는데 사용되는 많은 것들을 추상화할 수 있습니다. 따라서, 썬 자바 스튜디오 크리에이터 같은 JSF 호환 IDE의 플러그 인으로, 또 JSF 애플리케이션을 개발할 때 간단한 AJAX를 사용할 수 있게됩니다.

어디서부터 시작해야 할까요?

현재 사용하고 있는 프레임웍의 기능이 충분치 않다고 느끼거나, 직접 AJAX 컴포넌트나 기능을 개발하기 원한다면, Asynchronous 자바 스크립트 Technology and XML (AJAX) With Java 2 Platform, Enterprise Edition라는 글을 읽는 것으로 시작하시기 바랍니다.

아주 기초의 예제(소스코드 포함)를 보기 원한다면 Using AJAX with Java Technology에서 기술적 팁을 얻으실 수 있습니다. 더 많은 AJAX 자료 목록은Blueprints AJAX Home 페이지에서 확인하시기 바랍니다.

다음 단계에서는 AJAX libraries and frameworks 을 참조하시기 바랍니다. 클라이언트측 AJAX 스크립트를 직접 작성하고자 할 때 처음부터 고민해야하는 수고를 덜어줍니다.

Dave Crane, Eric Pascarello, Darren James의 책 AJAX in Action 또한 좋은 자료가 될 것입니다. 이 책에는 자바 개발자들이 자바 스크립트를 익힐 수 있는 부록이 수록되어 있습니다.

AJAX 기능을 직접 생성하기 위해 알아야할 것은 무엇입니까?

기존의 AJAX 컴포넌트를 사용하지 않고자 한다면 다음의 몇가지를 유의해야합니다.

먼저 AJAX의 기초가 되는 Dynamic HTML을 배워야 합니다. DHTML은 사용자와 웹페이지 간에 브라우저 기반 실시간 인터랙션을 가능하게 합니다. DHTML은 자바 스크립트, DOM(Document Object Model),CSS(Cascading Style Sheets)의 조합으로 이루어져 있습니다.

  • 자바 스크립트 -자바 스크립트는 모든 주요 브라우저가 지원하고 있는 느슨한 형 정의 객체 기반(loosely typed Object based)의 스크립트 언어로써 AJAX의 트랜잭션의 필수 요소입니다. 페이지 안의 자바 스크립트는 그 페이지에서 페이지 로드, 클릭, 키 입력(in a form element) 등의 특정 이벤트가 발생하면 호출됩니다.
  • DOM - 정형화된 문서에 액세스하여 조작하기 위한 API입니다. 대부분의 경우 DOM은 XML이나 HTML 문서의 구조를 나타냅니다.
  • CSS - 표현(presentation)이 내용(content)과 관계없이 분리되도록 하며, JavaSctript로 변경할 수도 있습니다.

HTTP의 기본적인 요청/반응 특성을 이해하는 것도 중요합니다. 예를 들어 XMLhttpRequest와 HTTP 반응 코드를 구성할 때 GET과 Olst 메소드의 차이를 간과한다면 callback을 처리할 때 미세한 버그들이 발생할 수 있습니다.

어떤 면에서 자바 스크립트는 클라이언트측 접착제라고도 할 수 있습니다. 자바 스크립트는 Xmlhttprequest 오브젝트를 생성하거나 비동기 호출을 유발하는데 사용되며, 돌아온 내용을 파싱하고 분석하는 데 사용합니다. 자바 스크립트는 또한 돌아온 메시지를 프로세싱하는 데 사용되며, DOM API를 사용하는 HTML에 CSS를 수정하기 위해 새로운 메시지를 삽입하는 데에도 사용됩니다.

꼭 java script를 배워야 하나요?

네, 웹 애플리케이션에 새로운 AJAX 기능을 개발하고자 한다면 기본적으로는 그렇습니다.

그러나 JSF 컴포넌트와 컴포넌트 라이브러리가 자바 스크립트, DOM, CSS의 디테일을 추상화할 수 있으며, 이 컴포넌트들이 AJAX 인터랙션을 가능하게 만드는데 필요한 인공물(artifacts)을 만들 수 있습니다. 또한, 자바 스튜디오 크리에이터 같은 비주얼 툴들은 애플리케이션을 제작하는데 JSF 컴포넌트가 enable된 AJAX를 이용하기도 하며, 이에 따라 툴 개발자는 AJAX의 세세한 코드들은 직접 다루지 않아도 됩니다. 그러나 사용자 고유의 JSF 컴포넌트를 개발하거나 하나의 툴에 여러 컴포넌트를 묶으려고 한다면 자바 스크립트에 대한 기본적인 이해가 꼭 필요합니다. 브라우저간 차이를 추상화한 자바 스크립트를 이용하는 클라이언트 자바 스크립트 라이브러리를 이용할 수 있습니다. 자바 스크립트 object를 배우고자하는 자바 개발자에게는 Object Hierarchy and Inheritance in 자바 스크립트가 큰 도움이 될 것입니다.

어떤 자바 스크립트 라이브러리와 프레임웍들이 사용 가능합니까?

이미 많은 라이브러리와 프레임웍들이 브라우저 차이와 같은 성가신 것들을 추상화하는 것을 쉽게하고 있으며, 지금도 많이 생겨나고 있습니다. 그 중 dojo toolkit, prototype, DWR 이 세가지 좋은 라이브러리를 소개합니다.
  • Dojo Toolkit 은 리치한 웹 애플리케이션(rich web application)의 개발을 지원하기 위한 API들과 위젯(widget)들을 포함하고 있습니다. Dojo는 intelligent packaging system, UI 효과, Drag and drop API, widget API, event abstraction, client storage API, AJAX 인터랙션 API등을 포함합니다. Dojo는 브라우저의 '뒤로(back)' 버튼 감지 기능, url 바의 url을 북마크하는 기능, client 쪽에서 AJAX나 자바스크립트가 완전히 지원되지 않을 때 부드러운 처리 기능과 같은 네비게이션 관련 서포트와 같은 보편적인 사용에 관한 문제들을 해결해 줍니다. Dojo는 자바스크립트 라이브러리의 맥가이버칼 같은 존재라고 할 수 있습니다. 하나의 라이브러리로써는 가장 넓은 범위의 옵션을 제공하며, 신/구버전을 막론하고 여러 브라우저들을 훌륭히 지원합니다.
  • Prototype 은 자바스크립트 AJAX 오브젝트를 포함한 AJAX 인터랙션에 초점을 맞추고 있습니다. 이는 요청을 하거나, 문서의 일부를 업데이트하거나, 문서에 내용을 삽입하거나, 문서의 일부를 주기적으로 업데이트 하는 것과 같은 기본적인 태스크를 수행할 몇가지 오브젝트를 포함하고 있습니다. 프로토파입 자바스크립트 라이브러리는 AJAX 요청을 나타낼 일련의 자바스크립트 오브젝트들을 포함하고 있으며, 페이지 내 컴포넌트에 접근하거나 DOM을 조작하는 유틸리티 기능도 포함하고 있습니다. Script.aculo.usRico는 프로토타입의 최상위에 구축되었으며 UI 효과를 제공, 드래그 앤 드랍을 지원하고, 일반적인 자바스크립트 중심 위젯을 포함하고 있습니다. prototype은 AJAX 인터랙션을 비롯 기본적인 몇 개의 태스크만 지원하는 것을 찾는 사람들에게 적합합니다. 만약 UI 효과도 원한다면 Rico나 Script.aculo.us를 선택하는 것이 좋습니다.

  • Yahoo UI Library 는 유틸리티 라이브러리이며, 리치 클라이언트를 지원하는데 API를 사용하는 위젯들의 집합으로, 크로스 브라우저 AJAX 인터랙션, 애니메이션, DOM 스크립트 지원, 드래그 앤 드랍, 크로스 브라우저 이벤트 지원 등을 포함합니다. Yahoo UI 라이브러리는 세심하게 작성되어 있으며 많은 예제를 포함하고 있습니다.

  • DWR (Dynamic Web Remoting) 는 클라이언트측이자 서버측 프레임웍으로, 개발자가 클아이언트측 자바스크립트부터 자바 엔터프라이즈 에디션 웹 컨테이너 내 평범한 기존 자바 오브젝트까지 RPC를 호출할 수 있도록 하는 데에 초점을 맞추고 있습니다. 서버측에서 DWR은 자바 오브젝트와 인터랙션하는 데 서블렛을 사용하여 자바 오브젝트나 XML 문서의 오브젝트 표현을 리턴합니다. DWR은 쉽게 돌아갈 것이고 다른 자바 기술들과 잘 조화됩니다. 통합이 잘되는 클라이언트/서버 겸용 프레임웍을 찾는다면 DWR을 사용하시면 됩니다.

  • Zimbra 는 리치 자바스크립트 기반의 클라이언트에게 e-mail을 노출(expose)하는 기능 등 메시징을 가능하게 하는 것에 중점을 두는 클라이언트/서버 프레임웍입니다. 포함되어 있는 툴킷에는, 브라우저 차이를 추출하는 UI toolkit API(다양한 빌트인 위젯 포함), UI 이벤트 커뮤니케이션과 클라이언트-서버 이벤트 커뮤니케이션을 가능하게 하는 이벤트 API, 클라이언트 상에서 자바스크립트 개발을 쉽게 하는 유틸리티 클래스, 크로스 브라우자 DOM 문제 처리를 쉽게 하는 DOM API 추상, 자바스크립트 클라이언트가 AJAX와 SOAP를 이용하여 커뮤니케이션하는 것을 돕는 network API가 있습니다.

자바 스크립트를 위한 새로운 라이브러리들이 쏟아져 나오고 있으며, 위의 목록은 많이 알려진 l라이브러리들에 대해서만 소개한 것입니다. 라이브러리를 선택할 때는 개발자 본인의 필요를 가장 잘 충족시켜 주는 것을 선택하시기 바랍니다. 하나의 라이브러리를 선택하는 것이 좋지만, 여러 종류의 프레임웍을 사용하여도 문제 없습니다. 좀 더 클라이언트측 프레임웍의 리스트는 Survey of AJAX/자바 스크립트 Libraries를 참고하시기 바랍니다.

리턴 타입으로 XML이나 text, 또는 자바 스크립트, HTML을 사용해야 하나요?

경우에 따라 다릅니다. AJAX의 X가 XML를 뜻하기는 하지만, 몇몇 AJAX 프로포넌트의 경우 해당 AJAX 자체는 자바 스크립트나 html, 단순 text 등의 이(異)종 payload의 사용을 전혀 제한하고 있지 않음을 금방 알아챌 수 있을 것입니다.

  • XML - 웹 서비스와 AJAX는 서로를 위해 만들어진 것처럼 잘 맞습니다. RESTful Web Services로부터 XML 컨텐츠를 다운로드받고 파싱하는데 클라이언트측 API를 사용할 수 있습니다. (그러나 몇몇 SOAP 기반 웹서비스 아키텍처의 경우 payload가 상당히 크고 복잡할 수 있으며, 이에 따라 AJAX 테크닉을 적용하기에 부적당할 수 있습니다.)
  • 단순 Text - 서버에서 생성된 텍스트가 문서에 주입되거나 클라이언트측 로직에 의해 evaluate됩니다.
  • 자바 스크립트 - 서버측 컴포넌트가 자바스크립트 객체 선언을 포함한 자바스크립트의 fragment를 전달한다는 예외를 제외하고는 단순 text의 연장선으로 볼 수 있습니다. 자바스크립트의 eval() 기능을 이용하여 클라이언트 상에서 객체를 생성할 수 있습니다. 데이터 교환 명세에 기반한 자바스크립트 객체인 JSON이 이 방법을 이용합니다.
  • HTML - 서버에서 생성된 HTML fragment를 문서에 바로 주입하는 것은 일반적으로 매우 효과적인 AJAX 테크닉입니다. 하지만, 서버측 컴포넌트를 클라이언트의 화면 디스플레이와 같도록 유지하는 것은 복잡할 수 있습니다.

Mashup은 이(異)종의 웹서비스나 기타 다른 온라인 API에서 가져온 내용을 조합함으로써 완전히 새로운 웹 애플리케이션을 만드는 것을 일컫는 유명한 용어입니다. Mashup에 대한 좋은 예는 craiglist.org의 주택 광고와 maps.google.com의 지도를 그래픽적으로 조합하는 housingmaps.com에서 찾아볼 수 있습니다.

AJAX를 사용할 때 고려해야할 점은 무엇입니까?

AJAX 인터랙션과 DHTML을 통해 검색된 데이터를 다이내믹하게 사용하여 페이지를 업데이트하면 페이지의 모습과 상태가 과감히 바뀔 수도 있습니다. 사용자는 원하는 때에 브라우저의 '뒤로' 혹은 '앞으로'버튼을 사용하거나, 페이지를 북마크하거나, url bar에서 url을 카피하고 그것을 e-mail이나 온라인 메신저를 통해 친구와 공유하거나 페이지를 인쇄할 수 있습니다. AJAX 기반 애플리케이션 설계 시 네비게이션, 북마킹, 인쇄, 브라우저 지원의 경우에 예상되는 비헤이비어에 대해 다음과 같이 고려해야 합니다.

  • 네비게이션 - 애플리케이션 디자인에서 브라우저의 [뒤로, 앞으로, 새로고침, 즐겨찾기에 추가] 버튼을 클릭할 경우의 비헤이비어. 수작업으로(manually)지난 history manipulation을 수행할 수 있다면, API의 history manipulation과 네비게이션 컨트롤을 제공하는 Dojo와 같은 자바스크립트 프레임웍을 사용하는 것이 더 쉬울 것입니다.
  • 즐겨찾기 추가와 URL 공유하기 - 많은 사용자들은 URL을 즐겨찾기에 추가하거나, 주소창에서 잘라내어 붙여넣기 하고 싶어합니다. Dojo는 즐겨찾기 추가와 URL 조작을 위한 클라이언트 측을 제공합니다.
  • 인쇄 - 다이내믹하게 표현되는 페이지는 가끔 인쇄할 때 문제가 되기도 합니다.

개발자로서 AJAX를 사용할 때 고려해야 할 또다른 점;

  • 브라우저 지원 - 모든 AJAX/DHTML의 기능이 모든 브라우저에서 지원되는 것은 아닙니다. 지원 브라우저과 가능한 대안 목록은 quirksmode.org에서 볼 수 있습니다.
  • 자바스크립트 끄기 - 만약 사용자가 자바스크립트 기능을 활성화하지 않는다면 어떤 일이 벌어질지도 미리 고려해야 합니다. 더구나, 간혹 어떤 사용자의 웹 브라우저에서는 몇 가지 이유로 자바스크립트와 css지원이 불가능할 수밖에 없습니다.
  • 대기 시간 - 설계시 대기 시간을 고려해야 합니다. 작동 중인 애플리케이션은 당연히 deployed되었을 때의 애플리케이션보다 훨씬 반응이 빠릅니다. 또한, 여러 개의 리퀘스트를 생성했을 때 모든 return order가 보장되니 않음을 기억해야 합니다. 대기 시간에 대한 자세한 논의는 AJAX Latency problems: myth or reality?를 참고하시기 바랍니다.
  • 접근성 - 장애가 있는 사람들도 이용할 수 있는 사이트를 만드는 것은 고귀한 정신의 차원이 아니라, 많은 시장에서 법으로 규정되어 있습니다. 몇몇 훌륭한 테크놀로지들 덕분에 시각 장애, 청각 장애, 신체 장애, 언어 장애, 인지 장애, 신경 장애 등 장애를 가진 사람들도 웹을 이용할 수 있게 되었습니다. 조금 앞선 시각으로 몇몇 베스트 프렉티스를 살펴본다면 enabling 기술과 호환이 가능한 애플리케이션을 제작할 수 있을 것입니다.

Degradability란 다양한 웹 브라우저의 다양한 사양에 적응하기 위해 웹 애플리케이션에서 쓰이는 테크닉을 말합니다. 많은 AJAX 라이브러리는 자동 degradability를 내장하고 있습니다. 하지만 자체적으로 AJAX 기능을 코딩하고 있다면, W3C(World Wide Web Consortium)와 같은 표준 기구에서 추천하는 좋은 예제나 Web Standards 커뮤니티 같은 곳에서 이루어지는 움직임에 관심을 가져보시기 바랍니다. 이를 통해 AJAX를 지원하지 않는 브라우저에서도 돌아가는 애플리케이션을 제작할 수 있을 것입니다. 이런 구형 브라우저에서는 눈길을 확 잡아끄는 요소는 표현되지 않을 수 있지만, 여전히 무난하게 작동할 것입니다.

단지 멋져 보이게 하기 위해서 AJAX를 사용해서는 안 됩니다. 애플리케이션을 개발하는 이유는 사람들이 사용하게 하기 위해서입니다. 사용자들은 그들의 웹브라우저와 호환이 되지 않는다면 그 애플리케이션을 사용하지 않을 것입니다.

자바스크립트를 어떻게 디버깅하나요?

클라이언트측 디버깅과 서버측 디버깅을 동시에 지원하는 툴은 많지 않습니다. 그러나 AJAX 애플리케이션이 확산되면 상황이 많이 바뀔 것이라고 생각합니다. 필자의 경우 현재 클라이언트측 디버깅과 서버측 디버깅을 따로 하고 있습니다. 아래는 보편화된 브라우저들에서 사용되는 클라이언트측 디버거들에 대한 설명입니다.

  • Firefox/Mozilla/Netscape - venkman이라는 매우 유용한 디버거를 포함하고 있습니다. 필자 개인적으로는 주로 firefox 상에서 애플리케이션을 개발하고 나서 다른 브라우저를 시도하는 것을 좋아합니다.
  • Safari - 활성화되어야 하는 디버거를 포함하고 있습니다. 자세한 내용은 Safari FAQ를 참고하시기 바랍니다.
  • Internet explorer - 자바 스크립트를 디버깅하는 데에 대한 MSDN Documentation가 있습니다. IE를 위한 developer toolbar 역시 도움이 될 것입니다.

물론 많은 개발자들이 사용하는 alert() function을 System.out.println()와 같이 함수 호출하는것도 가능합니다. Dojo와 같은 몇몇 프레임웍들은 디버그 statement를 추적할 수 있는 API들을 제공합니다.

AJAX 호출을 위해 HTTP GET 또는 POST를 사용해야 합니까?

AJAX request는 데이터를 검색할 때(retrieve) 데이터가 주어진 요청 URL로 바뀌지 않을 곳에서 HTTP GET request를 사용해야 합니다. HTTP POST는 상태가 서버에 업데이트되었을 때 사용해야 합니다. 이것은 HTTP idempotency recommendations 와 잘 조화되며, 일관성있는 웹 애플리케이션 아키텍쳐를 위해 강력하게 권장됩니다.

국제화된 AJAX 인터랙션은 어떻게 제공하나요?

XML을 사용하고 있다는 사실이 로컬 컨텐츠를 AJAX 리퀘스트를 사용하여 적절하게 보내고 받을 수 있다는 것을 의미하지는 않습니다. 국제화된 AJAX 컴포넌트를 제공하기 위해서는 다음의 작업이 필요합니다.

  • 페이지의 chartset을 지정한 언어가 지원되는 인코딩으로 설정합니다. 필자 개인적으로는 거의 모든 언어를 커버하는 UTF-8을 주로 사용합니다. HTML/JSP 페이지 내에서 다음과 같은 메타 선언을 통해 컨텐츠 타입을 설정할 수 있습니다.
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    
      
  • 페이지에서 자바 스크립트는 서버로 보내진 모든 파라미터를 인코딩합니다. 자바 스크립트는 로컬 텍스트가 6진법 형태로 쓰여있는 Unicode escape strings를 반환하는 escape()함수를 제공합니다. 자바스크립트 인코딩에 대한 더 자세한 정보는 Comparing escape(), encodeURI(), and encodeURIComponent()를 참고하시기 바랍니다,.
  • 서버측 컴포넌트 상에서 HttpServletRequest.setCharacterEncoding() 메소드를 사용하여 문자 인코딩을 설정합니다. 이것은 HttpServletRequest.getParameter()로 파라메터를 꺼내기 전에 해야합니다. UTF의 경우에는 request.setCharactherEncoding("UTF-8");이 됩니다.

AJAX response를 반환하는 서버측 컴포넌트는 response의 인코딩을 페이지에서 사용된 인코딩과 같게 설정해야 합니다.

    response.setContentType("text/xml;charset=;UTF-8");
    response.getWriter().write("<response>invalid</response>"); 

Java Enterprise Edition technologies로 AJAX를 사용하는 것에 대한 더 많은 정보는 AJAX and Internationalization를 참고하시고, 여러 가지 언어로 된 애플리케이션을 개발하는 것에 대한 정보는 Developing Multilingual Web Applications Using JavaServer Pages Technology를 참고하시기 바랍니다.

동시에 발생하는 AJAX 요청을 어떻게 처리해야 할까요?

자바스크립트를 사용하면 한번에 한 개 이상의 AJAX request를 프로세싱하게 될 수 있습니다. 코드의 적절한 차후 프로세싱을 보장하기 위하여 자바 스크립트 Closures를 이용할 것을 권해드립니다. 다음의 예제는 AJAX인터랙션라는 자바스크립트 객체에 의해 추상화된 XMLHttpRequest 객체를 보여줍니다. 인수로서 URL과 프로세스가 완료되었을 때 실행되는 function을 전달하고 있습니다.

function AJAX인터랙션(url, callback) {

    var req = init();
    req.onreadystatechange = processRequest;
        
    function init() {
      if (window.XMLHttpRequest) {
        return new XMLHttpRequest();
      } else if (window.ActiveXObject) {
        return new ActiveXObject("Microsoft.XMLHTTP");
      }
    }
    
    function processRequest () {
      if (req.readyState == 4) {
        if (req.status == 200) {
          if (callback) callback(req.responseXML);
        }
      }
    }

    this.doGet = function() {
      req.open("GET", url, true);
      req.send(null);
    }
    
    this.doPost = function(body) {
      req.open("POST", url, true);
      req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
      req.send(body);
    }
}

function makeRequest() {
  var ai = new AJAXInteraction("processme", function() { alert("Doing Post Process");});
  ai.doGet();
}


위 예제의 makeRequest() 함수는 "processme"라는 URL을 갖는 AJAX인터랙션과, "doing Post Process"라는 메시지가 담긴 경고 메시지 상자를 보여줄 인라인 함수를 생성합니다. AJAX 인터랙션은 ai.doGet()가 호출될 때 시작되고 서버측 컴포넌트가 "processme" URL 위에 위치할 때 문서를 반환합니다. 이 문서는 AJAX인터랙션이 생성될 때 지정된 callback 함수로 넘겨진 것입니다.

이 closure의 사용은 특정한 AJAX 인터랙션과 관련된 적절한 callback 함수가 호출되도록 보장합니다. 어떤 주어진 시간에 request를 생성하는데 사용되는 socket의 수는 제한되어 있으므로, 그 안에 복수의 closure 객체를 생성하는 것이 XmlHttpRequest를 생성할 때는 주의해야 합니다. 예를 들어 인터넷 익스플로러는 오직 두 개의 AJAX 동시 요청에만 반응할 수 있습니다. 다른 브라우저는 3~5개까지 가능합니다. AJAX 인터랙션 객체들의 공유 풀을 활용하시기 바랍니다.

Client로부터 복수의 AJAX 호출을 생성할 때 한가지 기억해야할 것은, 호출에 대해 모두 반응한다고 보장할 수 없다는 것입니다. Closure 객체의 callback 내에 closure을 가짐으로써 depedency들이 올바르게 프로세스되었음을 보증하는데 사용할 수 있습니다.

Ajaxian Fire and Forget Pattern를 읽어보시면 도움이 될 것입니다.

AJAX 클라이언트와 인터랙션하기 위해 서버 상에서 해야하는 일은 무엇인가요?

'content-type' 헤더를 'text/xml'로 설정해야 합니다 . 서블렛에서 리턴 타입이 XML이면 HttpServletResponse.setContentType()를 "text/xml"로 설정함으로써 실행될 수 있습니다. "Content-Type" 헤더가 설정되어 있을 경우, XMLHttpRequest 실행이 에러가 나는 경우가 많습니다. 다음은 "Content-Type"을 설정하는 방법입니다.

    response.setContentType("text/xml");
    response.getWriter().write("<response>invalid</response>"); 

또한, autocomplete와 캐쉬 여부도 설정하는 편이 좋을 수 있습니다.

    response.setContentType("text/xml");
    response.setHeader("Cache-Control", "no-cache");
    response.getWriter().write("<response>invalid</response>"); 

개발자를 위한 참고사항: 인터넷 익스플로러에서는 이 헤더가 설정되어있지 않은 경우 HTTP GET에서 돌아오는 모든 AJAX 반응에 대해 캐쉬된 결과물을 자동으로 사용하므로 일이 복잡해질 수 있습니다. 개발하는 중에는 이 헤더를 설정해 두는 것이 좋을 것입니다.

AJAX 클라이언트의 상태를 어디에 저장하나요?

다른 브라우저 기반의 웹 애플리케이션을 사용하는 경우에 다음과 같은 몇 가지 옵션들이 있습니다.

  • 클라이언트의 쿠키에 - 크기 제한이 있으며(도메인당 4KB짜리 쿠키 최대 20개, 총 80KB) 암호화하지 않는 한 내용의 보안을 장담할 수 없습니다. 암호화하는 것은 어려운 작업이지만 자바스크립트를 이용하면 할 수는 있습니다.
  • 클라이언트의 페이지에 - 이 방법을 사용하면 보안은 확실하지만 작업하기가 어렵고 말썽을 일으킬 수가 있습니다. Storing State on the Client를 참고하시기 바랍니다.
  • On the client file system - This can be done if the client grants access to the browser to write to the local file system. 클라이언트의 파일 시스템에 -브라우저가 로컬 파일 시스템에 접근하는 것을 클라이언트가 허용할 경우 가능한 방법입니다. 개인에 따라 필수적인 방법이 될 수도 있으나 주의가 요구됩니다.
  • 서버에 - 클라이언트가 서버상의 상태를 반영하는 전통적인 모델에 가까운 방법입니다. 양쪽의 데이터가 동일하도록 유지하는 것은 약간 골치아플 수 있지만 이것에 대한 해결책은 있습니다. (Refreshing Data) 더 많은 프로세싱되는 정보나 컨트롤이 클라이언트로 이동할수록, 상태가 저장되어 있는 곳은 계속해서 갱신되어야 할 것입니다.

16. form이나 form의 일부를 페이지를 새로고침하지 않고 삽입하는 방법은 무엇입니까?

Form을 생성할때는 "form" 요소 "onSubmit" 속성이 false를 반환하는 자바 스크립트 함수로 설정되어 있는 것을 확인해야 합니다.

  <form onSubmit="doAJAXSubmit();return false;" >
   <input type="text" id="tf1" />

   <input type="submit" id="submit1" value="Update"/>
  </>

form 버튼이 있는 함수를 결합시킴으로써 비슷하게 데이터를 제출할 수도 있습니다.

  <form onSubmit="doAJAXSubmit();return false;" >
   <input type="text" id="tf1" />

   <input type="button" id="button1" onClick="doAJAXSubmit()" value="Update"/>
  </>

form "onsubmit" 속성이 여전히 설정되어 있는 것에 주목하시기 바랍니다. 만약 사용자가 텍스트 필드에서 엔터를 치면 form이 작성완료되어 버리므로, 이 문제를 해결해야 합니다.

페이지를 업데이트할 때는, 페이지 안의 데이터를 업데이트하기 전에 form 데이터의 AJAX 업데이트가 성공적으로 끝났는지 먼저 확인하는 것이 좋습니다. 그렇지 않으면 데이터가 무사히 업데이트되지 않을 수 있고 사용자가 알지 못할 수도 있습니다. 개인적으로는 부분적으로 업데이트를 할 때 잠시 공지를 띄워 놓았다가, AJAX 인터랙션이 성공적으로 끝나면 그때 페이지를 업데이트합니다.

컨트롤하는 것은 서버입니까 클라이언트입니까?

그때그때 다릅니다. AJAX에서는 대체로 '중간쯤'이라고 답할 수 있습니다. 서버측 컴포넌트, 혹은 클라이언트측과 서버측 컨트롤러들이 조합된 경우에는 컨트롤의 위치가 더욱더 한쪽에 치중될 수 있습니다.

  • 서버측 컨트롤러 집중 - 이 때의 핵심은 클라이언트측 페이지의 데이터가 서버의 데이터와 같도록 유지하는 것입니다. 몇몇 애플리케이션은 모든 상태 정보를 서버에 저장하고 모든 업데이트를 간단한 자바스크립트 컨트롤러를 통해 클라이언트 DOM에 보냅니다.
  • 클라이언트측/ 서버측 컨트롤러 - 이런 아키텍쳐는 컨트롤이나 이벤트 프로세싱, 페이지 조작, 클라이언트 상의 모델 데이터 랜더링과 관련된 모든 표현을 자바스크립트가 하도록 합니다. 비즈니스 로직이나 업데이트된 모델 데이터를 클라이언트로 보내는 것은 서버측에서 담당합니다. 이 경우 서버는 최초로 클라이언트에 보내진 페이지 이외에 presentation에 대한 정보를 가질수 없습니다.

    AJAX 애플리케이션 전체가 한 페이지 안에 작성된 케이스가 있습니다. 만약 이런 아키텍쳐를 택한다면, 네비게이션과 즐겨찾기 추가의 처리 문제를 고려해야 합니다.

완성 목적에 따라 두 가지 방법을 자유롭게 사용할 수 있습니다. 개인적으로는 클라이언트와 서버에 제어권을 나누어 주는 방법을 선호합니다.

AJAX와 관련된 보안 이슈는 무엇입니까?

자바 스크립트는 사용자가 페이지의 소스 보기를 선택하는 경우 밋밋하게 보입니다. 자바 스크립트는 사용자의 허가가 없이는 로컬 파일시스템에 접근할 수 없습니다. AJAX 인터랙션은 해당 페이지가 로딩되는 서버측 컴포넌트에만 관련이 있습니다. 외부 서비스에서는 AJAX 인터랙션에 프록시 패턴이 사용될 수 있습니다.

만약 악의를 가진 사용자가 당신의 애플리케이션을 전복시키려는 의도로 접근할 때 서버측 컴포넌트가 위험에 처하게 될 수 있으므로 애플리케이션 모델을 노출시키지 않도록 조심하십시오. 모든 다른 웹애플리케이션에는, 비밀 정보가 교환될 때 연결의 보안을 확실히 하기 위해 HTTPS의 사용을 고려해 볼 수 있습니다.

Synchronous와 asynchronous request를 각각 어떤 때 사용하나요?

좋은 질문입니다. 아무 이유없이 AJAX를 호출하지 않습니다! 동기(synchronous) 요청은 페이지 이벤트 프로세싱을 차단할 것이며, 비동기 (asynchronous) 요청이 선호되는 경우는 별로 본 적이 없습니다.

애플릿과 플러그인은 어떻습니까?

애플리케이션에서 플러그인이나 애플릿에 기반한 부분들을 바로 버리지 마십시오. AJAX와 DHTML이 드래그 앤 드랍과 같은 상위 사용자 인터페이스들을 지원하는 반면, 여전히 한계가 있으며, 특히 브라우저 지원에 있어서 그렇습니다. 플로그인과 애플릿은 수년간 AJAX와 비슷한 요청을 생성하는데 이용되어 왔습니다. 애플릿은 개발하는 데 필요한 거의 모든 것을 제공하는 UI 컴포넌트와 API를 다수 제공합니다.

많은 사람들이 플러그인을 초기화할 때 기다려야 하며 필요한 버전의 JVM 플러그인이 깔려 있을지 없을지 모른다는 이유로 애플릿이나 플로그인을 경시합니다. 플러그인이나 애플릿이 페이지 DOM을 조작하는 것은 불가능할지 모릅니다. 그러나 균일한 환경에 있거나 특정 JVM이나 플러그인이 사용 가능한 환경 (예를 들어 기업 환경)에서 플로그인이나 애플릿은 유용하게 사용될 수 있습니다.

한가지 고려해야 할 것은, AJAX와 애플릿과 플러그인이 혼재되어 있는 경우입니다. Flickr 는 사용자 경험을 위해 그림에 라벨을 붙이고 유저 인터랙션, 사진 수정 등에 AJAX 인터랙션과 DHTML을 조합하여 사용합니다. 서버측 컴포넌트를 잘 설계한다면 두 클라이언트 모두와 커뮤니케이션이 가능합니다.

'뒤로'와 '앞으로' 버튼을 어떻게 처리하나요?

애플리케이션의 현재 상태를 추적할 수 있는 고유의 솔루션을 만들 수도 있지만, 전문가들에게 이 문제를 넘기는 것이 좋을 것이라고 생각합니다.Dojo는 밑의 자바 스크립트 예제에서 보이는 것처럼 브라우저 안에서의 네비게이션을 중립적으로 어드레스합니다.

function updateOnServer(oldId, oldValue, itemId, itemValue) {
    var bindArgs = {
        url:  "faces/ajax-dlabel-update",
        method: "post",
        content: {"component-id": itemId, "component-value": itemValue},
        mimetype: "text/xml",
	    load: function(type, data) {
               processUpdateResponse(data);
             },
        backButton: function() {
               alert("old itemid was " + oldId);
			},
        forwardButton: function(){
               alert("forward we must go!");
            }
     };
    dojo.io.bind(bindArgs);
}

이 예는 서버 상의 값을 함수와 함께 dojo.io.bind()를 사용하여 업데이트합니다. dojo.io.bind()는 브라우저의 '뒤로' 버튼 이벤트를 담당하는 고유한 속성으로 사용됩니다. 개발자라면 oldValue에 값을 재저장하거나 뭔가 다른 적당한 액션을 취할 수 있을 것입니다. 하단의 링크는 어떻게 Dojo가, 개발자가 브라우저의 버튼 이벤트를 감지하지 못하게 하는지에 대한 설명입니다.

AJAX: How to Handle Bookmarks and Back Buttons 이 문제에 대한 자세한 설명이 담겨 있으며, '뒤로'와 '앞으로' 문제에 대해서만 논의하는 자바 스크립트 library Really simple History framework(RSH)를 제공합니다.

AJAX를 사용하여 이미지를 전송하는 방법은 무엇인가요?

Google maps와 같은 애플리케이션으로 AJAX를 사용하면 이미지가 보내지는 것처럼 보일 수 있으나, 사실은 이미지의 URL들이 AJAX 요청에 대한 반응이 보내지고 DHTML을 사용하여 그 URL들이 보내지고 있는 것입니다.

하단은 XML 문서가 AJAX 인터랙션으로부터 리턴되고 카테고리 바가 삽입된 예입니다.

<categories>
<category>
  <cat-id>1</cat-id>

  <name>Books</name>
  <description>Fun to read</description>
  <image-url>books_icon.gif</image-url>
 </category>

<category>
  <cat-id>2</cat-id>
  <name>Electronics</name>
  <description>Must have gadgets</description>

  <image-url>electronics.gif</image-url>
 </category>
</categories>

image-url 요소가 카테고리를 대표하는 이미지 URL의 위치를 담고 있음에 주목하시기 바랍니다. AJAX 인터랙션의 callback 메소드는 response XML 문서를 파싱할 것이며, response XML 문서 안에 포함된 각각의 카테고리 addCategory 함수를 호출합니다. 이 addCategory 함수는 페이지의 body안에 있는 table row element인 "category table"을 올려다보며 이미지를 포함하는 요소에 한 row를 추가합니다.

<scrip type="text/자바 스크립트" >

...

function addCategory(id, name, imageSrc) {

    var categoryTable = document.getElementById("categoryTable");
    var row = document.createElement("tr");
    var catCell = document.createElement("td");
    var img = document.createElement("img");
    img.src = ("images\\" + imageSrc);
    var link = document.createElement("a");
    link.className ="category";
    link.appendChild(document.createTextNode(name));
    link.setAttribute("onclick", "catalog?command=category&catid=" + id);
    catCell.appendChild(img);
    catCell.appendChild(link);
    row.appendChild(catCell);
    categoryTable.appendChild(row);
}

</script>

...

<table>
 <tr>
  <td width="300" bgoclor="lightGray">
    <table id="categoryTable" border="0" cellpadding="0"></table>

  </td>
  <td id="body" width="100%">Body Here</td>
 </tr>
</table>

이미지의 출처는 이미지 소스로 설정되어 있음을 유의하세요. 이 이미지는 이미지 요소가 categoryTable에 추가되었을 때 images/books_icon.gif" 이나 "images/electronic_icon.gif"이라는 URL의 HTTP 요청에 의해 로딩됩니다.

AJAX 폴링(polling)을 하기 위한 쓰레드를 어떻게 생성하나요?

자바 스크립트는 쓰레드가 없습니다. 자바 스크립트의 함수들은 페이지가 로딩되거나, 마우스 클릭이 있거나, 어떤 form 요소에 표시를 할 때 등의 이벤트가 발생할 때 호출됩니다. 함수의 이름과 시간(밀리세컨 단위)를 인수로 사용하는 setTimeout 함수를 사용하여 타이머를 만들 수 있습니다. 그런 다음, 같은 함수를 하단의 자바 스크립트 예제처럼 호출함으로써 루프를 생성할 수 있습니다.

function checkForMessage() {
  // start AJAX 인터랙션 with processCallback as the callback function
}

// callback for the request
function processCallback() {
    
    // do post processing
    
    setTimeout("checkForMessage()", 10000);
}

checkForMessage는 무기한으로 루프를 돌린다는 점을 주의하시기 바랍니다. 페이지의 특성에 따라 간격의 인크레먼트를 바꿀 수도 있습니다. 또한 특정 AJAX 반응 프로세싱 조건에 따라 루프가 정지되는 로직을 추가할 수도 있습니다.

댓글