06.Ajax2010. 10. 29. 11:35
반응형

AJAX Solutions can be used by web developers to create amazing applications. Dozens of projects, even Gmail, made with AJAX provide new interactivity for applications that can have enhanced user functionality. Using AJAX, better, faster, more flexible web solutions are available. AJAX is the first step toward web applications of the future.

What exactly is AJAX? AJAX is an acronym for Asynchronous JavaScript and XML, and though some think it’s a new programming language, it’s really not. AJAX is basically XHTML, DOM, CSS, XML, XMLHttpRequest used together to do one thing, which is to improve the user-server interaction.
• To better understand AJAX, check out some articles about it.
• To learn the AJAX basics, look up some tutorials.
• To learn about CSS, look up some articles and tutorials.

Remember: Google is your friend!
Contained in this article are 80+ AJAX scripts and resources you should have at your side while designing your own applications. Auto-completion, instant field editing, menus, calendars, interactive elements, visual effects, animation, basic Javascript, as well as an extensive developer’s suite are contained here for a useful toolbox, so that you don’t have to go through a huge list of bookmarks.

Auto Complete Scripts

1. AJAX AutoSuggest

2. AJAX Autocompleter / script.aculo.us library

3. AJAX AutoCompleter

4. Ajax autosuggest/autocomplete from database

5. Ajax dynamic list

Instant Editor Scripts

6. AJAX inline text edit 2.0

7. AJAX & CSS Flickr-like Editing Fields

8. AJAX Instant Edit

Tab and Menu Scripts

9. 14 Tab-Based Interface Techniques

10. AJAX Accordion Navigation

11. AJAX Dialogs, Menus, Grids, Trees and Views

12. AJAX Tab Module - Closeable Implementation

13. Ajax Tabs Content

14. MooTabs - Tiny tab class for MooTools

15. Dynamically loaded articles

Calendar/Datetime Scripts

16. AJAX Datetime Toolbocks - Intuitive Date Input Selection

17. AJAX Calendars

Interactive Elements Scripts

18. AJAX Floating Windows

19. AJAX Star Rating Bar

20. Ajax poller

Developer’s Suite Scripts

21. AJAX HistoryManager, Pagination

22. AJAX Login System Demo

23. AJAX image preloader

24. AJAX Tooltips: Nice Titles revised | Blog | 1976design.com

25. 40+ Tooltips Scripts With AJAX, JavaScript & CSS | Smashing Magazine

26. AJAX Web Controls

27. AJAX syntaxhighlighter

28. Transparent Message

29. ModalBox — An easy way to create popups and wizards

30. Chained select boxes

31. Fly to basket

32. AJAX Key Events Signal

33. Disable form submit on enter keypress

Enhanced Solutions

34. AJAX Instant Completion

35. Novemberborn: Event Cache

36. Altering CSS Class Attributes with JavaScript

37. Select Some Checkboxes JavaScript Function

38. AJAX Emprise Charts

39. amCharts: customizable flash Pie & Donut chart

40. PJ Hyett : The Lightbox Effect without Lightbox

Forms

41. AJAX Upload Form

42. An AJAX contact form

43. AJAX contact form

44. Ajax.Form

45. Ajax form validation

46. Really easy field validation

47. AJAX fValidate

48. Ajax newsletter form

49. wForms

Tables and Grids

50. Data Grids with AJAX, DHTML and JavaScript | Smashing Magazine

51. Grid3 Example

52. AJAX Table Sort Script (revisited)

53. AJAX Sortable Tables

54. AJAX TableKit

Showcases, Galleries, and Lightbox Scripts

55. 30 Scripts For Galleries, Slideshows and Lightboxes | Smashing Magazine

56. AJAX LightBox, Sexy Box, Thick Box

57. AJAX Lightbox JS

58. AJAX Unobtrusive Popup - GreyBox

59. SmoothGallery: Mootools Mojo for Images | Full gallery

60. AJAX Libraries and Frameworks

Animation and Visual Effects Scripts

61. How to Create Digg Comment Style Sliding DIVs with Javascript and CSS

62. How to Create a Collapsible DIV with Javascript and CSS

63. How to Create an Animated, Sliding, Collapsible DIV with Javascript and CSS

64. AJAX Shopcart

65. Draggable content

66. Dragable RSS boxes

67. AJAX Pull Down Effect

68. AJAX Animation Effects

69. Combination Effects in scriptaculous wiki

70. AJAX Motion Transition

Useful Javascript Scripts

71. 9 Javascript(s) you better not miss!

72. Top 10 custom JavaScript functions of all time

73. Hyperdisc Materials: JavaScript: Top 10: Automatic Breadcrumb Trail

74. JavaScript: Top 10 Most Useful JavaScripts

75. My Favorite Javascripts for Designers: Blakems.com ?

More Resources and Galleries

76. Max Kiesler - mHub : Ajax and rails examples & how-to’s

77. Ajax Resources

78. DZone Snippets: Store, sort and share source code, with tag goodness

Posted by 1010
06.Ajax2010. 4. 20. 16:24
반응형

Ajax 기본 예제와 JSP 엔진에서 한글 인코딩 충돌 문제 처리 

Ajax가 필요한 일이 발생해서, 급조해서 Ajax를 공부했다.
공부한 책은 Ajax 입문이며, 처음 약 5~60 페이지만 읽었다. 급조한 내용이니 너무 신뢰하지 말 것. 아.. 그리고 이 책, 중대한 오탈자가 은근히 있다. 혹시 이 책으로 공부하고자 한다면 오탈자를 확인한 뒤에 공부해서 불필요한 시간 낭비를 줄이는 것이 좋겠다.

아무튼, 책의 내용중 Ajax의 기본적인 사용에 관한 문제를 정리하고, 또 JSP/Servlet 엔진에서 Ajax사용시에 발생하는 한글 인코딩(encoding)문제의 처리방법도 정리해 둔다.


Ajax의 개념에 관한 설명은 인터넷 상에 차고 넘치므로 생략.

* A Simpler Ajax Path가 Ajax 입문에 좋은 글.


Ajax의 개발 순서

1. XMLHttpRequest 객체 생성
2. HTTP 요청을 발생시킴(open(), send())
3. 서버측에서 XMLHttpRequest를 통해 보낸 요청을 받아서 파라미터를 분석하고, 작업을 한 뒤에 결과를 XML이나 문자열로 리턴한다.
4. XMLHttpRequest로 서버가 리턴한 데이터를 받아서 처리(onreadystatechange, responseText, responseXML)


XMLHttpRequest에 의한 송수신 상세 예


JavaScript에서 XMLHttpRequest Object 생성하기


// XMLHttpRequest 오브젝트 생성 함수
// @sample oj = createHttpRequest();
// @return XMLHttpRequest 오브젝트
function createHttpRequest()
{
    if (window.ActiveXObject) {
        try {
            // IE6
            return new ActiveXObject("Msxml2.XMLHTTP");
        } catch (e) {
            try {
                // IE4, IE5
                return new ActiveXObject("Microsoft.XMLHTTP");
            } catch (e2) {
                return null;
            }
        }
    } else if (window.XMLHttpRequest) {
        // Mozilla, FireFox, Opera, Safari, Konqueror3
        return new XMLHttpRequest();
    } else {
        return null;
    }
}



HTTP 요청 발생

 1. open() 메소드 실행 (POST/GET, 요청URL, 동기/비동기지정)

var request = createHttpRequest();
request.open("GET", "/test.xml");
 
// param 1 : GET/POST
// param 2 : URL
// param 3 : 생략가능. 동기/비동기 여부. 기본 비동기.


 2. send() 메소드(데이터 송신)

 request.send(""); // 데이터 없이 전송할때 혹은
 request.send(null); // Konqueror에서는 오류 발생함. Konqueror를 제외하고 데이터 없이 전송할 때 사용가능


위 a,b가 기본적인 모양새이지만, 실제로 GET과 POST 방식에 따라 차이가 많이난다.

  * GET 방식 : GET 방식은 URL에 파라미터를 직접 붙여 보내지만, 한글 등의 문제로 인코딩이 필요하고, RequestHeader 설정도 필요하다. 일반적으로 다음과 같은 모양이 된다.

var paramName = encodeURIComponent("파라미터명"); // 파라미터이름을 UTF-8로 인코딩
var paramValue = encodedURIComponent("파라미터값"); // 파라미터 값을 UTF-8로 인코딩

// 파라미터 구분에 사용되는 ?와 &는 인코딩 되면 안된다. 그래서 따로 붙인다.
var fullParameter = '?' + paramName + '=' + paramValue; // URL에 사용할 파라미터 구성

request.open("GET", "/test.cgi" + data);

// setRequestHeader()는 open()보다 이후에 나와야만 한다.
// 아래는 파라미터 값을 UTF-8로 인코딩해서 보내겠다는 의미.
// GET방식에서는 필요 없고, POST방식에서는 필수이다.
request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');

request.send(null);


  * POST 방식 : send() 메소드에 인수를 데이터로 넘긴다.

request.open("POST", "/test.cgi");
request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
// POST 방식에서도 파라미터를 인코딩하여 send()메소드의 인자로 넘겨주면 된다.
request.send("name=test&data=123");


A Simpler Ajax Path에 보면 HTML폼에 입력된 값을 자동으로 파라미터 문자열로 변경해주는 메소드 예가 있다.


착신과 데이터 처리

 * onreadystatechange 이벤트(송수신 상태 변할때 기동) - IE 이외 부라우저에서는 콜백 스타일의 onload 이벤트 사용가능
 * readyState 프라퍼티 (송수신 상태를 나타내는 값. "4"가 송신 완료) - onload의 경우에는 불필요
onreadystatechange는 요청 처리 상태를 나타내는 readyState 프라퍼티의 값이 바뀔 때 발생한다.
 * 착신을 처리할 함수 지정은 request.open() 함수를 호출하기 전에 선언해야 정상 작동했다. 항상 요청을 보내기 전에 요청을 처리할 함수 지정을 해둔다.

request.onreadystatechange = callbackFunction; // callbackFunction() 함수가 호출된다.

function callbackFunction() {
    // readyState == 4는 착신 완료를 의미한다.
    if (request.readyState == 4) {
        // 착신시의 처리
    }
}


다른 방법으로, callback 함수를 인라인으로 정의하고, HTTP 상태 코드가 200일때만 작업하도록 할 수도 있다. 두가지를 한꺼번에 보면,

request.onreadystatechange = funcation() {
    if (request.readyState == 4 &&
            request.status == 200) {
        // 착신시의 처리
    }
}


onreadystatechange 대신 onload를 사용할 수 있다. Opera 8은 버그때문에 onload만 사용한다. (IE를 제외한 다른 브라우저에서 다 된다)

request.onload = function() {
    // 착신시의 처리
}


onload와 onreadystatechange를 동시에 이용하기 위해서 다음과 같이한다.

if (window.opera) {
    request.onload = function() { callback(request); }
} else {
    request.onreadystatechange = function() {
        if (request.readyState == 4) {
            callback(request);
        }
    }
}

function callback(request) {
    // 실제 착신시의 처리를 구현하는 부분
}


 * responseText 또는 responseXML (데이터를 텍스트 혹은 DOMDocument로 수신)
   * responseText : 텍스트로 받기
   * responseXml : XML로 받기
   * 여러줄의 CSV 텍스트를 받았을 때의 일반적 처리

var res = request.responseText;
var rows = res.split(" "); // 여러 줄을 한 줄씩 배열로 만든다.
var cols = rows[0].split(","); // 첫번째 줄을 쉼표 단위로 분리하여 배열로 만든다.


   * JSON 처리

eval("res = " + request.responseText)
//... 기타 처리


   * XML 처리


  Toshiro Takahashi
  hello



var res = request.responseXML;
var msgs = res.getElementsByTagName("msg"); // DOM 객체 사용

alert(msg[0].firstChild.nodeValue);



서버측 스크립트

XMLHttpRequest.send() 에 의해 요청을 받아 처리하게 되는 서버측 스크립트(JSP, Servlet, ASP, PHP 등)은 요청 파라미터를 분석하여 작업을 처리한 뒤에 결과를 Text나 XML로 리턴하면 된다.
 * 리턴시 문자 인코딩은 기본적으로 UTF-8로 한다.
 * 텍스트로 리턴할 경우, Opera 8, Konqueror 3, Safari 등은 UTF-8을 인식하지 못한다. 서버는 응답 문자열을 UTF-8기준으로 URI 인코딩을 해서(Java의 경우 java.net.URLEncoder.encode() 메소드 사용) 리턴하고, 받는 측(웹 브라우져)는 다음과 같이 해석하면 정상적인 문자열을 받게 된다.(실제로는 작동하지 않으므로 URLEncoder를 사용하지말고 받는 자바 스크립트 측에서도 아래와 같이 받지 말고 그냥 request.responseText를 받을 것)

// Mozilla FireFox와 IE에서는 Encode/Decode할 경우
//공백이 +로 바뀌는 현상이 발생했다. 그래서 안쓴다.
// JavaScript측에서 decodeURIComponent를 안하면 서버측에서도 URLEncoding을 하면 안된다.
var res = decodeURIComponent(request.responseText);



JSP/Servlet 에서 Ajax와 한글 인코딩 문제

Ajax는 기본적으로 UTF-8 만으로 통신을 한다고 보면된다. 그 이외의 Encoding을 지원하는 인코딩 함수가 없기 때문에 EUC-KR로 데이터를 전송하려는 꿈은 접어야만 한다.
헌데, 아직 우리나라는 EUC-KR 인코딩으로 된 웹 어플리케이션이 압도적으로 많은 상황이다(어서 빨리 UTF-8로 옮겨가길 바라마지 않는다).
거기다가 보통 JSP/Servlet 웹 어플리케이션은 Servlet 스펙 2.3이후부터 문자 인코딩 서블릿 필터를 사용해 모든 요청에 대해 일관된 문자 인코딩을 사용하는 것이 보편적인 방법으로 자리잡았다.

서블릿 필터는 일관성있게 모든 요청을 EUC-KR로 받아들이게 했는데, 몇몇 Ajax관련 요청만 UTF-8로 받아들여야만 하는 것이다.
필터를 적용할 URL-Pattern을 따로 줘보려 했으나, 너무 복잡해졌다.
그래서 HTTP 요청의 헤더를 이용해서 해결 했다.

아.. 한가지 더. 현재 한글 문제는 "XMLHttpRequest 요청 -> JSP/Servlet" 이 상황에서만 발생하는 것이다.
"JSP/Servlet -> XMLHttpRequest"의 상황(서버에서 클라이언트로 값을 리턴)에서는 이 문제가 발생하지 않는다.
서버가 리턴하는 문자열은 간단하게 다음처럼 하면 WAS가 자동으로 UTF-8로 값을 변경해서 전달하기 때문이다.



contentType에서 text/plain은 텍스트나 JSON으로 값을 리턴할 때이다. XML로 리턴할 때는 text/xml.

아래는 Ajax 요청을 처리하기 위해서 만들어본 간단한 Encoding Filter 이다.

package ajax.filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * 어플리케이션 전체에 적용되는 필터이다.
 *
 *

 *
encoding 파라미터 : encoding 파라미터를 설정하면 request 객체에
 * setCharacterEncoding(encoding)을 실행한다.
 *
ajaxFlag 파라미터 : Ajax요청임을 나타내는 HTTP 파라미터 이름이다. ajaxFilter로 지정한 HTTP 파라미터의
 * 값이 true 로 설정되면 인코딩을 무조건 UTF-8로 설정한다.
 *

 *
 * @author 손권남(kwon37xi@yahoo.co.kr)
 *
 */
public class EncodingFilter implements Filter {

    private Log log = LogFactory.getLog(this.getClass());

    /** HTTP 요청 문자 인코딩 */
    private String encoding = null;

    /** Ajax 요청임을 나타내는 플래그 파라미터 이름 */
    private String ajaxFlag = null;

    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {

        if (ajaxFlag != null
                && "true".equals(((HttpServletRequest) request)
                        .getHeader(ajaxFlag))) {
            // Ajax 처리 요청일 경우 무조건 UTF-8 지정.
            request.setCharacterEncoding("UTF-8");
            if (log.isDebugEnabled()) {
                log.debug("요청 헤더에 " + ajaxFlag + "가 "
                        + ((HttpServletRequest) request).getHeader(ajaxFlag)
                        + "로 설정되어 있어 문자 인코딩에  UTF-8을 사용합니다.");
            }
        } else if (encoding != null) {
            // Ajax 플래그가 true가 아니면, 기본적인 인코딩을 적용한다.
            request.setCharacterEncoding(encoding);
            if (log.isDebugEnabled()) {
                log.debug("문자 인코딩에 " + encoding + "을 사용합니다.");
            }
        }

        chain.doFilter(request, response);
    }

    public void init(FilterConfig config) throws ServletException {
        encoding = config.getInitParameter("encoding");

        ajaxFlag = config.getInitParameter("ajaxFlag");

        if (log.isDebugEnabled()) {
            log.info("encoding : " + encoding + ", ajaxFlag : " + ajaxFlag);
        }
    }

    public void destroy() {
    }
}


이 필터를 적용하고서, web.xml에 다음 내용을 추가하면 필터가 작동한다.


    이중 인코딩 필터
    EncodingFilter
    ajax.filter.EncodingFilter
   
        encoding
        euc-kr
   
   
        ajaxFlag
        Ajax
   


    EncodingFilter
    /*


여기 내용을 보면, 기본적인 인코딩은 EUC-KR이고, 요청 헤더에 "Ajax" 헤더의 값이 "true"일 경우에는 강제로 UTF-8을 지정하라고 한 것이다. "ajaxFlag"의 값을 변경하면 헤더의 키을 "Ajax"가 아닌 다른 값으로도 지정할 수 있다. 하지만 아무튼 해당 헤더의 값을 "true"로 지정하면 Ajax로 인식하게 되는 것이다.

이를 위해서는 XMLHttpRequest에도 한가지 처리를 더 보태야 한다.

    request.open("GET", "AjaxProcessor.jsp" + fullParameter);
    request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
    request.setRequestHeader('Ajax', 'true');


당연히 헤더에 값 Ajax요청임을 명시하는 값을 설정하는 것이다.

그리고 다음 문제가 또 있는데, Tomcat 버전별로 문자 인코딩 설정이 달라질 수 있다는 것이다.
위 내용은 Tomcat 4.x에서는 정상 작동하지만, Tomcat 5.x 에서는 제대로 작동하지 않는다.
Tomcat 5.x에서는 server.xml 에 GET 방식의 요청에 대한 인코딩을 지정하기 때문이다.
여기서 URIEncoding="euc-kr" 을 사용하지 않고, useBodyEncodingForURI="true"을 사용하면 Tomcat 4.x 처럼 request.setCharacterEncoding()의 값을 따라가게 할 수 있다.
Tomcat과 한글에 대해서는 Tomcat/JSP와 한글문서를 참조한다.

또하나 Ajax임을 나타내는 플래그를 HTTP 요청 헤더에 설정하도록 했는데, 그러지 않고 요청 파라미터(request.getParameter()로 값을 얻어올 수 있는 것)으로 설정하면 안된다.
request.getParameter()가 실행되어 Ajax 플래그의 값을 감지하는 그 순간, 그 이후 호출되는 request.setCharacterEncoding()는 완전히 무시되어 버리기 때문이다.


예제

급조한 예제이다.
* AjaxCaller.jsp - Ajax 호출부(클라이언트) : 수식을 만들어서 서버측에 계산을 요청한다.






이름 : 


    +
    -
    *
    /




* AjaxProcessor.jsp - Ajax 처리부(서버) : 수식을 계산한 결과를 JSON 형태로 리턴한다



이름 입력 부분에 한글을 입력하여 문제없이 처리되는지 확인해보기 바란다.


JSON

Ajax(JavaScript)는 데이터를 리턴 받는 방법으로 XML/Text/JSON을 지원한다. JSON은 텍스트 형태로 객체를 정의하는 방식이다. 이것은 XML과 1:1 매칭을 할 수도 있다. XML보다 훨씬 만들기 쉽고 사용법도 자바 객체를 사용하는 것과 유사하다. 그래서 이걸 사용해서 프로그램을 작성했다.

{
  "test1": "hello",
  "test2": "hello2"
}


위와 같은 메시지를 서버에서 응답으로 내보냈다고 할 때

// JSON 형태의 텍스트를 JavaScript 객체화 한다.
eval("res = " + request.responseText);

// 객체를 사용한다.
alert(res.test2); // 이 명령은 "hello2"를 출력한다.


배열은 다음과 같이 생성한다.

[
  ["test1", "test2"],
  ["test3", "test4"]
]


아래와 같이 사용한다.

eval("res = " + request.responseText);

// test4를 출력한다.
alert(res[1][1])


 * JSON 홈페이지 : http://www.json.org/
 * Java 객체를 이용해서 JSON 객체를 위한 텍스트 생성하기 : http://www.json.org/java/simple.txt 매우 단순한 방법으로 핵심 기능만 가지고 있다. 이것을 사용하길 권장한다. 라이브러리 다운로드는 http://www.JSON.org/java/json_simple.zip 에서 한다.
 * XML과 JSON간의 변환 

(출처 : http://ingenuity.egloos.com)

Posted by 1010
06.Ajax2010. 4. 20. 16:11
반응형

Ajax에서 서버와의 통신을 위한 핵심 요소인 XMLHttp는

IE7과 모질라 계열 브라우저에서는 native XMLHttpRequest를 사용.
그리고 IE6 이하 버전에서는 Microsoft.XMLHttp를 ActiveXObject로 object 생성.

[ IE에서 생성할 수 있는 XMLHttp object ]
  - Microsoft.XMLHttp
  - MSXML2.XMLHttp
  - MSXML2.XMLHttp.3.0
  - MSXML2.XMLHttp.4.0
  - MSXML2.XMLHttp.5.0


[ Cross-Browser 를 위한 XMLHttp object 메소드 생성 예 ]

function CreateXMLHttp()
{
  if (window.XMLHttpRequest)
  {
    return new XMLHttpRequest();
  }
  else if (window.ActiveXObject)
  {
    var aVersions = [ "MSXML2.XMLHttp.5.0"
      ,"MSXML2.XMLHttp.4.0"
      ,"MSXML2.XMLHttp.3.0"
      ,"MSXML2.XMLHttp"
      ,"Microsoft.XMLHttp"
      ];

    for (var i = 0; i < aVersions.length; i++)
    {
      try
      {
        var oXmlHttp = new ActiveXObject(aVersions[i]);
        return oXmlHttp;
      }
      catch (oError)
      {    
      }
    }
  }
}


[XMLHttp의 메소드 , 프로퍼티 및 이벤트]
1. 메소드
- abort( ) : 요청을 취소
- getAllResponseHeaders( ) : 모든 응답 헤더를 수신
- getResponseHeader(header) : 특정 응답 헤더 수신
- open(RequestType, url, async) : 통신 연결(nativ XMLHttpRequest는 Cross-domain을 제한함.)
   - RequestType : Get or Post

   - url : 서버 주소
   - async : true(비동기 방식 통신), false(동기 방식)
  
- send(content) : 서버로 요청을 보냄. content는 null 을 포함함.
- setHeader(header, value) : 헤더의 키와 값의 쌍을 설정

2. 프로퍼티 / 이벤트 핸들러
- onreadystatechange : readyState가 변경 시 실행될 함수 등록
- readyState : 요청 및 처리 상태
   - 0 (Uninitialized) : 아직 open() 메소드를 호출 하지 않은 상태
   - 1 (Loading) : open() 메소드를 호출한 상태(아직 send는 하지 않은 시점)
   - 2 (Loaded) : 요청을 서보로 보낸 상태( send() )
   - 3 (Interactive) : 일부만 응답 받은 상태
   - 4 (Complete): 모든 데이터를 받고 연결이 끊어진 상태

- responseText : 서버로 부터 받은 결과값의 스트링 반환
- responseXML : 서버로 부터 받은 결과값의 XML 형식
- status  : 서버로 부터 응답 받은 상태 코드 (200 (OK) or 404 (Not Found) 등)
- statusText : status 코드에 대한 의미 명기


[ 서버 전송 예 ]
function sendRequest()
{
    var content = getRequestBody();

    var oXmlHttp = createXMLHttp();
    oXmlHttp.open("post", "http://www.text.com/testForm.aspx", true);
    oXmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");

    //서버로 호출이 성공 하였을 경우 처리할 CallBack 함수 등록
    oXmlHttp.onreadystatechange = function ()
    {
        if (oXmlHttp.readyState == 4)
        {
            if (oXmlHttp.status == 200)
            {
                saveResult(oXmlHttp.responseText);
            }
            else
            {
                saveResult("An error occurred: "+ oXmlHttp.statusText);
            }
        }
    };
    
    oXmlHttp.send(content);
}


----------------------- 에이작스 한글깨짐 -----------------------------

JavaScript --> PHP

encodeURIComponent( string ) --> iconv( "UTF-8", "CP949", rawurldecode($string ) )


PHP --> JavaScript

rawurlencode( iconv( "CP949", "UTF-8", $string ) ) --> decodeURIComponent( string )


JSP/Servlet 에서 Ajax와 한글 인코딩 문제


Ajax는 기본적으로 UTF-8 만으로 통신을 한다고 보면된다. 그 이외의 Encoding을 지원하는 인코딩 함수가 없기 때문에 EUC-KR로 데이터를 전송하려는 꿈은 접어야만 한다.
헌데, 아직 우리나라는 EUC-KR 인코딩으로 된 웹 어플리케이션이 압도적으로 많은 상황이다(어서 빨리 UTF-8로 옮겨가길 바라마지 않는다).
거기다가 보통 JSP/Servlet 웹 어플리케이션은 Servlet 스펙 2.3이후부터 문자 인코딩 서블릿 필터를 사용해 모든 요청에 대해 일관된 문자 인코딩을 사용하는 것이 보편적인 방법으로 자리잡았다.

서블릿 필터는 일관성있게 모든 요청을 EUC-KR로 받아들이게 했는데, 몇몇 Ajax관련 요청만 UTF-8로 받아들여야만 하는 것이다.
필터를 적용할 URL-Pattern을 따로 줘보려 했으나, 너무 복잡해졌다.
그래서 HTTP 요청의 헤더를 이용해서 해결 했다.

아.. 한가지 더. 현재 한글 문제는 "XMLHttpRequest 요청 -> JSP/Servlet" 이 상황에서만 발생하는 것이다.
"JSP/Servlet -> XMLHttpRequest"의 상황(서버에서 클라이언트로 값을 리턴)에서는 이 문제가 발생하지 않는다.
서버가 리턴하는 문자열은 간단하게 다음처럼 하면 WAS가 자동으로 UTF-8로 값을 변경해서 전달하기 때문이다.

<%@ page contentType="text/plain; charset=utf-8" pageEncoding="EUC-KR"%>


contentType에서 text/plain은 텍스트나 JSON으로 값을 리턴할 때이다. XML로 리턴할 때는 text/xml.

아래는 Ajax 요청을 처리하기 위해서 만들어본 간단한 Encoding Filter 이다.

package ajax.filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * 어플리케이션 전체에 적용되는 필터이다.
 *
 * <ul>
 * <li>encoding 파라미터 : encoding 파라미터를 설정하면 request 객체에
 * setCharacterEncoding(encoding)을 실행한다.</li>
 * <li>ajaxFlag 파라미터 : Ajax요청임을 나타내는 HTTP 파라미터 이름이다. ajaxFilter로 지정한 HTTP 파라미터의
 * 값이 true 로 설정되면 인코딩을 무조건 UTF-8로 설정한다.</li>
 * </ul>
 *
 * @author 손권남(kwon37xi@yahoo.co.kr)
 *
 */
public class EncodingFilter implements Filter {

    private Log log = LogFactory.getLog(this.getClass());

    /** HTTP 요청 문자 인코딩 */
    private String encoding = null;

    /** Ajax 요청임을 나타내는 플래그 파라미터 이름 */
    private String ajaxFlag = null;

    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {

        if (ajaxFlag != null
                && "true".equals(((HttpServletRequest) request)
                        .getHeader(ajaxFlag))) {
            // Ajax 처리 요청일 경우 무조건 UTF-8 지정.
            request.setCharacterEncoding("UTF-8");
            if (log.isDebugEnabled()) {
                log.debug("요청 헤더에 " + ajaxFlag + "가 "
                        + ((HttpServletRequest) request).getHeader(ajaxFlag)
                        + "로 설정되어 있어 문자 인코딩에  UTF-8을 사용합니다.");
            }
        } else if (encoding != null) {
            // Ajax 플래그가 true가 아니면, 기본적인 인코딩을 적용한다.
            request.setCharacterEncoding(encoding);
            if (log.isDebugEnabled()) {
                log.debug("문자 인코딩에 " + encoding + "을 사용합니다.");
            }
        }

        chain.doFilter(request, response);
    }

    public void init(FilterConfig config) throws ServletException {
        encoding = config.getInitParameter("encoding");

        ajaxFlag = config.getInitParameter("ajaxFlag");

        if (log.isDebugEnabled()) {
            log.info("encoding : " + encoding + ", ajaxFlag : " + ajaxFlag);
        }
    }

    public void destroy() {
    }
}

이 필터를 적용하고서, web.xml에 다음 내용을 추가하면 필터가 작동한다.
<filter>
    <description>이중 인코딩 필터</description>
    <filter-name>EncodingFilter</filter-name>
    <filter-class>ajax.filter.EncodingFilter</filter-class>
    <init-param>
        <param-name>encoding</param-name>
        <param-value>euc-kr</param-value>
    </init-param>
    <init-param>
        <param-name>ajaxFlag</param-name>
        <param-value>Ajax</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>EncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

여 기 내용을 보면, 기본적인 인코딩은 EUC-KR이고, 요청 헤더에 "Ajax" 헤더의 값이 "true"일 경우에는 강제로 UTF-8을 지정하라고 한 것이다. "ajaxFlag"의 값을 변경하면 헤더의 키을 "Ajax"가 아닌 다른 값으로도 지정할 수 있다. 하지만 아무튼 해당 헤더의 값을 "true"로 지정하면 Ajax로 인식하게 되는 것이다.

이를 위해서는 XMLHttpRequest에도 한가지 처리를 더 보태야 한다.
Posted by 1010
06.Ajax2010. 2. 19. 16:17
반응형

개발자가 주목할 IE8 세미나 중 "Ajax 개발자가 IE8에 대해 알아야 할 모든 것" 부분에 대한 참고자료 입니다. 질문은 댓글 혹은 메일(jania902 at gmail dot com)로 해주시기 바랍니다.

2009년 3월 11일 기준 자료이므로 이후에 내용이 바뀔 수 있습니다.

감사합니다.

IE8_for_Ajax_Developers_final.pptx
Segoe fonts.zip

세미나 동영상


개요

  • 주제: Ajax 개발자가 IE8에 대해 알아야 할 모든 것
  • 소개: IE8의 새로운 기능, 타 브라우저와의 호환성, 개발자용 도구, 성능 개선 등 IE8과 관련하여 Ajax 개발자가 알아야 할 주요 이슈들을 소개합니다.
  • 장소: 코엑스 컨퍼런스 센터 401호
  • 일시: 2009/03/11 13:30~18:00 중 16:00~16:50

주제

1. Ajax

XMLHttpRequest:

Cross Domain Request (XDR):

Cross Document Messaging (XDM):

HTML/JSON Sanitizing:

    • Built-in JSON object. 빠르고 안전한 JSON 처리.
    • Special functions, toJSON(), are added to the prototypes of Date, Number, String, boolean objects
    • Doug Crockford의 json2.js에 기반. 이를 사용하고 있던 웹 사이트에서는 호환성 문제가 생기지 않을 것.

    • Firefox 3.1 도 Native JSON 지원.
    • 참고로, Webkit nightly에서도 지원 중.

Connectivity:

    • HTTP/1.1 on Broadband인 경우 호스트당 최대 6개의 동시 연결(기존 2개). 이는 HTTP/1.1 스팩에 따른 것(A single-user client SHOULD NOT maintain more than 2 connections with any server or proxy)이었으나 Broadband, Ajax 등으로 인해 상황이 바뀌었음.
    • window.maxConnectionsPerServer로 알아낼 수 있음

    • onLine property of window.navigator and window.clientInformation. "Work offline" 뿐 아니라 실제 연결이 끊어진 경우도 true

    • bodyonline, offline 이벤트 핸들러 지원(HTML5)

DOM Storage:

    • "What is DOM Storage?" - cookie와 DOM storage 비교.
    • localStoragesessionStorage와 달리 여러 윈도/여러 세션 간 공유됨.

  • 는 현재 sessionStorage만 지원. 비표준인 globalStoragelocalStorage와 유사하게 활용될 수 있음.

  • Webkit 최신 버전(Safari 4 public beta 등)은 sessionStoragelocalStorage 모두 지원.

Ajax Navigation:

    • Prev/Back 버튼 문제 지원을 위한 onhashchange 이벤트 추가. document.location.hash가 바뀌면 호출됨.

    • iframe, hash+setInterval 등을 이용한 기존의 꼼수를 대체.

2. 프로그래밍 일반

JScript:

    • 기존 JScript와 ECMAScript 스팩의 차이를 밝히고 이를 제거하는 것이 첫 단계라는 글. See

    • 엄청난 악플들. 요약하자면 "8년 동안 뭐하다가 이제서야 고치는가", "JScript 문제를 왜 Javascript 문제라고 말하는가".
    • ECMAScript 4(Mozilla, Apple, Opera, Google)와 ECMAScript 3.1(Microsoft, Yahoo) 그룹 간의 합의. ECMAScript Harmony 프로젝트 시작됨.
    • 를 실제 표준으로. 예를 들면 JS Getter/Setter는 Mozilla, Apple, Opera에서 이미 구현한 기능.

    • Harmony에 대한 MSDN JScript 블로그의 글. 특별한 내용은 없음.
    • IE Beta 2의 개선사항 요약.
    • 업계 최초의 Native JSON 지원. (2009년 3월 현재 Firefox 3.1 및 Webkit nightly에서 지원. 결국 누가 최초냐는 누가 먼저 정식 릴리즈를 하느냐의 문제)
    • Developer Tool 지원 향상. 이를테면 console.log 지원, profiler 추가 등
    • 에 의하면 Beta 2에서 DOM prototype 지원 시작.

    • IE Team과의 web chat 요약. JScript 향상에 집중하고 있다고. "We're certainly focusing heavily on improving Javascript, in IE8 and beyond. I'd expect to see great things here in the future."

Performance:

    • IE8 Beta 1에서는 애플리케이션의 메모리 소비량에 따라 GC 실행 주기가 적응적으로 변하도록 개선
    • JScript에 의해 참조되는 DOM 객체를 일반 JS 객체와 동일하게 취급. 따라서 Circular Reference로 인한 Memory Leak 문제가 발생하지 않음. IE7의 경우 페이지를 이동할 때에만 메모리가 release 되었음.
    • Array 연산, String concatenation 등의 성능 향상
    • Function calls, object creation, accessing object prototype properties and specific lookup patterns for JScript variables scoped to the window or this objects.
    • Unblocked downloads
    • Native JSON support
    • Selector API
  • Performance Profiler (see Developer Tools)

Selector API:

    • 대부분 브라우저의 최신 빌드에서는 99% 성공. IE8은 44%만 성공. Major problem areas are lack of whitespace trimming, incorrect exceptions being thrown, and lack of full CSS 3 selector support.
    • 전체 문서에서 찾은 후 범위에 의해 필터링하는 방식의 문제. Alex Russell (dojo), Andrew Dupont (prototype), John Resig (jquery) 등은 Spec 버그로 간주.
  • :visited는 보안상(privacy) 무시

  • 결론: 기존 브라우저들 때문에 어차피 앞으로 최소 1~2년 간은 Selector API를 직접 쓸 일 없을 것. 적당한 라이브러리를 쓸 것을 권장함. 라이브러리 성능이 크게 향상될 것이라는 점에 의의가 있음.

DOM:

3. 개발 도구

Developer Tool:

4. 참고자료

Overview articles:

Sites:

이번 세션에서 다루지 않는 주제들

Accessibility and ARIA:

  • ...

Rendering Mode and Standard Compliance:

Security:

Posted by 1010
06.Ajax2009. 11. 24. 07:33
반응형


http://www.methodchain.com/index.html

MethodChain?


MethodChain은 Ajax 라이브러리로 New Paradigm입니다.


MethodChain은 프로그램을 작성하지 않고 웹 애플리케이션을 개발할 수 있는

아키텍처와 메커니즘을 제공합니다.


2009년 11월 17일: MethodChain UI RC1 버전을 발표했습니다.


  • MethodChain UI 정식 버전은 2009년 12월 1일에 발표할 예정입니다.
  • 정식 버전에는 다음 내용이 포함됩니다.
  • - RC1에 포함되지 않은 예제
  • - 주석이 포함된 클래스 단위의 소스 코드
  • - MethodChain의 발전 방향, 사상, 아키텍처와 메커니즘 설명
  • - 2.1 버전 로드맵
  • - 라이센스 정책 및 가격


  • ** 아래 예제는 별도로 프로그램을 개발하지 않고 MethodChain 기능만으로 개발한 것입니다.
  • - 서버에서 받은 데이터는 상품명, 수량, 단가, 할인율 코드입니다.
  • - 할인율 코드에 해당하는 radio를 checked 상태로 설정하였으며
  • - Calculator 메커니즘을 적용하여 산출금액에서 부가세포함까지를 클라이언트에서 산출한 것입니다.


  • ** 아래 예제는 Grid Entry로 다수의 데이터를 입력할 수 있습니다.
  • - Operator 메커니즘을 적용하여 산출금액과 할인금액을 체크하고 메시지를 표시하였습니다.
  • - 수량과 단가를 입력할 때마다 산출금액, 판매금액, 부가세, 부가세포함을 자동으로 계산합니다.
  • - 이 모든 것을 위해 별도로 프로그램을 개발하지 않아도 됩니다.
Posted by 1010
06.Ajax2009. 8. 26. 10:39
반응형
출처 : http://hmkang.com/v2.0/hmblog/web/1961

Ajax 한글 파라미터 보내기

XMLHttpRequest 는 전송시

[meta http-equiv="content-type" content="text/html; charset=euc-kr" /]

위에 처럼 euc-kr 이 지정되어 있더라도 설정된 인코딩을 사용하지 않는다
따라서 한글일경우 자바스크립트에서 직접 인코딩해주어야 한다 (불편하다! -0-)
자바스크립트에서 escape함수와 encodeURIComponent 함수를 지원해 주는데 escape은 유니코드로, encodeURIComponent는 utf-8로 인코딩 된다

고로 보내기전 인코딩하고 받는 쪽에서도 인코딩 하면 한글문제는 일어나지 않는다

보내는쪽
utf-8 'list.jsp?search='+encodeURIComponent('홍길동')

받는쪽
request.setCharacterEncoding("utf-8");
request.getParameter("search");

Ajax에서 전송시 GET, POST 방식 모두 동일하게 처리해 주면 된다

출처 : Tong - janus94님의 IT통
Posted by 1010
06.Ajax2009. 2. 18. 12:02
반응형
"AJAX Programming” 온라인 강좌(10주 과정)
  썬마이크로시스템즈 자바 에반젤리스트 신 상 철 진행

썬마이크로시스템즈에서 자바 에반젤리스트로 활동 중이시며, 한국에도 방한하여 JCO Conference 등에서 열정적인 강의를 선보이셨던 신상철씨가 오는 8월 4일부터 10주간 AJAX 무료 온라인 강좌를 진행합니다.
국내 개발자 여러분들의 많은 참여 바랍니다.
(본 강좌는 전세계 개발자 대상이므로 영어로 진행됩니다.)


2006년 8월 4일에 “AJAX Programming” 무료 온라인 코스(10주 과정)가 시작됩니다. AJAX를 처음 배우시는 분이나, 실력을 더 쌓고 싶으신 분 모두 수강하실 수 있습니다. 10주의 코스 동안 AJAX의 기본 컨셉부터 Dojo 툴킷, jMAki, Google Web Toolkit, AJAX-fied JavaServer Faces (JSF) components와 같은 다양한 AJAX 프레임웍과 툴킷의 사용법까지 모두 배우게 됩니다.

이 코스는 온라인상에서 진행된다는 것과 무료라는 것을 제외하면 실제 대학 수업처럼 진행됩니다. 프레젠테이션 자료를 공부한 뒤에는 매주 과제가 나가며, 모르는 것을 서로 질문/답변할 수 있도록 수강생 메일링 리스트가 제공됩니다. 수업에 필요한 모든 강의자료(슬라이드, 강의노트, 플래쉬 데모 파일, 실습 자료, 과제물 등 포함)는 웹사이트에서 제공됩니다. 아래 주소로 내용이 없는 이메일을 하나 보내시면 바로 자동으로 등록하실 수 있습니다.
ajaxworkshop-subscribe@yahoogroups.com
본 강의의 신청 기한은 없으며, 강좌가 끝나기 전까지 등록하시면 됩니다. 단, 과제를 모두 제출하셔야 수강한 것으로 인정됩니다.
FAQ는 아래 링크에서 확인하시기 바라며, 그 외 문의는 SKDN@Sun.COM(한글 문의 가능)으로 보내주시기 바랍니다.

Posted by 1010
06.Ajax2008. 11. 24. 16:46
반응형
프로그래밍 :: 자바 개발자들을 위한 Ajax: 구글 웹 툴킷(Google Web Toolkit) 연구

출처 : http://www-128.ibm.com/developerworks/kr/library/j-ajax4/index.html

자바 개발자들을 위한 Ajax:
구글 웹 툴킷(Google Web Toolkit) 연구 (한글)

단일 자바 코드 베이스에서 Ajax 애플리케이션 개발하기

 

난이도 : 고급

Philip McCarthy, 소프트웨어 개발 컨설턴트, Independent

2006 년 8 월 11 일

최근에 출시된 구글 웹 툴킷은 거의 자바 코드로 표현된 동적 웹 애플리케이션을 생성하는 에이피아이 및 툴 세트입니다. 구글 웹 툴킷의 기능을 설명하고 여러분에게 맞는 것을 선택할 수 있도록 팁을 제시합니다.

   GWT(참고자료)는 웹 애플리케이션 개발에 있어 독특한 방식을 사용한다. 클라이언트 측 및 서버측 코드 베이스의 활용보다는 컴포넌트 기반 GUI를 생성하고 사용자 웹 브라우저에 표시하기 위한 용도로 GUI를 컴파일 하도록 하는 자바 API를 제공한다. GWT를 사용하는 과정은 일반적으로 자바 애플리케이션 개발과 관련된 경험보다는 Swing 또는 SWT로 개발하는 과정과 훨씬 더 유사하다. GWT의 사용을 통해 HTTP 프로토콜 및 HTML DOM 모델을 추상화하려는 시도를 하고 있다. 사실, GWT 애플리케이션이 웹 브라우저에서 표현된다는 사실은 거의 우연같이 느껴진다.

 

   GWT는 코드 생성을 통해 이와 같은 기능을 이룩하고 GWT 컴파일러는 서버측 자바 코드에서 JavaScript를 생성한다. GWT는 GWT 자체에서 제공하는 API와 함께 java.langjava.util의 단편들로 이루어져 있다. 하지만 이 단편들은 해독하기 어려워, 컴파일 된 GWT 애플리케이션은 블랙박스(GWT의 자바 바이트코드에 해당)로 여겨진다.

 

   이 글에서 필자는 원격 웹 API로부터 날씨 정보를 가져와 이를 브라우저에 표시하는 단순한 GWT 애플리케이션의 생성에 대해 설명한다. GWT의 기능들을 가능하면 간단히 설명하고 GWT 기능에서 발생하는 몇 가지 잠재적인 문제들을 언급하려 한다.

 

   시작은 간단히!

 

   Listing 1은 GWT를 사용해 만들 수 있는 가장 단순한 애플리케이션의 자바 소스 코드를 나타낸다.


Listing 1. 가장 단순한 GWT에 관한 예
public class Simple implements EntryPoint {
   public void onModuleLoad() {
      final Button button = new Button("Say 'Hello'");
      button.addClickListener(new ClickListener() {
         public void onClick(Widget sender) {
            Window.alert("Hello World!");
         }
      });
      RootPanel.get().add(button);
   }
}

   이는 Swing, AWT 또는 SWT에서 작성했을지도 모를 GUI 코드와 많이 유사하다. 추측했겠지만, Listing 1을 통해 클릭하면 "Hello World!" 라는 메시지를 디스플레이 하는 버튼을 생성하게 된다. 이 버튼은 HTML 페이지 본체 주위에 있는 GWT 래퍼인 RootPanel에 추가된다. 그림 1은 GWT 쉘 내에서 실행 중인 애플리케이션에 대해 나와 있다. 이 쉘은 디버깅 호스팅 환경으로 단순한 웹 브라우저를 포함하며 GWT SDK에 포함된다.


그림 1. 실행 중인 가장 단순한 GWT에 관한 예




/* Weather Reporter 애플리케이션 구축하기 */

 

   필자는 GWT를 사용해 단순한 Weather Reporter 애플리케이션을 생성하려 한다. 애플리케이션의 GUI는 사용자에게 ZIP 코드 및 온도를 나타내는 ℃및 ℉ 중 하나를 선택하여 입력하는 입력 상자를 제공한다. 사용자가 전송 버튼을 클릭하면, GWT 애플리케이션은 Yahoo! 무료 Weather API를 이용해 선택된 위치의 RSS-포맷 리포트를 얻게 된다. 이 문서의 HTML 부분이 선택되어 화면에 나타나 사용자들이 보게 된다.

 

   GWT 애플리케이션은 모듈로 패키지화되어 있고, 특정 구조에 맞아야 한다. 이른바 module-name.gwt.xml -- 라는 이름의 설정 파일은 애플리케이션의 엔트리 포인트로 작용하는 클래스를 정의하고 기타 GWT 모듈로부터 리소스 승계 여부를 나타낸다. 반드시 이 설정 파일을 모든 클라이언트 측 자바코드가 있는 client라는 이름의 패키지와 이미지, CSS 및 HTML과 같은 프로젝트 웹 자원을 포함하는 public이라는 이름의 디렉토리와 같은 레벨에 있는 GWT 애플리케이션의 소스 패키지 구조에 위치시켜야 한다. 마지막으로 public 디렉토리는 meta태그가 모듈의 정식 이름을 포함한 상태에서 HTML 파일을 반드시 포함해야 한다.

 

   GWT의applicationCreator는 엔트리-포인트 클래스의 이름이 주어진 상태에서, 이와 같은 기본 구조를 생성한다. 따라서
applicationCreator developerworks.gwt.weather.client.Weather를 불러오면 필자가 Weather Reporter 애플리케이션에 시작점으로 활용하는 프로젝트 개요를 생성한다. 이 애플리케이션에 대한 소스 다운로드 파일은 이 구조에 맞는 GWT 프로젝트와 같이 작용하는 유용한 타깃을 포함하는 Ant 구축파일(buildfile)을 포함한다. [
Download]


 

   기본 GUI 정의하기

 

   먼저 임의의 기능 추가 없이, GWT 애플리케이션의 사용자-인터페이스 위젯에 관한 기본 레이아웃을 개발한다. GWT UI에서 표현할 수 있는 기능 중 거의 모든 기능을 나타내는 최고급 클래스는 widget(위젯)클래스다. Widgets(위젯)은 항상 panels(패널)에 포함되어 있고 panels 자체는 Widget이라 내포되어 있다. 여러 가지 다른 타입의 패널은 각기 다른 레이아웃 기능을 제공한다. 따라서 GWT panel(패널)은 AWT/Swing 에서의 레이아웃(Layout)또는 XUL에서의 박스(BOX)의 패널과 비슷한 기능을 한다.

 

   모든 위젯 및 패널은 위젯 및 패널을 호스팅 하는 웹 페이지에 부가되어야 한다. Listing 1에서 보다시피, 위젯 및 패널을 직접 RootPanel. Alternatively, you can use RootPanel에 부가할 수 있다. 교대로 Rootpanel을 사용해, ID 또는 클래스 네임으로 식별되는 HTML 컴포넌트에 대한 레퍼런스를 얻는다. 이 경우 필자는 input-containeroutput-container라는 명칭의 각각의 HTML DIV 컴포넌트를 사용한다. 첫 번째 파일은 Weather Reporter에 관한 UI 제어 기능을 포함하며, 두 번째 파일은 Weather Report 자체를 보여준다.

 

   Listing 2는 기본 레이아웃 설정 시 필요한 코드를 나타내는데 이 코드는 자가 설명적이어야 한다. HTML 위젯은 단순히 HTML 작성을 위한 상자에 불과하고 Yahoo! 날씨 정보에서 나온 HTML 출력 정보를 나타내는 곳이다. 이와 같은 모든 코드는 EntryPoint 인터페이스에서 제공되는 Weather 클래스의 onModuleLoad() 메소드 내부로 들어간다. weather 모듈을 둘러싸고 있는 웹 페이지를 클라이언트 웹 브라우저로 로드 할 때 이 메소드를 호출한다.


Listing 2. Weather Reporter에 대한 메소드 코드
 public void onModuleLoad() {
   HorizontalPanel inputPanel = new HorizontalPanel();


// Align child widgets along middle of panel inputPanel.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE); Label lbl = new Label("5-digit zipcode: "); inputPanel.add(lbl); TextBox txBox = new TextBox(); txBox.setVisibleLength(20); inputPanel.add(txBox); // Create radio button group to select units in C or F Panel radioPanel = new VerticalPanel(); RadioButton ucRadio = new RadioButton("units", "Celsius"); RadioButton ufRadio = new RadioButton("units", "Fahrenheit"); // Default to Celsius ucRadio.setChecked(true); radioPanel.add(ucRadio); radioPanel.add(ufRadio); // Add radio buttons panel to inputs inputPanel.add(radioPanel); // Create Submit button Button btn = new Button("Submit"); // Add button to inputs, aligned to bottom inputPanel.add(btn); inputPanel.setCellVerticalAlignment(btn, HasVerticalAlignment.ALIGN_BOTTOM); RootPanel.get("input-container").add(inputPanel); // Create widget for HTML output HTML weatherHtml = new HTML(); RootPanel.get("output-container").add(weatherHtml); }

   그림 2는 GWT 쉘에서 표현된 레이아웃을 나타내고 있다.


그림 2. 기본 GUI 레이아웃


   CSS로 스타일링 기능 추가하기

 

   표현된 웹 페이지는 보기에는 상당히 볼품없지만, CSS 스타일링 규칙으로 웹 페이지는 상당히 세련된 기능을 갖춘다. GWT 애플리케이션을 스타일링 하는 두 가지 방식을 사용한다. 먼저, 각 위젯은 디폴트로, project-widget 형식의 CSS 클래스 네임을 갖는다. 예를 들어, gwt-Buttongwt-RadioButton은 중심적인 GWT 위젯의 클래스 네임들이다. 일반적으로 내포된 테이블이 뒤죽박죽 모인 타입으로 패널을 구현한다. 패널은 디폴트 클래스네임을 가지지 않는다.

 

   디폴트 위젯-형식 당 클래스 네임 방식으로 애플리케이션 전체에 균일하게 여러 위젯에 이름을 붙이기 용이해진다. 물론 정상적인 CSS 선택자 규칙이 적용되고, 이 규칙을 이용해, 여러 가지 다른 스타일을 애플리케이션 컨텍스트에 따라 동일한 위젯 타입에 적용할 수 있다. 더 높은 가변성을 위해, 위젯의 setStyleName()addStyleName() 메소드를 불러와 특정적으로, 위젯의 디폴트 클래스네임을 바꾸거나 확대한다.

 

   Listing 3은 이와 같은 방식들을 결합해 여러 스타일을 Weather Reporter 애플리케이션의 입력 패널에 적용시키는 방식을 보여주고 있다. weather-input-panel 클래스 네임은 inputPanel.setStyleName("weather-input-panel");에 대한 호출을 통해, Weather.java에서 형성된다.


Listing 3. CSS 스타일을 Weather Reporter 입력 패널에 적용하기
/* Style the input panel itself */
.weather-input-panel {
   background-color: #AACCFF;
   border: 2px solid #3366CC;
   font-weight: bold;
}


/* Apply padding to every element within the input panel */
.weather-input-panel * {
   padding: 3px;
}


/* Override the default button style */
.gwt-Button {
   background-color: #3366CC;
   color: white;
   font-weight: bold;
   border: 1px solid #AACCFF;
}

/* Apply a hover effect to the button */
.gwt-Button:hover {
   background-color: #FF0084;
}

   그림 3에서는 이와 같은 스타일이 적합한 상태에서 다시 Weather Reporter 애플리케이션에 대해 나와 있다.


그림 3. 스타일을 적용한 상태에서의 입력 패널



   클라이언트 측 기능 추가하기

 

   애플리케이션의 기본 레이아웃 및 스타일링 기능이 행해졌으므로, 필자는 몇 가지 클라이언트 측 기능을 시작한다. 친숙한 리스너 패턴을 사용해 GWT에서의 이벤트 핸들링을 수행한다. GWT는 부가된 편의 기능의 몇 가지 어댑터 및 헬퍼-클래스 뿐만 아니라 마우스 이벤트, 키보드 이벤트 및 변경 이벤트 등의 리스너(Listener) 인터페이스를 제공한다.

 

   일반적으로, Swing 프로그래머에게 친숙한 익명 내부-클래스 이디엄을 이용해 이벤트 리스너를 추가한다. 하지만 모든 GWT 리스너(Listener)의 첫 번째 매개변수는 이벤트 센더로 사용자가 대화하는 위젯이다. 이는 필요한 경우, 동일한 리스너(Listener) 인스턴스를 다중 위젯에 부가하고 센더 매개변수를 이용해 이벤트를 보내는 위젯이 어떤 것인지 결정한다는 것을 의미한다.

 

   Listing 4는 Weather Reporter 애플리케이션에서의 두 가지 이벤트 리스너에 대한 구현을 나타낸다. 클릭 핸들러는 전송(Submit) 버튼에, 키핸들러는 TextBox에 각각 부가된다. TextBox를 중점적으로 볼 경우, 전송(Submit) 버튼을 클릭하거나, 엔터 키를 누르면 관련 핸들러에서 사설 validateAndSubmit() 메소드를 불러온다. Listing 4에 있는 코드뿐만 아니라, txBoxucRadioWeather 클래스의 인스턴스 멤버가 되면서 확인 방법으로 처리된다.


Listing 4. 클라이언트 측 기능 추가하기
// Create Submit button, with click listener inner class attached
Button btn = new Button("Submit", new ClickListener() {
   public void onClick(Widget sender) {
      validateAndSubmit();
   }
});

// For usability, also submit data when the user hits Enter 
// when the textbox has focus
txBox.addKeyboardListener(new KeyboardListenerAdapter(){
   public void onKeyPress(Widget sender, char keyCode, int modifiers) {


// Check for Enter key if ((keyCode == 13) && (modifiers == 0)) { validateAndSubmit(); } } });

   Listing 5는 validateAndSubmit() 메소드 구현을 보여준다. 이 구현 과정은 상당히 단순하며, 확인 로직을 요약한 ZipCodeValidator 클래스에 따라 다르다. 사용자가 유효한 다섯 글자 ZIP 코드를 입력하지 않을 경우, validateAndSubmit() 메소드는 Window.alert()에 대한 호출로 GWT 세계에 표현된 경보 박스에 있는 에러 메시지를 나타낸다. ZIP 코드가 유효한 경우, ZIP 코드 및 ℃/℉가운데 사용자의 선택 단위 등이 fetchWeatherHtml() 메소드를 통과한다. 이에 대해선 나중에 다루기로 하겠다.


Listing 5. validateAndSubmit 로직
private void validateAndSubmit() {
   // Trim whitespace from input
   String zip = txBox.getText().trim();

   if (!zipValidator.isValid(zip)) {
     Window.alert("Zip-code must have 5 digits");
     return;
   }

   // Disable the TextBox
   txBox.setEnabled(false);

   // Get choice of celsius/fahrenheit
   boolean celsius = ucRadio.isChecked();
   fetchWeatherHtml(zip, celsius);
}




   GWT 쉘로 클라이언트 측 디버깅하기

 

   GWT 쉘이 자바 IDE에 있는 클라이언트 측 코드를 디버그 하도록 해주는 JVM 후크를 가진다는 사실을 언급하기 위해, 잠깐 주제에서 벗어난 얘기를 하겠다. 여러분은 웹 UI와 대화하고 클라이언트에서 실행되는 해당 JavaScript를 나타내는 자바 코드를 알 수 있다. 클라이언트 측에 생성되는 생성 JavaScript를 디버깅하는 것은 기본적으로 성공할 가망이 없기 때문에 이와 같은 기능은 상당히 중요한 기능이다.

 

   Eclipse 디버그 태스크를 구성해 com.google.gwt.dev.GWTShell 클래스를 통해 GWT 쉘을 실행하는 것은 쉽다. 그림 4는 전송(Submit) 버튼을 클릭하는 과정 후에 validateAndSubmit() 메소드에 있는 중지점에서 정지된 Eclipse를 보여준다.


그림 4. 클라이언트 측 GWT 코드를 디버깅하는 Eclipse




   서버측 컴포넌트와의 통신

 

   이제, Weather Reporter 애플리케이션에서 사용자 입력 정보를 수집해 정보를 확인했다. 서버에서 데이터를 꺼내오는 과정이 그 다음 단계다. 정상적인 Ajax 개발 과정에 있어, 이 단계는 JavaScript로부터 서버측 리소스를 불러오고 JavaScript 객체 표기법(JSON) 또는 XML로 코드화된 데이터를 다시 받는 과정을 수반한다. GWT는 자체의 원격 프로시저 호출 (RPC) 메커니즘 뒤에 있는 이와 같은 대화 과정을 추상화한다.

 

   GWT 용어 측면에서 보면 클라이언트 는 웹 서버 상에서 실행되는 서비스와 대화한다. 이런 서비스를 나타내는 데 사용되는 RPC 메커니즘은 자바 RMI에서 사용하는 방식과 비슷하다. 이는 서비스 및 몇 가지 인터페이스의 서버측 구현 프로세스를 작성하기만 하면 된다는 것을 의미한다. 코드 생성 및 리플렉션 프로세스는 클라이언트 스텁 및 서버측 골격 프록시를 처리한다.

 

   이에 따라 첫 번째 단계는 Weather Reporter 서비스에 대한 인터페이스를 정의하는 것이다. 이 인터페이스는 GWT RemoteService인터페이스를 확장시켜야 하고, GWT 클라이언트 코드에 나타나야 하는 서비스 메소드의 서명을 포함한다. GWT에서의 RPC 호출은 JavaScript 코드 및 자바 코드 사이에서 행해지기 때문에 GWT는 객체-직렬화 메커니즘을 도입해 언어 분할 (직렬화 가능 타입 사이드 바를 참조) 전체에 걸쳐 인수를 조정하고 값을 반환한다.

 

직렬 타입

GWT하에서 직렬 타입에 대해 간략히 요약하면 다음과 같다.:

  • 프리머티브 (int와 같은) 및 원시 래퍼 클래스(정수등)는 직렬화 가능하다.
  • 문자열(String)날짜(Date)는 직렬화 가능하다.
  • 직렬화 타입의 배열은 그 자체로 직렬화 가능하다.
  • 사용자 정의 클래스는 모든 클래스의 상주 멤버가 직렬화 가능하고 GWT의 IsSerializable 인터페이스를 구현할 경우에 직렬화 가능하다.
  • Collection 클래스는 자체에서 포함된 직렬화 타입을 서술하는 Javadoc 주석과 같이 사용된다.

어쨌든 클라이언트 코드는 GWT에서 수행되는 소규모의 자바 클래스 하위 세트에 제한되어 있기 때문에 이와 같은 직렬화 가능 타입은 상당히 포괄적인 적용 범위를 제공한다.

   서비스 인터페이스를 정의하면, 이 인터페이스를 GWT의 RemoteServiceServlet 클래스를 확장하는 클래스에 구현하는 과정이 그 다음 단계다. 이름에서도 암시하듯, RemoteServiceServlet 클래스는 자바 언어의 HttpServlet을 특수화시킨 것으로, 임의의 servlet 상자에서 호스팅 된다.

 

   여기서 언급될 만한 가치가 있는 GWT의 특성 중 하나는 서비스의 원격 인터페이스는 애플리케이션의 client패키지에 반드시 있어야 한다는 것이다. JavaScript 생성 과정에서 서비스 원격 인터페이스가 들어가야 하기 때문이다. 하지만 서버측 구현 클래스는 원격 인터페이스를 기준으로 하기 때문에, 자바 컴파일 타임 의존성은 서버측 코드 및 클라이언트 코드 사이에 존재한다. 이에 대한 필자의 솔루션은 원격 인터페이스를 client공통 하위 패키지 안으로 넣는 것이다. 그리고 난 뒤, 필자는 자바에서 공통 하위 패키지를 포함시키고, 나머지 client 패키지를 제외시킨다. 이렇게 하면, 클래스 파일이 JavaScript로만 변환되어야만 하는 클라이언트 코드에서 생성되는 것을 방지한다. 더 좋은 솔루션은 클라이언트 측 및 서버측 코드에 관한 두 가지 소스 디렉토리 전체에 걸친 패키지 구조를 분할한 뒤, 공통 클래스를 두 디렉토리로 복사하는 것이다.

 

   Listing 6에서는 Weather Reporter 애플리케이션: WeatherService에서 사용되는 원격 서비스 인터페이스가 나타나 있다. 이 인터페이스는 입력 정보로 ZIP 코드 및 ℃/℉ 플래그를 취하고 HTML weather 설명을 포함하는 문자열을 반환한다. Listing 6에서는 또한 YahooWeatherServiceImpl의 개요를 보여준다. 이 개요는 Yahoo! weather API를 이용해 주어진 ZIP 코드에 대한 RSS weather정보를 얻고 그 정보로부터 HTML 설명을 뽑아낸다.


Listing 6. 원격 WeatherService(weather서비스) 인터페이스 및 부분적 구현
public interface WeatherService extends RemoteService {
   /**
    * Return HTML description of weather
    * @param zip zipcode to fetch weather for
    * @param isCelsius true to fetch temperatures in celsius, 
    * false for fahrenheit
    * @return HTML description of weather for zipcode area
    */
   public String getWeatherHtml(String zip, boolean isCelsius) 
      throws WeatherException;
} 


public class YahooWeatherServiceImpl extends RemoteServiceServlet
   implements WeatherService {
   /**
    * Return HTML description of weather
    * @param zip zipcode to fetch weather for
    * @param isCelsius true to fetch temperatures in celsius, 
    * false for fahrenheit
    * @return HTML description of weather for zipcode area
    */
   public String getWeatherHtml(String zip, boolean isCelsius) 
      throws WeatherException {
     // Clever programming goes here
   }
}

   이 시점에서 표준 RMI 방식에서 벗어나기 시작한다. JavaScript로부터의 Ajax호출은 비동기식이므로, 서비스를 호출하기 위해 클라이언트 코드에서 사용하는 비동기식 인터페이스를 정의하는 부가적인 작업이 필요하다. 비동기식 인터페이스 메소드 서명은 원격 인터페이스 서명과는 다르기 때문에 GWT는 Magical Coincidental Naming에 의존한다. 즉, 비동기식 인터페이스 및 원격 인터페이스 사이에 정적인 컴파일-타임 관계가 존재하지 않는다. 하지만 GWT는 명명 협약을 통해 컴파일-타임 관계를 인지한다. Listing 7은 WeatherService에 대한 비동기식 인터페이스를 나타내고 있다.


Listing 7. WeatherService(weather서비스)에 대한 비동기식 인터페이스
public interface WeatherServiceAsync {
   /**
    * Fetch HTML description of weather, pass to callback
    * @param zip zipcode to fetch weather for
    * @param isCelsius true to fetch temperatures in celsius,
    * false for fahrenheit
    * @param callback Weather HTML will be passed to this callback handler
    */
   public void getWeatherHtml(String zip, boolean isCelsius, 
      AsyncCallback callback);
}
 

   알다시피, MyServiceAsync라 불리는 인터페이스를 생성하고, 각 메소드 서명에 대한 복사물을 제공한 뒤, 반환 (return) 타입을 제거하고, AsyncCallback타입에 관한 부가적 매개변수를 추가하는 것이 일반적인 개념이다. 비동기식 인터페이스는 원격 인터페이스와 같은 패키지에 존재해야 한다. AsyncCallback 클래스는 onSuccess()onFailure() 등의 두 가지 메소드가 있다. 서비스에 관한 호출이 성공일 경우, 서비스 호출에 대한 반환 값으로 onSuccess()를 호출한다. 원격 호출이 실패할 경우, onFailure()를 호출하고, 서비스에 의해 생성되는 Throwable 타입이 통과되면서 오류 근원이 나타나게 된다.




   클라이언트로부터 서비스 호출하기

 

   WeatherServiceWeatherServiceAsync의 비동기식 인터페이스가 적절한 상태에서 필자는 이제 Weather Reporter 클라이언트를 호출해 서비스를 호출하고 서비스에서 나온 응답을 다룬다. 이에 대한 첫 번째 단계는 단순히 반복 사용 설정 코드에 관한 것이다. 반복 사용 설정 코드는 GWT.create(WeatherService.class)를 불러내고 GWT.create(WeatherService.class)에서 반환하는 객체를 다운 캐스팅 해 weather 클라이언트가 사용하는 WeatherServiceAsync의 인스턴스를 생성한다. 그 다음 단계로, WeatherServiceAsyncServiceDefTarget에 캐스트 해 ServiceDefTarget상에 setServiceEntryPoint()를 불러올 수 있도록 해야 한다. setServiceEntryPoint()는 자체 해당 원격 서비스 구현 프로세스가 전개되는 URL에서의 WeatherServiceAsync 스텁을 가리킨다. 반복 사용 설정 코드는 효과적으로 컴파일 타임에서 하드 코드화된다. 이 코드는 웹 브라우저에서 전개되는 자바코드로 되기 때문에 런타임에서의 속성 파일에서부터 위 URL을 찾을 방법이 없어 확실히 컴파일 된 GWT 웹 애플리케이션의 이식성을 제한한다.

 

   Listing 8에서는 WeatherServiceAsync 객체의 설정에 대해 나와 있으며 필자가 이전에 언급했던 fetchWeatherHtm()의 구현에 대해서도 나와있다. (클라이언트 측 기능 추가하기 참조)


Listing 8. RPC를 사용해 원격 서비스 호출하기
// Statically configure RPC service
private static WeatherServiceAsync ws = (WeatherServiceAsync) GWT.create(WeatherService.class);
static {
   ((ServiceDefTarget) ws).setServiceEntryPoint("ws");
}

/**
 * Asynchronously call the weather service and display results
 */
private void fetchWeatherHtml(String zip, boolean isCelsius) {
   // Hide existing weather report
   hideHtml();

   // Call remote service and define callback behavior
   ws.getWeatherHtml(zip, isCelsius, new AsyncCallback() {
      public void onSuccess(Object result) {
         String html = (String) result;

         // Show new weather report
         displayHtml(html);
      }

      public void onFailure(Throwable caught) {
         Window.alert("Error: " + caught.getMessage());
         txBox.setEnabled(true);
       }
   });
}

   서비스의 getWeatherHtml()에 대한 실질적인 호출 과정은 구현하기 쉽다. 익명 콜백 핸들러 클래스는 단순히 서버에서 나온 응답을 서비스의 getWeatherHtml()를 나타내는 메소드에 전한다.

 

   그림 5는 Yahoo! weather API에서 가져온 날씨 정보를 나타내는 실행 중인 애플리케이션에 대해 나와있다.


그림 5. Yahoo!에서 가져온 리포트를 나타내는 Weather Reporter 애플리케이션




   서버측 확인에 관한 필요성

 

   GWT에서 클라이언트 측 코드 및 서버측 코드를 융합하는 것은 본질적으로 위험하다. GWT의 추상화 과정으로 클라이언트/서버 분할을 감춘 상태에서 자바 언어로 모든 프로그램을 작성하기 때문에, 클라이언트 측 코드를 런타임 시 신뢰할 수 있다고 착각하기 쉽다. 하지만 그런 생각은 잘못된 것이다. 웹 브라우저에서 실행하는 임의의 코드는 악의적인 사용자에 의해 변조되거나 완전히 우회될 가능성이 있다. GWT는 이런 문제를 줄일 수 있도록 악의적인 사용자들에게 고도로 혼란을 주는 기능을 제공한다. 하지만 GWT 클라이언트 및 클라이언트 서비스 사이를 이동하는 임의의 HTTP 트래픽 등의 2차 공격 시점은 여전히 존재한다.

 

   여기서 필자가 Weather Reporter 애플리케이션의 약점을 이용하는 공격자라고 가정해 보자. 그림 6은 Weather Reporter 클라이언트에서 서버 상에서 실행하는 WeatherService까지 전송되는 요청을 가로채는 Microsoft의 Fiddler 툴에 대해 나와있다. 일단 요청을 가로채면 Fiddler 툴은 요청의 일부를 변경하도록 한다. 그림 6에서 강조된 텍스트를 통해 필자는 필자가 지정한 ZIP 코드가 요청 내에서 코드화된 곳을 발견했다는 사실을 보여주고 있다. 이 요청을 필자가 좋아하는 코드로 변경할 수 있다. 예를 들면 "10001"에서 "XXXXX"로 변경하는 것 등이다.


그림 6. Fiddler를 이용해 클라이언트 측 확인 과정 우회하기

   이제, YahooWeatherServiceImpl에 있는 고유 서버측 코드에서 ZIP 코드상에 있는 Integer.parseInt()를 불러온다고 가정하자. 결국에, ZIP 코드는 Weather's validateAndSubmit()로 통합된 확인 점검 기능을 우회해 통과한 것이 틀림없다. 그런가? 보다시피, 확인 점검 기능은 와해되고, NumberFormatException은 폐지된다.

 

   이 경우 끔찍한 일이 발생되지 않고, 공격자는 클라이언트에서 에러 메시지를 받게 된다. 하지만 더 민감한 데이터를 다루는 GWT 애플리케이션에서 여전히 공격 당할 가능성은 존재한다. ZIP코드를 주문 추적 애플리케이션에서의 고객 ID번호라 가정해 보자. ZIP코드를 가로채 변경하면 다른 고객에 대한 민감한 재정 정보가 나오게 된다. 데이터베이스 쿼리에서 값을 사용하는 임의의 장소에서 이와 같은 동일한 방식을 사용하면 SQL 삽입 공격에 대한 가능성이 존재한다.

 

   예전에 Ajax 애플리케이션으로 작업한 사람들이 이런 공격을 간단하게 하도록 내버려둬선 안된다. 서버 측의 입력 값을 재확인해 임의의 입력 값을 이중 점검하는 작업을 해야 한다, GWT 애플리케이션에서 작성하는 자바 코드는 런타임에서 본질적으로 신뢰할 만한 것이 아니라는 사실을 기억하는 것이 중요하다. 하지만 GWT는 장점도 있다. Weather Reporter 애플리케이션에서, 필자는 이미 클라이언트상에서 사용하기 위한 ZipCodeValidator를 작성해 ZipcodeValidator를 단순히 필자의 client.common 패키지로 이동시켜 서버 측에서 동일한 확인 과정을 다시 재사용했다. Listing 9에서는 YahooWeatherServiceImpl로 통합된 점검 기능에 대해 나와있다.


Listing 9. YahooWeatherServiceImpl로 통합된 ZipcodeValidator
public String getWeatherHtml(String zip, boolean isCelsius) throws WeatherException {
   if (!new ZipCodeValidator().isValid(zip)) {
      log.warn("Invalid zipcode: "+zip);
      throw new WeatherException("Zip-code must have 5 digits");
   }




   JSNI로 고유 JavaScript 불러오기

 

   웹 애플리케이션에서 시각 효과 라이브러리가 점점 인기를 얻고 있다. 이 라이브러리 효과는 미묘한 사용자-상호작용 큐를 제공하거나 단순히 폴리시 기능을 추가하기 때문이다. 필자는 Weather Reporter 애플리케이션에 몇 가지 아이-캔디 기능을 추가하고 싶다. GWT는 이와 같은 타입의 기능을 제공하지 않지만 GWT의 JavaScript Native Interface(JSNI)는 이 기능에 대한 솔루션을 제공한다. JSNI로 GWT 클라이언트 자바 코드로부터 JavaScript를 호출하게 된다. 이는 예를 들어, 필자가 Scriptaculous 라이브러리 (참고자료)나 Yahoo! 사용자 인터페이스 라이브러리로부터 효과를 이용할 수 있다는 것을 의미한다.

 

   JSNI는 특수 주석 블록에 포함된 자바 언어의 native(고유)키워드와 JavaScript를 조합한 타입을 사용한다. 이는 아마도 예를 통해 설명할 수 있을 것이다. Listing 10에서는 Element 상에 주어진 Scriptaculous 효과를 호출하는 메소드에 대해 나와있다.


Listing 10. JSNI로 Scriptaculous 효과 호출하기
/**
 * Publishes HTML to the weather display pane
 */
private void displayHtml(String html) {
   weatherHtml.setHTML(html);
   applyEffect(weatherHtml.getElement(), "Appear");
}

/**
 * Applies a Scriptaculous effect to an element
 * @param element The element to reveal
 */
private native void applyEffect(Element element, String effectName) /*-{
   // Trigger named Scriptaculous effect
   $wnd.Effect[effectName](element);
}-*/;
 

   이것은 컴파일러가 private native void applyEffect(Element element, String effectName); 만을 보기 때문에 완벽히 유효한 자바 코드이다. GWT는 주석 블록의 내용을 파싱하고 JavaScript를 출력한다. GWT는 window와 document 객체를 칭하는 $wnd$doc 변수를 제공한다. 이 경우, 나는 상위 레벨에 있는 Effect 객체에 액세스 하고 JavaScript의 대괄호를 사용하여 콜러가 지정한 네임드 함수를 호출한다. Element 유형은 GWT에서 제공하는 마법과 같은 타입으로서 Widget의 기반 HTML DOM 엘리먼트를 자바와 JavaScript 코드로 나타낸다. String은 자바 코드와 JavaScript간 JSNI를 통해서 투명하게 전달될 수 있는 타입 중 하나이다.

 

   이제 필자는 서버로부터 데이터를 반환할 시, 뚜렷이 나오는 날씨 정보를 가지게 되었다. 마지막으로 효과 종료 시 ZIP 코드인 TextBox를 재설정한다. Scriptaculous 효과는 비동기식 콜백 메커니즘을 사용해 리스너에 효과의 생명 주기에 관한 내용을 통보한다. 필자는 필자의 GWT 클라이언트 자바 코드 안으로 다시 JavaScript를 호출해야 하기 때문에, 여기서 상황이 조금 복잡해진다. JavaScript에서는 임의의 개수가 있는 인수들로 임의의 함수를 호출한다. 따라서 자바-스타일 메소드 과 부하는 존재하지 않는다. 이는 JSNI가 자바 메소드를 참조할 다루기 힘든 구문을 사용해 발생 가능한 과부하를 명확하게 해야 한다는 것을 의미한다. GWT 문서에서는 이 구문을 다음과 같이 기술한다.

[instance-expr.]@class-name::method-name(param-signature)(arguments)

   instance-expr. 부분은 일종의 옵션이다. 객체 레퍼런스에 대한 필요 없이 정적 메소드를 호출해야 하기 때문이다. 또 다시, Listing 11에서 보면 예에서 설명된 효과 메소드를 알기가 가장 쉽다.


Listing 11. JSNI로 자바 코드 안으로 다시 호출하기
/**
 * Applies a Scriptaculous effect to an element
 * @param element The element to reveal
 */
private native void applyEffect(Element element, String effectName) /*-{

  // Keep reference to self for use inside closure
  var weather = this;

  // Trigger named Scriptaculous effect
  $wnd.Effect[effectName](element, { 
     afterFinish : function () {

     // Make call back to Weather object
     weather.@developerworks.gwt.weather.client.Weather::effectFinished()();
     } 
  });
}-*/;
/** * Callback triggered when a Scriptaculous effect finishes. * Re-enables the input textbox. */ private void effectFinished() { this.txBox.setEnabled(true); this.txBox.setFocus(true); }

   applyEffect() 메소드를 변경해 여분의 afterFinish 인수를 Scriptaculous 효과로 전송한다. afterFinish의 값은 효과를 실행할 때 호출되는 익명 함수다. 이 함수는 GWT의 이벤트 핸들러에 의해 사용되는 익명 내부-클래스 이디엄과 뭔가 비슷하다. 호출할 Weather 객체의 인스턴스서부터 시작해, Weather 클래스의 정식 이름, 호출할 함수의 명칭까지 지정해 실질적으로 자바 코드 안으로 다시 호출한다. 괄호의 첫 번째 공란은 인수가 없는 effectFinished()라는 명칭의 메소드를 필자가 불러들이고 싶다는 것을 의미한다. 두 번째 괄호 세트는 함수를 불러들인다.

 

   여기서 로컬 변수인 weather에서 this reference. Because of the way JavaScript call semantics operate, the this 레퍼런스 사본을 보유하고 있다는 사실이 이상하다. JavaScript 호출 의미가 작동되는 방식 때문에 afterFinish 함수 내의 this 변수는 실제로 Scriptaculous 객체다. Scriptaculous객체에서 그 함수를 불러들이기 때문이다. 클로저 외부의 this 레퍼런스 사본을 만드는 것은 단순한 대안이다.

 

   여기서 필자는 몇 가지 JSNI 기능에 대해 알아보았다. 필자는 Scriptaculous 효과 기능을 주문 GWT 위젯으로 요약하는 방식이 Scriptaculous 효과를 GWT로 통합하는 더 좋은 방식이라는 것을 지적하고 싶다. 이 방식이 Alexei Sokolov가 GWT 컴포넌트 라이브러리에서 행했던 바로 그 방식이다. (참고자료)

 

   이제 필자는 Weather Reporter 애플리케이션에 대해 다 얘기했으므로, GWT로 웹 개발 시 몇 가지 장점 및 단점에 대해 설명하겠다.




GWT를 사용하는 이유?

 

   예상한 바와는 달리, GWT 애플리케이션은 이상하게도 웹과 유사하지 않다. GWT는 기본적으로 경량 GUI 애플리케이션에 관한 런타임 환경으로 브라우저를 이용하기 때문에 정상적인 웹 애플리케이션 보다는 Morfik, OpenLaszlo 또는 심지어 Flash로 개발한 것과 훨씬 비슷한 결과가 나온다. 따라서, GWT는 단일 페이지 상에 풍부한 Ajax GUI로 존재하는 웹 애플리케이션에 가장 잘 맞는다. GWT 애플리케이션이 구글 캘린더 및 스트레드시트 애플리케이션과 같은 구글의 베타 릴리스의 일부를 특성화시키기 때문에, 우연의 일치는 아닌 듯 하다. GWT 애플리케이션은 대단하지만 이를 이용해 모든 비즈니스 상황을 해결할 수는 없다. 대부분의 웹 애플리케이션은 페이지 중심 모델에 완벽히 들어맞기 때문이다. Ajax는 필요한 경우, 더 풍부한 대화형 방식을 사용한다. GWT는 전통 페이지-중심 애플리케이션과 잘 들어맞지 않는다. GWT 위젯과 정상 HTML 타입의 입력 자료를 결합시키는 게 가능하지만 GWT 위젯 상태는 나머지 페이지와는 다르다. 예를 들어, GWT Tree 위젯으로부터 선택된 값을 정규 형식의 일부로 전송하는 간단한 방법이 없다.

 

라이센싱

GWT의 런타임 라이브러리는 Apache 라이센스 2.0에 따라 허가된다. GWT를 자유롭게 사용해 상업적 애플리케이션을 생성한다. 하지만, GWT 툴 체인은 오로지 이진 타입으로 제공되고 툴 체인 변경은 금지된다. 툴 체인은 자바-대-JavaScript 컴파일러를 포함한다. 이는 생성된 JavaScript에서 발생한 에러는 통제 불능임을 의미한다. GWT가 사용자-에이전트 탐지 기능에 의존한다는 것도 특수한 문제다. 새 브라우저의 각 릴리스에는 지원 기능을 제공하는 GWT 툴킷에 대한 업데이트가 반드시 필요하다.

   GWT를 J2EE 애플리케이션 환경에서 사용하기로 결정한 경우, GWT 디자인은 통합 기능을 상대적으로 간단해야 한다. 이 상황에서 GWT 서비스는 단순히 웹 요청을 백 엔드 상의 비즈니스-로직 호출로 위임하는 얇은 중간층인 Struts에 있는 Action와 비슷한 것으로 여겨진다. GWT 서비스는 단순히 HTTP 서블릿이기 때문에 Struts 또는 SpringMVC로 쉽게 통합되고, 인증 필터 뒤에 위치한다.

 

   하지만, GWT는 몇 가지 중대한 결점을 가지고 있다. 우선 첫 번째는 점진적인 성능 저하에 대한 대책이 없다는 것이다. 최근의 웹 애플리케이션 개발에 있어 가장 좋은 훈련은 JavaScript 없이 작동하는 페이지를 생성하는 것이다. 장식하는 데 유용한 곳에 JavaScript를 사용한 다음 여기에 여분의 기능을 추가하는 것이다. GWT에서 JavaScript를 이용할 수 없는 경우, UI를 얻지 못하게 된다. 웹 애플리케이션의 일정 클래스의 경우에 이런 상황은 곧장 거래를 불가능하게 만드는 요건이 된다. 국제화도 GWT의 주요 문제 중 하나다. GWT 클라이언트 자바 클래스는 브라우저에서 실행되기 때문에, 이 클래스는 런타임 시 로컬화 된 문자열을 얻는 속성 또는 리소스 번들에 대한 접근 기능이 없다. 각 로케일(참고자료)에 대해 생성되는 각 클라이언트 측 클래스의 하위 클래스를 요구하는 복잡한 대안이 유용하다. 하지만 GWT 엔지니어는 좀 더 실행 가능한 솔루션에서 작업한다.

 

   코드 생성에 관한 경우

 

   아마도 GWT 아키텍처에서 이론의 여지가 있는 문제는 클라이언트 측에 대한 자바 언어로의 전환일 것이다. 자바 언어로 클라이언트 측을 작성하는 일이 본질적으로 JavaScript 작성보다 더 낫다고 제시하는 GWT 주창자들이 있다. 모든 사람들이 이런 관점에 다 공감하는 것은 아니다. 때로는 자바 개발 작업이 성가신 업무라 자바 언어의 가변성 및 표현성을 없애는 것을 상당히 주저하는 JavaScript 코더들이 많다. 경험이 있는 웹 개발자가 부족한 팀의 경우, 자바 코드에서 JavaScript로의 교체는 설득력을 얻는 상황이 된다. 하지만 그 팀이 Ajax 개발 프로젝트로 옮길 경우, 자바 코더들에게 의뢰해 전용 툴을 이용해 까다로운 JavaScript를 생성하는 것보다는 숙련된 JavaScript 프로그래머들을 고용하는 게 더 나을지도 모른다. GWT가 JavaScript, HTTP 및 HTML로 확장하는 추상화 과정에서의 누설로 인해 필연적으로 버그가 생성되고, 경험이 없는 웹 프로그래머들은 버그를 추적하느라 애를 먹는다. 개발자이자 블로거인 Dimitri Glazkov는 다음과 같이 말했다. "JavaScript를 다룰 수 없으면 웹 애플리케이션에 대한 코드를 작성하지 말아야 한다. HTTL, CSS 및 JavaScript는 이런 조류에 대한 필요 충분조건이다." (참고자료)

 

   정적 타이핑 및 컴파일-타임 점검으로 인해 자바 코딩이 본질적으로 JavaScript 프로그래밍보다 오류에 덜 취약하다고 주장하는 사람들도 있다. 이는 상당히 불합리한 주장이다. 어떤 언어라도 나쁜 코드를 작성하는 일은 가능하다. 버그가 있는 자바 애플리케이션은 이를 잘 증명해주고 있다. 또한 GWT의 버그 없는 코드 생성에 의존할 수도 있다. 하지만 오프라인 구문-점검 과정 및 클라이언트 측 코드의 확인 작업은 분명 이로울 수 있다. 이와 같은 것은 Douglas Crockford의 JSLint (참고자료)의 타입으로 있는 JavaScript에서 가능하다. GWT는 단위 테스팅 기능면에서 우세하며 클라이언트 측 코드에 대한 JUnit 통합 기능을 제공한다. 단위 테스팅 지원 기능은 여전히 JavaScript에서 부족한 영역이다.

 

   Weather Reporter 애플리케이션을 개발하는 데 있어 필자가 클라이언트 측 코드에서 가장 매력적으로 본 것은 두 층 사이에 동일한 확인 클래스를 공유하는 기능이었다. 이 기능으로 인해 분명 애플리케이션 개발 노력을 줄여준다. RPC 전체에 전송된 임의의 클래스인 경우에도 같은 상황이 적용된다. 이때, 클래스들을 코드화하기만 하면 된다. 그러면 클라이언트 측 코드 및 서버측 코드 둘 다 클래스를 이용할 수 있다. 하지만 불행히도, 이런 추상화 법칙은 새기 쉽다. 예를 들어, 필자의 ZIP 코드 밸리데이터에서, 필자는 정규식을 사용해 점검 기능을 수행했으면 했다. 하지만 GWT는 String.match() 메소드를 구현하지 않는다. 심지어 구현했다 하더라도, GWT에서의 정규식은 클라이언트 및 서버 코드로 전개했을 때 구문적 차이를 보인다. 이는 호스트 환경의 기초적인 regexp 메커니즘으로 인해 생기는 것이며, 불완전한 추상화로 생기는 문제를 보여주는 예를 나타낸다.

 

   GWT에서 얻는 한 가지 큰 장점은 자체의 RPC 메커니즘 및 자바 코드 및 JavaScript 간의 객체의 고유 직렬화다. 이로 인해 일상적인 Ajax 애플리케이션에서 보는 수많은 작업들이 줄어든다. 하지만 전례가 없었던 건 아니다. 나머지 GWT 없이 이와 같은 기능을 원한다면, 자바 코드에서 JavaScript까지 객체를 동원하는 RPC를 제공하는 Direct Web Remoting은 고려해 볼만한 가치가 있다 (참고자료)

 

   GWT는 또한 크로스-브라우저 비호환성, DOM 이벤트 모델 및 Ajax 호출하기 등 Ajax 애플리케이션 개발에 있어 몇 가지 최하위 기능을 추상화하는 좋은 기능이 있다. 하지만 Yahoo!, UI 라이브러리, Dojo, 및 MochiKit등 최근의 JavaScript 툴킷은 전부 코드 생성에 대한 필요성 없이도 비슷한 수준의 추상화 기능을 제공한다. 게다가 이런 모든 툴킷은 오픈 소스다. 따라서 이런 툴킷을 필요에 맞게 이용하거나 발생되는 버그를 수정할 수 있다. GWT의 블랙박스에서는 이런 일이 불가능하다. (라이센싱 사이드 바 참조)




   결론

 

   GWT는 수많은 기능을 제공하는 광범위한 프레임웍이다. 하지만 GWT는 모 아니면 도 방식이 짙어 웹 애플리케이션 개발 시장에서 상당히 작은 영역에 국한되어 있다. GWT에 대한 간략한 소개의 글로 GWT의 기능 및 한계를 느꼈으리라 생각된다. 이 글이 모든 사람의 필요를 만족시킬 수는 없겠지만, GWT는 Ajax 애플리케이션을 설계할 시 엔지니어링 분야의 큰 업적이다. GWT에 관해선 필자가 설명한 것보다 훨씬 더 많은 영역이 있다. 따라서 GWT에 대해 자세한 내용을 원하면 구글 문서를 참조하거나 GWT 개발자 포럼 토론에 참석하기를 권한다. (참고자료)

 

기사의 원문보기

Posted by 1010
06.Ajax2008. 11. 13. 11:42
반응형

=============================================================================
====== Ajax 관련 자주 방문해야 하는 싸이트 ========
=============================================================================
 
 
 
 
 
 
 
 
 
 
 
=============================================================================
====================== Ajax 관련 오픈소스=======================
=============================================================================
=============================================================================
=============== Ajax 관련 라이브러리 & 툴 =================
=============================================================================
http://www.youngpup.net/2001/domdrag/ => dom dram 관련 싸이트
 
IBM AJAX Toolkit Framework =>IBM AJAX Toolkit Framework
An Eclipse Incubation Project Proposal =>IBM AJAX Toolkit Framework을 이해하는데 도움을 주는 제안서
 
http://httpunit.sourceforge.net/ => HttpUnit 테스팅 프레임웍
 
http://fitnesse.org/ => FitNesse 테스팅 프레임웍
 
http://jwebunit.sourceforge.net/ => 웹 테스팅 프레임웍으로 자바 개바자라면 추천해 본다.

http://www.edwardh.com/jsunit/ => JsUnit 홈페이지


http://devedge-temp.mozilla.org/toolbox/examples/2003/inheritFrom/index_en.html => 넷스케이프 커뮤니케이션의 Bob Clay 는 부모 클래스의 메소드를 자식 클래스에 복사할 수 있는 아주 간단한 메소드를 소개하였다.


http://chrispederick.com/work/webdeveloper/ => Web Developer Extension for FireFox 으로써 파이어폭스 브라우저가 제공해 주는 다양한 기능의 툴바를 다운/설치할 수 있는 싸이트이다.


http://hometown.aol.de/_ht_a/memtronic/ => 자바스크립트 파일을 압축하거나 Obfuscation(자신의 소스코드를 다른 사람이 악의적으로 도용하고나 훔쳐가는 것을 막기 위해서 멤버나 메소드 이름을 의미없는 문자들로 바꾸는 기법)하는 Freeware 싸이트이나 현재버젼에서는 아직까지 자바스크립트에 대한 Obfuscation 은 지원하지 않고 있다.


http://www.jslint.com/ => 자바스크립트 소스코드를 검증해 주는 싸이트


http://www.mozilla.com/ => 모질라 닷컴/파이어 폭스 최신버젼 다운로드


https://addons.mozilla.org/ => FireFox add on home page


https://addons.mozilla.org/extensions/?application=firefox => firefox add on extensions


http://www.activeperl.com/ => 펄의 런타임 환경인 ActivePerl 을 다운로드 받을 수 있다.


http://jsdoc.sourceforge.net/ => javadoc 명령으로 HTML API를 생성하듯이 자바스크립트의 주석을 바탕으로 HTML 다큐먼트를 생성하는 오픈소스


http://www.openqa.org/selenium/ => html 및 자바스크립트를 검사해주는 아주 훌륭한 오픈소스다. 실험적인 프로그램이지만 100점 주고 싶다.


http://www.activeperl.com/ => 펄 런타임 환경 다운로드 싸이트


http://jsdoc.sourceforge.net/ => jsDoc


http://www.json.org => JSON 홈페이지


http://www.ashleyit.com/rs/main.htm => Remote Scripting 관련하여 Brent Ashley 가 운영하는 싸이트




=============================================================================

======================= Ajax 응용 싸이트 =========================
=============================================================================
 
=> 구굴에서 만든 달력 및 메모
 
http://maps.a9.com/ => Ajax 를 이용한 map 싸이트
 

http://maps.google.com/ => 구굴 맵


http://www.google.com/ig => Draggable DOM pattern 을 아주 훌륭하게 적용한 싸이트


http://www.google.com/webhp?complete=1&hl=kor => 구굴 Suggest 한글 검색창


http://www.google.com/webhp?complete=1&hl=en => 구굴 Suggest 영문 검색창


http://www.netflix.com/BrowseSelection => ajax 를 이용한 툴팁을 구현한 싸이트


http://www.apple.com/itunes/ => AJAX 관련 refresh 기능을 구현해 놓은 싸이트.(애플 itunes 뮤직 다운로드 자동 카운트)


http://www.digg.com/spy => AJAX 관련 refresh 기능을 구현해 놓은 싸이트.(새로운 정보 컨텐츠 리스트 자동 소팅 기능)

 
 
 

=============================================================================

============== Ajax 관련  기타  참고 싸이트 ==============
=============================================================================

http://www.apress.com/book/supplementDownload.html?bID=10042&sID=3021 => Foundation of Ajax 소스 다운로드 url



|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||

출처: http://blog.naver.com/jinoxst/140021466351 


 

AJAX 관련 자주 방문해야 하는 싸이트


http://ajaxian.com/


http://ajaxpatterns.org


http://ajaxmatters.com/r/welcome


http://ajaxblog.com/


http://labs.google.com/


http://www.adaptivepath.com/


http://www.37signals.com/


http://www.oreilly.com/


http://developer.apple.com/



AJAX 관련 오픈소스


http://zk1.sourceforge.net/


http://sourceforge.net/projects/zk1/


http://sourceforge.net/projects/taconite


http://www.rubyonrails.org/


http://www.ruby-lang.org/en/


http://swik.net/AJAXSLT


http://code.google.com/webtoolkit/



AJAX 관련 라이브러리 & 툴


http://www-128.ibm.com/developerworks/kr/library/os-ecl-ajax/
=> Eclipse의 Ajax Toolkit Framework에서 지원되는 툴 (한글)


http://www.youngpup.net/2001/domdrag/
=> dom dram 관련 싸이트


http://httpunit.sourceforge.net/
=> HttpUnit 테스팅 프레임웍


http://fitnesse.org/
=> FitNesse 테스팅 프레임웍


http://jwebunit.sourceforge.net/
=> 웹 테스팅 프레임웍으로 자바 개바자라면 추천해 본다.


http://www.edwardh.com/jsunit/

=> JsUnit 홈페이지


http://devedge-temp.mozilla.org/toolbox/examples/2003/inheritFrom/index_en.html

=> 넷스케이프 커뮤니케이션의 Bob Clay 는 부모 클래스의 메소드를 자식 클래스에 복사할 수 있는 아주 간단한 메소드를 소개하였다.


http://chrispederick.com/work/webdeveloper/

=> Web Developer Extension for FireFox 으로써 파이어폭스 브라우저가 제공해 주는 다양한 기능의 툴바를 다운/설치할 수 있는 싸이트이다.


http://hometown.aol.de/_ht_a/memtronic/

=> 자바스크립트 파일을 압축하거나 Obfuscation(자신의 소스코드를 다른 사람이 악의적으로 도용하고나 훔쳐가는 것을 막기 위해서 멤버나 메소드 이름을 의미없는 문자들로 바꾸는 기법)하는 Freeware 싸이트이나 현재버젼에서는 아직까지 자바스크립트에 대한 Obfuscation 은 지원하지 않고 있다.


http://www.jslint.com/

=> 자바스크립트 소스코드를 검증해 주는 싸이트


http://www.mozilla.com/

=> 모질라 닷컴/파이어 폭스 최신버젼 다운로드


https://addons.mozilla.org/

=> FireFox add on home page


https://addons.mozilla.org/extensions/?application=firefox

=> firefox add on extensions


http://www.activeperl.com/

=> 펄의 런타임 환경인 ActivePerl 을 다운로드 받을 수 있다.


http://jsdoc.sourceforge.net/

=> javadoc 명령으로 HTML API를 생성하듯이 자바스크립트의 주석을 바탕으로 HTML 다큐먼트를 생성하는 오픈소스


http://www.openqa.org/selenium/

=> html 및 자바스크립트를 검사해주는 아주 훌륭한 오픈소스다. 실험적인 프로그램이지만 100점 주고 싶다.


http://www.activeperl.com/

=> 펄 런타임 환경 다운로드 싸이트


http://jsdoc.sourceforge.net/

=> jsDoc


http://www.json.org

=> JSON 홈페이지


http://www.ashleyit.com/rs/main.htm

=> Remote Scripting 관련하여 Brent Ashley 가 운영하는 싸이트



AJAX 응용 싸이트


http://www.dhteumeuleu.com/

http://www.google.com/calendar/render
=> 구굴에서 만든 달력 및 메모

http://maps.a9.com/
=> Ajax 를 이용한 map 싸이트

http://maps.google.com/

=> 구굴 맵


http://www.google.com/ig

=> Draggable DOM pattern 을 아주 훌륭하게 적용한 싸이트


http://www.google.com/webhp?complete=1&hl=kor

=> 구굴 Suggest 한글 검색창


http://www.google.com/webhp?complete=1&hl=en

=> 구굴 Suggest 영문 검색창


http://www.netflix.com/BrowseSelection

=> ajax 를 이용한 툴팁을 구현한 싸이트


http://www.apple.com/itunes/ =

> AJAX 관련 refresh 기능을 구현해 놓은 싸이트.(애플 itunes 뮤직 다운로드 자동 카운트)


http://www.digg.com/spy

=> AJAX 관련 refresh 기능을 구현해 놓은 싸이트.(새로운 정보 컨텐츠 리스트 자동 소팅 기능)


AJAX 관련  기타  참고 싸이트

http://www.apress.com/book/supplementDownload.html?bID=10042&sID=3021

=> Foundation of Ajax 소스 다운로드 url

Posted by 1010
06.Ajax2008. 10. 9. 15:59
반응형
Posted by 1010
06.Ajax2008. 9. 3. 14:39
반응형

Ajax와 XML: 다섯 개의 추천할 만한 Ajax 위젯 (한글)

새로운 그래픽 툴로 Ajax와 XML을 사용하여 사이트 품질 높이기

developerWorks
문서 옵션
수평출력으로 설정

이 페이지 출력

이 페이지를 이메일로 보내기

이 페이지를 이메일로 보내기

토론


제안 및 의견
피드백

난이도 : 중급

Jack D Herrington, Senior Software Engineer, Leverage Software Inc.

2007 년 5 월 02 일

Web 2.0은 사용자 경험을 강조하고 있습니다. 이것의 일환으로 고급스러운 방식으로 사용자와 인터랙팅 하고 사용자에게 정보를 제공하는 것입니다. 이러한 새로운 인터페이스들을 위젯이라고 하며, Asynchronous JavaScript + XML (Ajax)을 사용하여 서버와 통신합니다. 사이트와의 상호 작동을 향상시키는데 사용할 수 있는 다섯 개의 위젯에 대해 알아봅시다.

Web 2.0 혁명은 웹 사이트 상에서 고객과 상호 작동하는 독특하면서도 고급스러운 방식이 탄생했다. 이렇게 새롭고 혁신적인 많은 기술들은 서버와 통신하는 그래픽과 위젯을 사용하여 데이터를 가져오는데 까지 진화했다. 이 글에서는, 다섯 가지 위젯을 소개하겠다. 일부는 오픈 소스이고, 일부는 상용이며, 이러한 위젯들은 Ajax와 XML을 통해 서버와 통신한다.

  • carousel: 이 위젯은 작은 그래픽으로 나타난 아이템 리스트를 스크롤 하는데 사용할 수 있는 회전식 이미지 뷰어이다. 사용자가 해당 아이템을 클릭할 때 어떻게 할 것인지는 여러분이 정한다. carousel의 예로는 Flikr 사이트와 Apple의 iTunes 인터페이스가 있으며, 이는 무료로 사용할 수 있으며, 대중적인 jQuery JavaScript 기반이다.
  • SWF/Charts: Adobe Flash 기반 컨트롤은 서버에 있는 차팅(charting) 데이터 및 스타일링 옵션용 XML을 읽고, 데이터에 기반하여 차트를 디스플레이 한다. 인터페이스는 고급스럽고, XML 데이터는 생성하기도 쉬워서 페이지에 동적 그래픽을 빠르게 추가할 수 있다.
  • SWF/Gauge: SWF/Charts의 사촌격인 이 Flash 위젯은 서버에 있는 XML을 사용하여 완전히 커스터마이징 가능한 게이지 디스플레이를 구현한다. 게이지는 비행기 또는 차에 있는 것과 비슷하다.
  • In-place editing: 엄밀히 말하면 위젯은 아니지만, In-place editing 컨트롤은 매력적이고, 대화식으로 사용자에게서 정보를 가져온다. In-place editing 기능은 Scriptaculous 프레임웍에 포함되어 있고, 이는 prototype.js 라이브러리에 있다.
  • DHTML windows: DHTML window는 모델이 없는 윈도우를 페이지 콘텐트에 놓는 장치이다. 사용자들은 윈도우를 이동하고, 사이즈를 조정하며, 제거하기도 한다. 이 윈도우의 콘텐트는 페이지 상에서 JavaScript 코드에 의해 지정되거나, 서버에서 Ajax를 통해 읽힌다. 이러한 유형의 윈도우는 경고 장치로 사용하기에 알맞으며, 전체 페이지를 재 로딩 할 필요가 없는 작은 폼을 가져오는데 알맞다.

SWF/Charts 위젯부터 설명하겠다. 내가 생각하기에 이 위젯이 전개하기에 가장 쉽다. 노력에 비해 보상도 가장 크다.

SWF/Charts 위젯

"한편의 그림이 천마디 말보다 낫다"라는 속담을 무시할 수 없으며 특히, 그래프가 관여된 곳에서는 더욱 그렇다. 그러나, 웹에서의 그래프는 언제나 문제가 되며, 대부분의 웹 프레임웍들은 그래핑 툴이 부족하다. 따라서 여러분 스스로 그래프를 만들어야 한다.

XML로 인코딩 된 데이터를 그릴 수 있는 위젯이 있다면 정말 좋을 것 같지 않은가? 마침 SWF/Charts가 있다. 이 위젯을 사용하려면, 사이트에서 SWF 파일과 이 위젯이 사용하는 추가 SWF 파일들을 다운로드 하고 나서, 사이트에 파일을 설치하고, HTML 페이지 상의 SWF 위젯에 링크를 추가했다. (Listing 1)


Listing 1. Chart_page.html
                
<html><body>

<object
  classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
  codebase="http://download.macromedia.com/pub.../swflash.cab#version=6,0,0,0" 
  width="400" height="250">
<param name="movie"
  value="charts.swf?xml_source=chart_data.xml&library_path=charts_library">

<embed
  src="charts.swf?xml_source=chart_data.xml&library_path=charts_library" 
  width="400" height="250" 
  type="application/x-shockwave-flash" 
  pluginspace="http://www.macromedia.com/go/getflashplayer">
</embed>
</object>

</body></html>

Charts.swf 는 두 개의 매개변수를 취한다. 라이브러리 디렉토리의 위치와 XML 데이터의 URL이다. XML 데이터 포맷은 매우 쉽다. Listing 2는 예제이다.


Listing 2. Chart_data.xml
                
<chart>
  <chart_type>bar</chart_type>
  <chart_data>
    <row>
      <null/>
      <string>2005</string>
      <string>2006</string>
    </row>
    <row>
      <string>Projected</string>
      <number>500</number>
      <number>700</number>
    </row>
    <row>
      <string>Actual</string>
      <number>600</number>
      <number>900</number>
    </row>
  </chart_data>
</chart>

이 파일은 차트용 데이터이고, 선택적인 비주얼 정보도 있다. 이 경우, 필자는 차트 유형을 바(bar) 차트로 지정했다. SWF 파일을 다운로드 했던 사이트에는 더 많은 옵션들과 그래프 유형들이 있다.

Firefox 브라우저에서 파일을 검색하면 그림 1과 같은 그래프를 볼 수 있다.


그림 1. Chart Widget
Chart Widget 보기

기본 컬러 스킴과 모습도 멋지며, 그래프는 중심축 값을 보기 좋게 처리했다. 적은 노력으로 전체적으로 큰 효과를 보았다.

분명히, graph_data.xml 파일을 동적인 웹 페이지로 대체할 수 있었다. 리턴된 데이터가 올바른 포맷으로 되어 있다면 그래프 컨트롤은 적은 부분만 신경 쓰면 된다. 이 글에 있는 대부분의 예제들이 이에 속한다. 사실, 웹 서버(Apache Tomcat 또는 IBM® WebSphere® Application Server)나 웹 프로그래밍 언어(PHP, Microsoft® ASP.NET, Java™ 2 Enterprise Edition [Java EE])를 사용하지 않고도 로컬 파일에 있는 웹 브라우저에서 이 예제들을 실행할 수 있다.




위로


SWF/게이지 위젯

데이터를 나타내는 또 다른 방법은 게이지로 표현하는 것이다. 개인적으로는 게이지에 대해서는 흥미가 별로 없다. 적은 정보를 나타내는 데도 많은 공간을 차지하기 때문이다. 하지만, 게이지는 전문 대시보드의 핵심 기능이기 때문에, 이들을 빠르게 생성하는 기능은 매우 유용하다.

하지만, 웹이 간단한 바 차트도 잘 수행하지 못한다면, 원형 게이지 역시 수행할 수 없다. 따라서, XML/Graph를 만들었던 회사에 문의했다. 그들도 게이지에 대한 솔루션이 있었다. 바로 XML/Gauge였다.

SWF게이지 위젯을 삽입하는 HTML 페이지로 시작하겠다. (Listing 3)


Listing 3. Gauge_page.html
                
<html><body>

<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
  codebase="http://download.macromedia.com/.../swflash.cab#version=6,0,0,0"
  width="110" height="55">
<param name=movie VALUE="gauge.swf?xml_source=gauge_data.xml">
<embed src="gauge.swf?xml_source=gauge_data.xml"
  width="110" height="55" type="application/x-shockwave-flash"
  pluginspace="http://www.macromedia.com/go/getflashplayer">

</embed></object>

</body></html>	

gauge.swf 영화는 하나의 인자를 취한다. 데이터의 위치이다. 이 경우, 그 위치는 gauge_data.xml이다. (Listing 4)


Listing 4. Gauge_data.xml
                
<gauge>

<circle fill_color="888888" start="275" fill_alpha="100"
  line_color="555555" line_thickness="3" line_alpha="90"
  radius="50" x="55" end="445" y="55"/>
<circle fill_color="99bbff" start="280" fill_alpha="90"
  line_thickness="4" line_alpha="20" radius="45" x="55"
  end="440" y="55"/>
<circle fill_color="666666" start="317" fill_alpha="100"
  line_color="333333" line_alpha="0" radius="44" x="55"
  end="322" y="55"/>
<circle fill_color="666666" start="337" fill_alpha="100"
  line_color="333333" line_alpha="0" radius="44" x="55"
  end="342" y="55"/>
<circle fill_color="666666" start="357" fill_alpha="100"
  line_color="333333" line_alpha="0" radius="44" x="55"
  end="362" y="55"/>
<circle fill_color="666666" start="377" fill_alpha="100"
  line_color="333333" line_alpha="0" radius="44" x="55"
  end="382" y="55"/>
<circle fill_color="666666" start="397" fill_alpha="100"
  line_color="333333" line_alpha="0" radius="44" x="55"
  end="402" y="55"/>
<circle fill_color="666666" start="417" fill_alpha="100"
  line_color="333333" line_alpha="0" radius="44" x="55"
  end="422" y="55"/>
<circle fill_color="99bbff" start="280" fill_alpha="100"
  radius="40" x="55" end="440" y="55"/>
<circle fill_color="FF4400" start="280" fill_alpha="100"
  radius="44" x="55" end="310" y="55"/>
<circle fill_color="44FF00" start="50" fill_alpha="100"
  radius="44" x="55" end="80" y="55"/>
<circle fill_color="99bbff" start="280" fill_alpha="80"
  radius="40" x="55" end="440" y="55"/>
<circle fill_color="333333" start="270" fill_alpha="100"
  line_alpha="0" radius="20" x="55" end="450" y="55"/>

<rotate start="280" shake_span="2" shadow_alpha="15"
  step="1" x="55" span="0" y="55" shake_frequency="20">
  <rect fill_color="ffff00" fill_alpha="90" line_alpha="0"
    height="40" x="53" width="4" y="13"/>
</rotate>

<circle fill_color="111111" start="270" fill_alpha="100"
  line_thickness="5" line_alpha="50" radius="15" x="55"
  end="450" y="55"/>

</gauge>

여러분도 보듯, SWF는 이 위젯에 다른 방식을 취했다. 게이지(또는 그래프)용 데이터를 지정하는 대신, 원, 호, 직사각형 같은 그래픽 프리머티브에서 게이지를 구현한다.

솔직히, 필자는 데이터를 제공할 수 있는 기본 게이지를 선호한다. 하지만, 이 방식도 작동하고, 얼마든지 조정이 가능하다. 비록, 필자는 기본 예제들을 몇 개 더 사용했다.

내 브라우저에 있는 페이지로 갈 때, 그림 2와 같은 게이지를 볼 수 있다.


그림 2. Gauge Widget
Gauge Widget

그래픽 프리머티브를 지정하는 것으로는, 이 위젯에서 얻을 수 있는 것이 많이 없다고 생각할 수도 있다. 그렇지 않다. 이 프리머티브에는 간단한 애니메이션 기술도 포함되어 있어서 바늘과 소리도 넣을 수 있고 사용자가 이것을 클릭하면 브라우저를 검색하는 중요한 연결 영역을 만드는 기능도 있다. 게다가, 이 콘트롤을 게이지에 사용하는 것뿐만 아니라, 간단한 그래픽 프리머티브 언어를 사용하여 어떤 유형의 이미지와 간단한 애니메이션을 구현할 수 있다.




위로


In-place editing

사용자들은 이제 데스크탑 애플리케이션에서 In-place editing을 기대하지만, 이러한 기능은 아직까지는 웹에서는 찾아보기 힘들다. Web 2.0에서는 상호 작동이 우수하기 때문에, In-place editing 같은 기술은 보다 더 일반화 된다.

In-place editing을 구현하려면, 직접 작성하거나, JavaScript 프레임웍들 중 하나를 사용한다. 가장 대중적인 툴킷은 Scriptaculous 프레임웍인데, 이것은 prototype.js에 구현된다. Scriptaculous 라이브러리를 사용하면 In-place editing 컨트롤을 매우 쉽게 구현할 수 있다.

In-place editing용 HTML 테스트 파일은 Listing 5를 참조하라.


Listing 5. Inplace.html
                
<html><head>
<script src="prototype.js"></script>
<script src="effects.js"></script>
<script src="controls.js"></script>
<script src="scriptaculous.js"></script>
</head><body>
<table width="100%">
<tr><th width="10%">Name</th>
<td width="90%"><p id="name">Candy bar</p></td>
</tr></table>
<script>
new Ajax.InPlaceEditor('name', 'submitted.html' );
</script>
</body>
</html>

Inplace.html에는 필요한 모든 JavaScript 소스 파일이 포함된다. 간단한 테이블에 In-place editing 가능한 데이터를 포함하고 있는 단락을 넣는다. 이 파일의 끝에, 이 단락의 InPlaceEditor 객체를 생성하는 스크립트를 삽입한다.

InPlaceEditor 컨스트럭터는 인자로서 단락의 ID와 편집을 수행한 후에 제출을 처리할 페이지의 URL을 취한다. 이 경우, 이 페이지는 submitted.html이다. 하지만 현실적으로, 이것은 ASP.NET, Java EE, 또는 PHP 페이지 또는 기타 동적 웹 기술이다.

Listing 6은 submitted.html 파일이다.


Listing 6. Submitted.html
                
<p>Name changed!</p>

이제 테스트 할 차례이다. 브라우저를 HTML 파일에서 연다. 이곳에서 원래의 텍스트를 보게 된다. 텍스트에 마우스를 갖다 대면, 노란색으로 변한다. (그림 3)


그림 3. in-place editing의 시작 포인트
in-place editing의 시작 포인트

노란색 하이라이팅은 이것을 클릭하여 필드를 편집할 수 있다는 사용자용 인디케이터이다. 따라서, 필자는 그 필드를 클릭하고 Name 필드, ok 버튼, cancel 링크를 만들었다. (그림 4)


그림 4. 클릭한 후 텍스트 편집하기
클릭한 후 텍스트 편집하기

텍스트를 수정하고 ok를 클릭한다. 이렇게 하면 데이터가 서버에 게시된다. (또는 이 경우 submitted.html page). 서버는 원래의 텍스트를 대체하는 HTML 페이지를 리턴한다. 이 경우에, 필자는 Name changed!를 보낸다. (그림 5) 실제로, 이것은 데이터의 새로운 값이 되어야 한다.


그림 5. ok를 클릭한 후 새로운 콘텐트
ok를 클릭한 후 새로운 콘텐트

이와 같은 간단한 인터페이스 업그레이드는 애플리케이션의 가용성에 차이를 만든다. 느린 서버에서 페이지 로드를 기다리는 것은 구식 인터페이스이다. In-place editing 같은 간단한 툴을 사용하면 구현 복잡성의 관점에서 볼 때 애플리케이션에 간단한 몸치장을 한 것과 같다.




위로


DHTML 윈도우

브라우저에서 윈도우를 웹 페이지에 구현하기 힘들다는 것은 좋은 일일지도 모른다. 하지만 가끔씩, 작은 윈도우도 좋은 것이 될 수 있다. 이는 경고를 디스플레이 하거나 작은 폼을 가져오는데 편리하며, 페이지의 내용을 덮어버리는 성가신 광고를 실행하기에 좋은 방법이다. 잠깐 기다려라. 마지막 말은 취소해야겠다.

어쨌든, 내가 말했지만 Dynamic HTML (DHTML) 페이지용 윈도우를 구현하는 것은 쉬운 일이 아니다. 그래서, Protoype.js 라이브러리에 기반한 매우 강력한 윈도우 패키지를 발견했을 때 너무 기뻤다. 사용하기 쉬울 뿐만 아니라, 인터페이스도 가볍고 모든 브라우저에서 잘 작동한다. Listing 7은 window.html 페이지 모습이다.


Listing 7. Window.html
                
<html>
<head>
<link href="default.css" rel="stylesheet" type="text/css" />
<script src="prototype.js"></script>
<script src="window.js"></script>
</head>
<body>
<script>
var win = new Window( 'myPopup', {
   title: "Terms and Conditions",
   top:70, left:100, width:300, height:200,
   resizable: true, url: "terms.html",
   showEffectOptions: { duration: 3 }
  } 
);
win.show();
</script>
</body>
</html>

prototype.js와 window.js 소스 파일을 헤더로 가져온다. 그런 다음, 내가 좋아하는 매개변수(크기, 위치, 타이틀, 위젯이 콘텐트를 얻는 페이지의 URL)로 팝(pop) 객체를 구현한다. Ajax를 통해 페이지에서 콘텐트를 로딩하는 것은 콘텐트를 얻는 방법들 중 하나이다. JavaScript 코드를 통해 동적으로 설정할 수 있고 또는 기존 <div> 태그 주위에 윈도우를 래핑할 수 있다.

이 경우 필자는 terms.html 파일을 참조한다. (Listing 8)


Listing 8. Terms.html
                
<html><body bgcolor="white">
<h1>Terms and Conditions</h1>
<p>In order to use this site you must comply
with the following conditions...</p>
</body></html>

내 브라우저에서 이 페이지를 실행하면 그림 6과 같은 윈도우를 보게 된다.


그림 6. 초기 윈도우
초기 윈도우

이것은 단지 두 개의 Mac 윈도우만은 아니다. Mac 처럼 보이는 DHTML 윈도우가 있고 그 밖에는 실제 Firefox 브라우저 윈도우이다. 하지만 어쨌든 같은 것으로 보여진다.

윈도우를 늘려 이동할 수 있다. (그림 7)


그림 7. 이동 및 크기 조정 후 윈도우 모습
이동 및 크기 조정 후 윈도우 모습

필자는 본 기술자료와 내 작업을 위해 여러 드물 윈도우 라이브러리를 검토했고, 이것이 가장 좋았다고 자신 있게 말할 수 있다. 다른 윈도우 패키지들은 실행 문제들이 있었고, 세그먼트에서 실행되며, 사이즈를 재조정 하면 형편없이 실행되었다. 브라우저 안에 갇힌 실제 윈도우처럼 보인다.




위로


carousel 위젯

많은 사용자 인터페이스(UI)를 다루어본 사람이라면 실제 상태를 나타내는 것이 중요하다고 말할 것이다. 꽉 찬 느낌을 주지 않고 주어진 공간에 최대로 담을 수 있는 데이터를 넣는 것이 중요하다. Apple iTunes의 carousel 컨트롤을 처음 보았을 때 깊은 감명을 받았다.

carousel 컨트롤은 고정된 공간에서 여러 이미지들을 보여준다. 이미지 블록의 왼쪽과 오른쪽은 왼쪽 화살표와 오른쪽 화살표이다. 화살표를 클릭하면, 이미지는 왼쪽 또는 오른쪽으로 이동하고, 새로운 이미지로 대체된다. iTunes 에서, 이 이미지는 앨범 커버였고, 각 장르마다 carousel 컨트롤이 있었다.

공간 절약은 중요하다. 세 개의 공간에 30 개의 앨범 커버를 넣을 수 있고, 각각 알맞은 크기로 보여줄 수 있다. 또한, 이 컨트롤은 매력적이다. 마치, 단순화 된 스크롤바 같다.

carousel의 단점은 구현이 쉽지 않다는 점이다. 특히, 이것의 특징 중 하나가 왼쪽 또는 오른쪽으로 이동하는 이미지의 애니메이션이기 때문이다. 따라서 jQuery JavaScript 프레임웍에 구현된 carousel이라고 하는 오픈 소스 carousel에 대해 알게 되었을 때 기뻤다.

필자는 웹 페이지에 간단한 carousel 위젯을 구현했다. ( Listing 9)


Listing 9. Carousel.html
                
<html>
<head>
<script type="text/javascript" src="js/jquery-1.0.3.js"></script>
<script type="text/javascript" src="js/jcarousel.js"></script>
<style type="text/css">
#mycarousel { display: none; }
.jcarousel-scope {  position: relative; width: 255px;
  -moz-border-radius: 10px; background: #D4D0C8;
  border: 1px solid #808080; padding: 20px 45px; }
.jcarousel-list li { width: 81px; height: 81px;
  margin-right: 7px; }
.jcarousel-list li img { border: 1px solid #808080; }
.jcarousel-list li a { display:block;  outline: none;
  border: 2px solid #D4D0C8; -moz-outline:none; }
.jcarousel-list li a:hover { border: 2px solid #808080; }
.jcarousel-next {  position: absolute; top: 45px;
  right: 5px; cursor: pointer; }
.jcarousel-next-disabled { cursor: default; }
.jcarousel-prev { position: absolute; top: 45px;
  left: 5px; cursor: pointer; }
.jcarousel-prev-disabled { cursor: default; }
.loading { position: absolute; top: 0px;
  right: 0px; display: none; }
</style>
<script type="text/javascript">
function loadItemHandler( carousel, start, last, available ) {
  if (available) { carousel.loaded(); return; }
  var cr = carousel;
  jQuery.get("data.xml", function(data) { appendItemCallback(cr, start, last, data); });
};

function appendItemCallback( carousel, start, last, data ) {
  var items = data.match( /(\<img .*?\>)/g );

  for (i = start; i <= last; i++) {
    if ( items[ i - 1 ] == undefined ) break;
    var item = carousel.add( i, getItemHTML( items[i-1]) );
    item.each(function() {
      jQuery("a.thickbox", this).click(function() {
        var t = this.title || this.name || null;
        var g = this.rel || false;
        TB_show(t,this.href,g);
        this.blur();
        return false;
      });
    });
  }
  carousel.loaded();
};

function getItemHTML( item ) {
  var found = item.match( /href=\"(.*?)\"/ );
  var url   = jQuery.trim(found[1]);
  var title = jQuery.trim(found[1]);
  var url_m = url.replace(/_s.jpg/g, '_m.jpg');
  return '<a href="' + url_m +
	'" title="' + title +
	'" class="thickbox"><img src="' + url +
	'" width="' + 75 + '" height="' + 75 +
	'" alt="' + title + '" /></a>';
};

var nextOver = function() {
  jQuery(this).attr("src", "img/horizontal-ie7/next-over.gif"); };

var nextOut = function() {
  jQuery(this).attr("src", "img/horizontal-ie7/next.gif"); };

var nextDown = function() {
  jQuery(this).attr("src", "img/horizontal-ie7/next-down.gif"); };

function nextButtonStateHandler(carousel, button, enabling) {
  if (enabling) {
    jQuery(button).attr("src", "img/horizontal-ie7/next.gif")
      .mouseover(nextOver).mouseout(nextOut).mousedown(nextDown);
  } else {
    jQuery(button).attr("src", "img/horizontal-ie7/next-disabled.gif")
      .unmouseover(nextOver).unmouseout(nextOut).unmousedown(nextDown);
  }
}

var prevOver = function() {
  jQuery(this).attr("src", "img/horizontal-ie7/prev-over.gif"); };

var prevOut = function() {
  jQuery(this).attr("src", "img/horizontal-ie7/prev.gif"); };

var prevDown = function() {
  jQuery(this).attr("src", "img/horizontal-ie7/prev-down.gif"); };

function prevButtonStateHandler(carousel, button, enabling) {
  if (enabling) {
    jQuery(button).attr("src", "img/horizontal-ie7/prev.gif")
      .mouseover(prevOver).mouseout(prevOut).mousedown(prevDown);
  } else {
    jQuery(button).attr("src", "img/horizontal-ie7/prev-disabled.gif")
      .unmouseover(prevOver).unmouseout(prevOut).unmousedown(prevDown);
  }
}

jQuery(document).ready(function() {
  jQuery().ajaxStart(function() { jQuery(".loading").show(); });
  jQuery().ajaxStop(function() { jQuery(".loading").hide(); });
  jQuery("#mycarousel").jcarousel({
    itemVisible: 3, itemScroll: 2, wrap: true,
    loadItemHandler: loadItemHandler,
    nextButtonStateHandler: nextButtonStateHandler,
    prevButtonStateHandler: prevButtonStateHandler
  });
});
</script></head><body><div id="mycarousel">
<div class="loading">
<img src="img/loading.gif" width="16" height="16" border="0" />Loading...</div>
<img src="img/horizontal-ie7/prev.gif" border="0" class="jcarousel-prev" />
<img src="img/horizontal-ie7/next.gif" border="0" class="jcarousel-next" />
<ul></ul>
</div></body></html>

이전 예제들 보다 방대하다. 하지만 코드 대부분이 그래픽을 설정하고 서버에서 리턴된 Ajax 데이터를 인터프리팅 하는 것이다. 사실, 이 글에 소개된 대부분의 코드는 다운로드에서 제공하는 예제를 기반으로 하고 있다. 따라서 이 콘트롤을 사용하기 위해 많은 부분을 배우거나 문서를 읽을 필요가 없었다.

이 carousel용 데이터는 Listing 10에 나와있다.


Listing 10. Data.xml
                
<images>
<img href="pics/image1.jpg" />
<img href="pics/image2.jpg" />
<img href="pics/image3.jpg" />
<img href="pics/image4.jpg" />
</images>

이 경우, 파일은 <images> 태그와 각 이미지의 URL을 포함하고 있는 <img> 태그 세트들을 갖고 있는 XML 포맷으로 되어있다. 어떤 포맷을 사용하든지 간에, 이 컨트롤은 기본적으로 Ajax 위젯이 아니다. 필자는 XML을 인터프리팅 하는 코드를 작성 중이고, 각각의 슬라이드 엘리먼트를 carousel에 구현하고 있다. 결과는 그림 8과 같다.


그림 8. 이미지 carousel
이미지 carousel

이미지를 클릭하고 그 이미지가 있는 페이지로 갈 수 있다. (또는 내가 지정한 URL로 간다.) 또는, 오른쪽/왼쪽 화살표를 클릭하여 carousel 주위를 스크롤 하여 더 많은 이미지들을 볼 수 있다. 효과는 매우 좋다.




위로


결론

웹 상에서 사용할 수 있는 무료/상용 위젯과 툴들을 소개했다. 이 글을 쓰면서 보았던 많은 툴들이 Ajax를 사용하지 않았고, 이 주제에도 잘 맞지 않았다. 하지만, 그 자체로도 주목할 만한 가치가 있었다. 특히, 필자는 고급의 오픈 소스 WYSIWYG 에디터를 다운로드 할 수 있다는 것에 놀랐다. 사용자들은 자신들의 사이트에 있는 콘텐트에 볼드체, 이탤릭체, 링크, 이미지 등을 사용하려면 텍스트 박스에서 HTML을 사용해야 하는 것에 많이 좌절했다. 이러한 에디터들은 모든 HTML을 숨기고 사용자에게 워드 프로세스 애플리케이션과 비슷한 느낌으로 편집할 수 있도록 해준다.

WYSIWYG 에디터 외에도, 프로그래스 바, 탭 다이얼로그 박스, 아코디언 컨트롤, 클락, 데이트 피커(date picker), RSS, Outline Processor Markup Language (OPML) 리더용 솔루션도 있다. 심지어 대화형 터미널 윈도우용 솔루션도 있다. DHTML 또는 Flash 컨트롤을 직접 구현하기 전에, 인터넷에서 (무료로) 무엇을 사용할 수 있는지 찾아봐야 한다. 이러한 위젯들을 사용하여 많은 노력을 들이지 않고도 사이트에 역동성을 부여할 수 있다.

기사의 원문보기



참고자료

교육

제품 및 기술 얻기

토론


필자소개

Jack D. Herrington은 20년 경력을 지닌 소프트웨어 엔지니어이다. Code Generation in Action, Podcasting Hacks, PHP Hacks 의 저자이다. 30개 이상의 기술자료를 기고했다. (jherr@pobox.com)


Posted by 1010
06.Ajax2008. 7. 26. 16:54
반응형

Ajax 마스터하기, Part 1: Ajax 소개

웹 사이트를 구현하는 생선적인 방식인 Ajax 이해하기

developerWorks
문서 옵션
수평출력으로 설정

이 페이지 출력

이 페이지를 이메일로 보내기

이 페이지를 이메일로 보내기

토론


제안 및 의견
피드백

난이도 : 초급

Brett McLaughlin, Author and Editor, O'Reilly Media Inc.

2006 년 5 월 29 일
2006 년 5 월 29 일 수정

HTML, JavaScript™, DHTML, DOM으로 구성된 Ajax는 볼품없는 웹 인터페이스를 인터랙티브 Ajax 애플리케이션으로 변형하는 획기적인 방식이다. Ajax 전문가인 필자는 이러한 기술들이 어떻게 작용하는지 전체적인 개요를 비롯하여 세부사항 까지 설명한다. 또한 XMLHttpRequest 객체 같은 Ajax의 중심적인 개념들을 소개한다.

5년 전, XML에 대해 무지했다면 아무도 얘기할 상대가 없는 미운 오리 새끼 신세가 되었을지도 모르겠다. Ruby 프로그램이 주목을 받았던 8개월 전, Ruby 프로그램 언어 기능에 대해 알지 못했던 프로그래머들은 냉수기 관련 산업세계에서 환영 받지 못했다. 그런 것처럼, 최신 기술단계로 입문하고자 한다면 Ajax에 대해 알아야 한다.

하지만 Ajax는 일시적으로 유행하는 툴이 아니다. 웹 사이트를 구축하는 강력한 방식이며 완전히 새로운 언어를 배우는 것보다는 그다지 어렵지 않다.

Ajax에 관해 자세히 들어가기 전에 잠시 Ajax의 기능에 대해 알아보자. 오늘날 애플리케이션을 작성할 시 두 가지 애플리케이션이 있다.

  • 데스크톱 애플리케이션
  • 웹 애플리케이션

두 애플리케이션은 다 친숙한 것들이다. 일반적으로 데스크톱 애플리케이션은 CD상에 배치된 다음 (또는 웹 사이트에서 다운로드) 컴퓨터에 완전 설치된다. 이 애플리케이션은 인터넷을 이용해 업데이트를 다운로드하기도 하지만 애플리케이션 실행 코드는 데스크톱 상에 상주해 있다. 전혀 새로운 것이 아닌 웹 애플리케이션은 웹 서버 상에서 실행되며 웹 브라우저 상에서 접속된다.

하지만 두 애플리케이션에 대한 코드 실행 위치보다 애플리케이션 작동방식 및 애플리케이션과 사용자와의 상호작용방식이 중요하다. 일반적으로 데스크톱 애플리케이션은 상당히 빠르고 (컴퓨터 상에서 실행되고 인터넷 상에서 대기 중인 상태가 안 나온다.), 대형 사용자 인터페이스(일반적으로 운영체제와 상호작용)를 갖추며 상당히 동적이다. 거의 대기시간 없이 메뉴 및 하위 메뉴를 클릭, 지시, 입력하고 풀업한다.

반면 웹 애플리케이션은 가장 최신 것이며 데스크톱에서는 전혀 얻을 수 없는 서비스를 제공한다.(Amazon.com 및 eBay를 생각해 볼 것.) 하지만 웹 애플리케이션 기능으로 인해 서버 응답 대기, 스크린 재생 대기, Request 컴백 및 새 페이지 생성에 관한 대기 기능 등이 부수된다.

분명 지나친 단순화 과정임에는 틀림없지만 기본 개념은 얻게 된다. 이미 눈치를 챘겠지만 Ajax는 데스크톱 애플리케이션 및 항상 업데이트 되는 웹 애플리케이션의 기능 및 상호작용 간의 차이를 줄여주는 역할을 한다. 여러분은 마치 데스크톱 애플리케이션에서 찾은 것처럼 동적 사용자 인터페이스 및 가상 제어기능을 사용한다. 하지만 웹 애플리케이션 상에서 데스크톱 애플리케이션을 이용할 수 있다. 그러면 대기 중인 것이 무엇인가? Ajax 및 볼품없는 웹 인터페이스가 응답 Ajax 애플리케이션으로 변환되는 과정에 대해 살펴보기로 하자.

그러면 대기 중인 것이 무엇인가? Ajax 및 볼품없는 웹 인터페이스가 응답 Ajax 애플리케이션으로 변환되는 과정에 대해 살펴보기로 하자.

오래된 기술, 새로운 기법

Ajax에 관해 살펴보면 Ajax는 실지로 많은 기술들이 응집되어 있다. Ajax의 기본을 마치고 넘어가려면 몇 가지 다른 기술들(필자는 첫 번째 이 시리즈에서 각각의 기술에 관해 설명할 것이다.)을 면밀히 살펴보아야 한다. 하지만 이들 기술 가운데 어느 정도 알고 있는 것이 많은 건 다행이다. 더군다나 각각의 기술 대부분은 Java/Ruby같은 프로그래밍 언어만큼 어려운 게 아니라서 배우기 쉽다.

Ajax 정의

Ajax는 비동기 JavaScript 및 XML의 약어이다.(DHTML도 마찬가지다.) Adaptive Path사의 Jesse James Garrett이 이 약어를 만들어냈으며(참고자료), Jesse에 따르면 이 약어는 두문자어는 아니라고 한다.

Ajax 애플리케이션에 포함된 기본기술은 다음과 같다.

  • 웹 양식을 구축하고 애플리케이션 완료 때까지 사용되는 필드를 식별하는 데 HTML을 사용한다.
  • 자바 스크립트 코드는 Ajax 애플리케이션을 실행하는 중심 코드며 서버 애플리케이션과의 커뮤니케이션을 용이하게 한다.
  • DHTML(동적 HTML)은 웹 양식을 동적으로 업데이트 한다. div, span및 기타 동적 HTML 요소를 사용해 HTML을 마크업 한다.
  • 서버에서 복귀된 HTML 및 (때로) XML 구조를 다루는 데 있어 DOM, 즉 문서 객체 모델(Document Object Model)을 사용한다.

이 기술들에 대해 간략히 요약하고 각 기술의 기능에 대해 좀 더 알아보기로 하는데 각 기술에 관한 자세한 사항은 차후 글에서 다룰 것이다. 우선은 Ajax의 구성요소 및 기술에 대해 친숙해 지는 데 초점을 맞추기로 한다. 자바 스크립트에 익숙할수록 Ajax에 담긴 기술에 관한 일반적인 지식 단계에서 각 기술에 관한 자세한 지식으로 넘어가는 게 더 쉬워진다.(또한 이로 인해 웹 애플리케이션 개발에 관한 문이 열리게 된다.)

XMLHttpRequest 객체

알고자 하는 객체 중 첫 번째는 아마도 가장 생소한 것이 아닌가 싶다. 그 객체는 일명 XMLHttpRequest인데 자바 스크립트 객체의 일종이며 Listing 1에 나와 있는 것처럼 단순하게 생성된다.


Listing 1. 새로운 XMLHttpRequest 객체 생성
                
<script language="javascript" type="text/javascript">
var xmlHttp = new XMLHttpRequest();
</script>

필자는 다음 글에서 이 객체에 대해 더 논의할 것이다. 하지만 지금 상태에서는 모든 서버 커뮤니케이션을 다루는 객체라는 사실만 알아둔다. 다음 사항으로 가기 전에 잠깐 생각해 보면 자바 스크립트 객체는 XMLHttpRequest를 통해 서버에 전달하는 자바 스크립트 기술의 일종이다. 이 객체는 애플리케이션 흐름이 정상적이지 않으며 Ajax 기술의 많은 부분을 차지하고 있다.

정상적인 웹 애플리케이션에서 사용자는 양식 필드를 기입하며 제출 버튼을 클릭한다. 그러면 전 양식을 서버에 보내며 서버는 처리과정을 통해 양식을 스크립트(일반적으로 PHP, 자바 또는 CGI 과정/이와 유사한 과정)에 전송한다. 스크립트를 실행할 때 스트립트를 통해 완전히 새로운 페이지가 전송된다. 그 페이지는 데이터가 작성된 새로운 양식의 HTML/확인 페이지 또는 원 양식에 기입된 데이터에 근거해 선택된 옵션이 포함된 페이지일 수 있다. 물론, 서버 상의 스크립트/프로그램이 처리되면서 새로운 양식을 다시 보내는 동안 사용자는 대기해야 한다. 서버로부터 데이터를 다시 받을 때까지는 스크린 상에 아무 것도 없게 되며 결국 대화성은 낮게 된다. 사용자는 즉각적으로 응답을 받지 못하며 데스크톱 애플리케이션 상에서 작업하는 기분이 들지 않게 된다.

Ajax는 근본적으로 자바 스크립트 기술 및 웹 양식 및 서버 간의 XMLHttpRequest 객체를 결합한다. 사용자가 웹 양식을 기입할 때 데이터는 직접 서버 스크립트에 전송되지 않고 자바 스크립트 코드에 전달된다. 대신 자바 스크립트 코드는 양식 데이터를 포착해 Request를 서버에 전송한다. 이 과정이 일어나는 동안, 사용자 스크린 상의 양식은 순식간에 나타나거나 깜빡이거나 사라지거나 정지하지 않는다. 즉 자바 스크립트 코드는 몰래 Request를 전송하며 사용자는 Request가 만들어졌는지도 알지 못한다. 게다가 Request를 비동기적으로 전송하기 때문에 더 좋은 상황이 된다. 이는 자바 스크립트에서 서버 응답을 그냥 대기하지 않는다는 것을 의미한다. 따라서, 사용자는 데이터를 계속 기입하고 화면이동하고 애플리케이션을 사용한다.

그런 다음 서버는 자바 스크립트 코드(웹 양식에 대해 아직도 대기 중임)에 데이터를 다시 전송한다. 자바 스크립트 코드에서는 데이터와의 상호기능을 결정하며 연속적으로 양식 필드를 업데이트 하면서 애플리케이션에 즉각적인 응답을 준다. 결국 사용자는 양식을 제출/재생하는 작업 없이 새로운 데이터를 얻게 된다. 자바 스크립트 코드는 데이터를 얻고 계산도 수행하며 또 다른 Request를 전송하며 이런 모든 과정은 사용자 개입 없이도 된다! 이것이 바로 XMLHttpRequest 객체의 장점이다. XMLHttpRequest 객체는 서버와 같이 커뮤니케이션을 주고받고 사용자는 그 과정에서 벌어지는 과정을 알지 못한다. 이로 인해 데스크톱 애플리케이션과 마찬가지로 동적, 상호 반응적인 고도의 양방향 경험을 얻게 되지만 그 속에 인터넷의 모든 장점이 담겨 있다.

자바 스크립트에 대한 부가사항

일단 XMLHttpRequest에 대해 다루게 되면 나머지 자바 스크립트 코드는 상당히 평범한 것들이다. 사실 다음과 같은 기본적인 작업에 자바 스크립트 코드를 이용한다.

  • 양식 데이터 얻기: 자바 스크립트 코드로 HTML 양식에서 데이터를 꺼내 이를 서버에 전송하는 작업이 간단해진다.
  • 양식 상의 값 변환: 필드 값 설정에서 연속적인 이미지 교체작업에 이르는 양식 업데이트 작업 또한 간단하다.
  • HTML 및 XML 구문분석: 자바 스크립트 코드를 이용해 DOM(다음 섹션 참조)을 처리하고 서버에서 다시 전송하는 HTML 양식 및 임의의 XML 데이터에 관한 구조를 다루게 된다.

첫 번째 두 항목에 대해서 여러분은 Listing 2에 나온 대로 getElementById()에 익숙해지려 할 것이다.


Listing 2. 자바 스크립트 코드에서의 필드 값 포착 및 설정
                
// Get the value of the "phone" field and stuff it in a variable called phone
var phone = document.getElementById("phone").value;

// Set some values on a form using an array called response
document.getElementById("order").value = response[0];
document.getElementById("address").value = response[1];

Ajax 애플리케이션에서 특별히 획기적인 사항은 없고 상기 사항 정도면 충분하다. 이에 대해 상당히 복잡한 건 없다는 사실을 깨달아야 한다. 일단 XMLHttpRequest만 정복하면 Ajax 애플리케이션에서 나머지는 대부분 Listing 2에 나온 바와 같이 상당히 독창적인 HTML과 결합된 단순 자바 스크립트 코드다. 그런 다음 가끔 약간의 DOM 작업이 발생하게 된다. 이에 관해 살펴 보자.

DOM으로 종료하기

DOM, 즉 문서 객체 모델이라는 것이 있는데 이는 아주 중요하다. DOM에 대해 듣는 것은 그다지 어렵지 않다고 하는 사람들이 있다. HTML 디자이너에 의해서는 종종 사용되지 않으며 하이-엔드 프로그래밍 작업으로 들어가지 않는 한은 JavaScript 코더에서 흔치 않은 것이 바로 DOM이다. 종종 과중-업무 Java 및 C/C++ 프로그램 상에서 DOM을 종종 많이 활용하게 된다. 사실은 DOM이 배우기 어려운 특성 때문에 명성이 자자해 그 프로그램 상에서 종종 사용하는 것이 아닌가 싶다.

다행히도 JavaScript 기술에 있어 DOM을 활용하는 일은 쉽고 대부분 직관적이다. 이 시점에서 필자는 DOM 사용법에 관해 보여 주고 적어도 이에 대한 몇 가지 코드 예를 제시하려 하지만 이 글의 의도와는 벗어나는 것 같다. DOM에 관해 대략적으로 다루는 것 없이도 Ajax에 대해 깊이 다룰 수 있다. 필자는 차후의 글에서 다시 DOM에 관해 다루려 한다. 하지만 지금 상황에서는 언급하지 않으려 한다. JavaScript 코드와 서버 사이에 XML을 이리저리 전송하고 HTML 양식을 변화시킬 때 DOM에 대해 자세히 다루게 될 것이다. 지금은 DOM없이 효과적인 Ajax 애플리케이션을 작동하는 게 쉬우므로DOM은 논외로 한다.




위로


Request 객체 얻기

Ajax 애플리케이션에 관한 기본적 개념에 대해 배웠으면 몇 가지 특수사항에 대해 살펴 보자. XMLHttpRequest 객체는 Ajax 애플리케이션에서 중요하므로, 아마도 많은 이들에게는 생소한 것일 수도 있다. 거기서 필자는 논의를 시작한다. Listing 1에서 보다시피, XMLHttpRequest 객체를 생성, 사용하는 것은 상당히 쉬워야 한다. 잠깐만 기다려 보시라.

수년 동안 브라우저에 관한 논란은 끊이지 않았고 동일한 브라우저로는 아무 것도 얻을 수 없다는 사실을 기억하는가? 믿건 말건, 소규모 브라우저에서도 이와 같은 논쟁은 끊이지 않고 있다. 더군다나 놀라운 사실은 XMLHttpRequest가 이 논란의 희생양 중 하나라는 것이다. 따라서 XMLHttpRequest 객체를 작동시키기 위해선 몇 가지 다른 작업을 해야 한다. 단계별로 설명하겠다.

Microsoft 브라우저 다루기

Microsoft 브라우저, Internet Explorer는 XML을 다룰 시 MSXML 구문분석계를 사용한다.(참고자료) Internet Explorer 상에서 다뤄야 할 Ajax 애플리케이션을 작성할 시 독특한 방식으로 XMLHttpRequest 객체를 작성해야 한다.

하지만 그렇게 간단한 작업은 아니다. Internet Explorer에 설치된 JavaScript 기술 버전에 따라 MSXML 버전도 변하게 되며 실지로 2개의 버전이 있다. 따라서 두 경우를 다루는 코드를 작성해야 한다. Microsoft 브라우저 상에서 XMLHttpRequest 객체를 생성하는 데 필요한 코드에 관해선 Listing 3을 보라.


Listing 3. Microsoft 브라우저 상에서 XMLHttpRequest 객체 생성
                
var xmlHttp = false;
try {
  xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
  try {
    xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
  } catch (e2) {
    xmlHttp = false;
  }
}

모든 작업이 정확히 맞아떨어지는 것은 아니다. 하지만 그래도 상관없다. 이 시리즈가 끝나기 전에 JavaScript 프로그래밍, 에러 취급 및 조건부 번역 및 기타 사항에 관해 자세히 다루게 될 것이다. 지금 현 상태에서는 두 가지 중심 라인만 다루고자 한다.

xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");

and

xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");.

간단히 말해서, 이 코드로 MSXML의 한 버전을 이용해 XMLHttpRequest 객체 생성을 기한다. 하지만 객체가 생성되지 않는 경우 다른 버전을 사용해 XMLHttpRequest 객체를 생성한다. 두 코드 다 작동되지 않는 경우 xmlHttp 변수는 거짓으로 설정되고 작동되지 않는 것이 있다는 것을 코드에 알려 준다. 그럴 경우, 비-Microsoft 브라우저가 있을 가능성이 있다. 따라서 객체 생성을 위해선 다른 코드를 사용해야 한다.

Mozilla 및 Microsoft 브라우저 다루기

인터넷 브라우저를 선택하지 않거나 비-Microsoft 브라우저를 작성할 경우 다른 코드가 필요하다. 사실, 이 라인은 Listing 1에서 봤던 단순 코드라인이다.

var xmlHttp = new XMLHttpRequest object;.

이 단순한 라인으로 Mozilla, Firefox, Safari, Opera 및 임의의 양식/형태에서 Ajax애플리케이션을 지원하는 기타 비-Microsoft 브라우저에서 XMLHttpRequest 객체를 생성한다.

지원기능 통합

여기서 모든 브라우저를 지원하는 것이 중요하다. Internet Explorer/비-Microsoft 브라우저에서만 작동되는 애플리케이션을 작성하는 사람이 어디 있겠는가? 또한 더 심한 경우, 애플리케이션을 두 번 작성하고자 하는가? 물론 아니라고 믿는다. 따라서 코드에선 Internet Explorer 및 비-Microsoft 브라우저를 지원하는 기능이 포함되어야 한다. Listing 4에서는 다중-브라우저 방식으로 작동하는 코드에 대해 나와 있다.


Listing 4. 다중 브라우저 방식으로 XMLHttpRequest 객체 생성하기
                
/* Create a new XMLHttpRequest object to talk to the Web server */
var xmlHttp = false;
/*@cc_on @*/
/*@if (@_jscript_version >= 5)
try {
  xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
  try {
    xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
  } catch (e2) {
    xmlHttp = false;
  }
}
@end @*/

if (!xmlHttp && typeof XMLHttpRequest != 'undefined') {
  xmlHttp = new XMLHttpRequest();
}

지금 현재로선, 주석 및 @cc_on와 같은 어려운 태그를 무시한다. 이들은 다음 글에서 깊이 다룰 JavaScript 컴파일러 명령으로 오로지 XMLHttpRequest 객체 상에만 초점이 맞추어져 있다. 이 코드에 관한 핵심은 세 가지 과정으로 요약된다.

  1. 변수 xmlHttp를 생성해 앞으로 생성할 XMLHttpRequest 객체를 참조한다.
  2. Microsoft 브라우저에서의 객체를 시도, 생성한다.
    • Msxml2.XMLHTTP 객체를 사용해 XMLHttpRequest 객체를 시도, 생성한다.
    • 과정이 실패할 경우, Microsoft.XMLHTTP 객체를 사용해 XMLHttpRequest 객체를 시도, 생성한다.
  3. xmlHttp가 아직도 설정되지 않은 경우 비-Microsoft 방식으로 XMLHttpRequest 객체를 생성한다.

위 과정 끝 단계 시 사용자가 실행하는 브라우저 종류에 관계없이 xmlHttp의 경우 유효한 XMLHttpRequest 객체를 인용한다.

보안

보안이란 무엇인가? 오늘날 브라우저는 사용자들에게 보안 레벨을 올리고 JavaScript 기술을 생성하며 브라우저 옵션을 해제하는 기능을 제공한다. 이 경우 코드가 작동되지 않는 경우도 있을 수 있다. 그 때 발생하는 문제를 적절하게 다뤄야 한다. 이에 관한 내용은 적어도 기사 한 분량을 차지할 정도라 나중에 다루기로 하겠다.(긴 시리즈가 될 것 같다, 그렇지 않은가? 하지만 걱정 마시라. 과정을 다 배우고 나면 이와 관련된 모든 사항을 숙달할 테니까.) 현재로선 강력하지만 완전하지 않은 코드를 작성하는 중이다. 이 코드는 Ajax 애플리케이션을 관리하는 데 좋다.




위로


Ajax 세계에서의 Request/Response

인제 Ajax 애플리케이션에 대해 이해하고 XMLHttpRequest 객체 및 객체 생성에 관한 기본적인 개념을 얻는다. 자세히 읽다 보면 Ajax 애플리케이션은 웹 애플리케이션에 제출되는 HTML 양식보단 서버 상의 임의의 웹 애플리케이션에 대화하는 JavaScript 기술이라는 사실을 알게 된다.

그러면 빠진 부분은 어떤 것인가? 실질적인 XMLHttpRequest 객체 사용법이다. 이 객체는 작성하는 각각의 Ajax 애플리케이션에서 일정 형태로 사용하는 중요 코드라 Ajax 애플리케이션이 포함된 기본 Request/응답 모델 모양을 통해 객체 사용법을 빨리 익힌다.

Request 만들기

새로운 XMLHttpRequest 객체가 있는 경우 이를 시험해 보자. 먼저 웹 페이지에서 호출하는 JavaScript 방법이 필요하다.(사용자가 텍스트에서 입력하거나 메뉴에서 옵션을 선택할 시와 같음.) 그 다음, 거의 모든 Ajax 애플리케이션에서의 동일한 기본 아웃라인을 따른다.

  1. 웹 양식으로부터 필요한 모든 데이터 얻기
  2. 연결할 URL 구축
  3. 서버 연결
  4. 서버 실행 종료 시 서버 실행 기능 설정
  5. Request 전송

Listing 5는 위의 순서대로 5단계를 진행하는 Ajax 방법의 예에 관해 나와 있다.


Listing 5. Ajax가 포함된 Request 만들기
                
function callServer() {
  // Get the city and state from the web form
  var city = document.getElementById("city").value;
  var state = document.getElementById("state").value;
  // Only go on if there are values for both fields
  if ((city == null) || (city == "")) return;
  if ((state == null) || (state == "")) return;

  // Build the URL to connect to
  var url = "/scripts/getZipCode.php?city=" + escape(city) + "&state=" + escape(state);

  // Open a connection to the server
  xmlHttp.open("GET", url, true);

  // Setup a function for the server to run when it's done
  xmlHttp.onreadystatechange = updatePage;

  // Send the request
  xmlHttp.send(null);
}

Ajax 코드에 관한 많은 것이 명백하다. Ajax 코드의 첫번째 비트는 몇 가지 양식 필드 값을 포착하는 기본 JavaScript 코드를 사용한다. 그런 다음 이 코드에서는 연결 최종 목적지로 PHP 스크립트를 설정한다.

PHP 스크립트의 URL을 지정한 다음(양식에서 나온) 단순한 GET 매개변수를 이용해 이 URL에 도시 및 국가를 추가한다. 그 다음 연결하면 먼저 XMLHttpRequest 객체가 작동되는 것을 보게 된다. 연결방법은 연결 URL 뿐만 아니라, GET 매개변수에도 나와 있다. 최종 매개변수를 true로 설정한 경우, 이 매개변수에선 비동기식 연결(Ajax를 만든다.)을 요구한다. false로 설정한 경우엔 Request를 만들 시 서버 상에서 Ajax에서의 JavaScript 코드가 대기하고 응답을 받을 때 코드가 지속된다. 사용자는 최종 매개변수를 true로 설정하면서 서버에서 배경에 있는 Request를 처리하는 동안 사용자는 웹 양식(심지어는 기타 JavaScript 방식)을 여전히 사용한다.

한편 xmlHttp(이것은 XMLHttpRequest 객체의 인스턴스라는 사실을 기억하라.)의 onreadystatechange 속성으로 서버 실행이 종료될 시(5분/5시간 내에 종료될 수 있음) 서버 기능을 명령한다. 이 코드는 서버 상에서 대기하지 않기 때문에 서버가 기능을 인식해 서버에 응답할 수 있도록 하는 게 필요하다. 이 경우 서버에서 Request를 처리하면서 종료 시 이른바 updatePage()라 불리는 특수 방법을 트리거한다.

최종적으로 send() 코드를 0(null) 값으로 호출한다. 데이터를 추가해 이를 서버에 전송하므로 Request에는 추가해서 보낼 게 없다. 이렇게 되면 Request를 발송하고 서버는 서버에 요구된 기능을 실행한다.

이 코드에서 나오는 것이 없는 경우, 코드가 상당히 간단하다는 것을 명심하라. 이 코드는 Ajax 애플리케이션의 비동기적 특성을 제외하고는 상당히 단순하다. 이 코드를 통해 복잡한 HTTP Request/응답 코드보다는 근사한 애플리케이션 및 인터페이스에 완전 초점을 맞추도록 한다는 사실을 여러분은 높게 평가할 것이다.

Listing 5의 코드는 코드를 얻는 방법만큼이나 쉽다. 데이터는 단순 텍스트이고 Request URL의 일부로 포함된다. GET 매개변수는 더 복잡한 POST대신 Request를 전송한다. 여기에 덧붙일 XML/컨텐츠 헤더가 없고 Request 본체에 전송할 데이터도 없다. 이게 바로 Ajax 유토피아다.

그렇다고 미리 겁먹지 마라. 시리즈가 계속될수록 문제는 더 복잡해진다. 그 때는 POST Request를 전송하는 방법, Request 헤더 및 컨텐츠 형식을 설정하는 방법, 메시지에 XML을 설정하는 방법 및 Request에 보안기능을 추가하는 방법을 배우게 되는데 배우는 목록만 해도 상당히 길다! 지금은 이런 어려운 주제에 대해 신경 쓰지 말자! 그냥 기본만 충실하게 익히면 Ajax 전체 툴을 구축하게 된다.

응답 취급과정

이제 서버 응답을 실지로 취급해야 한다. 이 시점에서는 정말로 두 가지 사항만 알면 된다.

  • xmlHttp.readyState 속성이 4와 같을 때까지는 어떤 작업도 해선 안 된다.
  • 서버는 xmlHttp.responseText 속성에 응답한다.

2가지 항목 중 첫번째 항목인 준비 상태에 관해선 다음 글에서 대부분 다룰 것이다. 그 때는 HTTP Request 단계에 대해 알고 싶은 것 이상으로 배우게 된다. 지금 현재로선, xmlHttp.responseText 속성 값 4를 단순 점검하는 경우, 작업이 계속 진행된다.(다음 글에서 기대할 만한 사항이 나오게 된다.) 서버 응답을 얻기 위해 xmlHttp.readyState 속성을 사용하는 과정인 두 번째 항목은 쉽다. Listing 6Listing 5에서 전송된 값에 근거해 서버에서 호출하는 방법에 관한 예를 보여준다.


Listing 6. 서버 응답 취급하기
                
function updatePage() {
  if (xmlHttp.readyState == 4) {
    var response = xmlHttp.responseText;
    document.getElementById("zipCode").value = response;
  }
}

다시 보면, xmlHttp.readyState 코드는 그리 어렵거나 복잡하지 않다. 이 코드는 서버에서 해당 준비 상태로의 호출을 대기하고 서버에서 다시 복귀되는 값(이 경우, 사용자 기입 도시 및 국가에 대한 ZIP 코드)을 사용해 또 다른 형태의 양식 필드를 설정한다. 그 결과, zipCode 필드는 ZIP 코드와 함께 갑자기 나타난다. 하지만 사용자는 버튼을 클릭해서는 안 된다! 그게 바로 이전에 말했던 데스크톱 애플리케이션이다. Ajax 코드에는 응답성, 동적 상태 외의 더 많은 것이 있다. 독자들은 zipCode가 정상 텍스트 필드라는 것을 눈치챘을지도 모른다.

일단 서버에서 zipCode를 복귀시키고 updatePage() 방식으로 도시/국가 ZIP 코드와 함께 zipCode 필드 값을 설정하는 경우 사용자는 값을 무효로 한다. 값을 무효로 하는 데는 두 가지 이유가 있다. 예에서 나오는 상황을 단순화시키고, 때로는 사용자가 서버에서 명령하는 것을 무효로 하기 위해서다. 이 두 가지를 명심하라. 좋은 사용자-인터페이스 설계를 위해 중요하다.




위로


웹 양식 다루기

그러면 이 글에서 다룰 게 남아 있는가? 그다지 많지 않다. 양식에 기입할 정보를 포착해 이를 서버에 전송하고 응답에 관해 취급할 또 다른 JavaScript 방법을 제공하면서 심지어는 다시 응답될 때 필드 값을 설정하기까지 하는 JavaScript 방법을 다룬다. 여기서는 첫번째 JavaScript 방법을 호출해 전 과정을 시작하기만 하면 된다. 분명 HTTL 양식에 버튼을 추가하지만 2001년 버전과 거의 동일하다고 생각되지 않는가? Listing 7과 같이 JavaScript 기술을 활용한다.


Listing 7. Ajax 프로세스 시작
                
<form>
 <p>City: <input type="text" name="city" id="city" size="25" 
       onChange="callServer();" /></p>
 <p>State: <input type="text" name="state" id="state" size="25" 
       onChange="callServer();" /></p>
 <p>Zip Code: <input type="text" name="zipCode" id="zipCode" size="5" /></p>
</form>

이런 단면이 루틴 코드의 한 단면 이상을 보여준다고 생각된다면 맞는 말이다. – 그렇다! 사용자가 도시/국가 필드에 관한 새로운 값을 입력할 경우 callServer() 방식을 전송한 다음 Ajax 애플리케이션이 시작된다. 이제 여러 상황을 다룰 만하다고 느껴지기 시작하는가? 좋다! 바로 그거다!




위로


맺음말

소셜 북마크

mar.gar.in mar.gar.in
digg Digg
del.icio.us del.icio.us
Slashdot Slashdot

이 시점에서 적어도 리소스 란에서 Ajax 애플리케이션에 관해 깊숙이 알려고 하는 경우, 첫번째 Ajax 애플리케이션을 작성할 준비가 되어 있지 않을 게다. 하지만 이런 애플리케이션이 작동하는 기본 개념 및 XMLHttpRequest 객체의 기본 개념을 이해하기 시작한 경우 이 객체, JavaScript-서버 간 대화 취급방식, HTML 양식 취급 및 심지어 DOM 관리 방식까지 모든 것을 배워야 한다.

지금 현재로선, Ajax 애플리케이션이 얼마나 강력한 툴인지 생각하는 데 시간을 보낸다. 버튼만 클릭할 뿐만 아니라 필드에 입력하고 콤보 상자에서 옵션을 선택하고 심지어는 마우스를 스크린 주위에 끄는 경우 응답하는 웹 형식을 상상해 본다. 비동기식의 정확한 의미 및 Request 상에서 응답하기 위해 서버 상에서 실행하지만 대기하지 않는 JavaScript 코드에 관해 생각해 본다. 여러분이 부딪치는 문제의 종류는 어떤 것인가? 어떤 영역의 문제에 주의를 기울일 것인가? 프로그래밍에 이 새로운 접근방식을 설명하기 위해 양식 설계를 변환하는 방법은 어떤 것인가?

이런 문제에 관해 실지로 생각할 시간을 보낸다면 잘라 붙이는 코드를 가지고 이를 잘 이해하지 못하는 애플리케이션에 포함시키는 것보다는 훨씬 더 낫다. 다음 글에서는 이와 같은 개념을 실제 작업에 응용해 본 작업에서처럼 애플리케이션을 만들어야 하는 코드에 관한 자세한 정보를 제공하기로 한다. 그 때까지 Ajax 애플리케이션의 가능성을 마음껏 즐겨라.

기사의 원문보기



참고자료

교육

토론


필자소개

Photo of Brett McLaughlin

Brett McLaughin은 Logo 시절부터 컴퓨터 업계에서 일했다 (작은 트라이앵글 기억하는가?). 최근에 그는 Java 및 XML 커뮤니티에서 인기 저자 및 프로그래머가 되었다. Nextel Communication사에서는 복잡한 기업 시스템 실행에 관한 업무, Lutris Technologies 사에선 애플리케이션 서버를 실지로 작성하는 업무, 최근 O’Reilly Media 사에서는 이와 관련된 중요한 책을 저술, 편집했다. Brett의 최근 저서인 Head Rush Ajax는 Ajax에 관한 혁신적인 연구에 기여, 공동 저자인 Eric 및 Beth Freeman과 함께 공동으로 수상했다. 그의 최근 저서인 Java 1.5 Tiger: A Developer's Notebook은 신 자바 기술 버전 상에서 이용 가능한 첫 번째 저서다. Brett의 최신 Java 및 XML은 자바 언어에서 XML 기술을 활용한 명백한 업적 중 하나로 남아 있다.


Posted by 1010
06.Ajax2008. 7. 8. 18:12
반응형

AJAX : A Basic Example and a Bookmarklet
Okay now what you all been waiting for: my example on AJAX. Waring: I am not going to go into extreme detail; you can get Dave Crane’s and my book (AJAX in Action) for that when it comes out later this year. First lets see an example of AJAX working right here under our noses.

Now everyone in a JavaScript world says. How can I protect my pages with a username and password without a server side language? Well it can not be done, but you can make it hard to find your content. In this example below you can see a textbox, a password box and the wonderful submit button. Try entering in a username and password.

User Name:
Password:  
Error: username and password is not correct!

Look at the source and you will see there is no username and password. Instead we are using the username and password field to see if the file exists. With AJAX, we look to see if this file is there. If it is, we go there, if not we get the error. Well I am sure you want to see the location so the username is Eric and the password is pass. Now you are able to go there and see my message.

So what is the code to do this? Well now we all know the fun we have coding JavaScript, nothing works the same for different browsers. With IE we need to use ActiveX to do it. Mozilla has there own method to do it.

First we have two things. We have the code that does the request, and then we have a function that handles the returned data. If you are using one of those libraries, you may not have seen this, so open up your eyes wide. Now I am just going to explain the code with comments. (Yeah that is cheating compared to my normal discussion style here on my blog, but I am trying to write a book you know!)

<html>
  <head>
    <script type="text/javascript">

      //We need a wonderful global variables to hold our request object!
      //So we can pass it around.
      var reqXML;
      //We need to have a global variable to hold the url.
      //It keeps us from having to repeat code!
      var url;

      //Create our function to start the request
      function VerifyLogin(){

        //inform there is an action!
        document.getElementById("spanLog").innerHTML = "<span style='color:green'> Checking Information</span>";

        //Grab our form field values
        var strName = document.Form1.username.value;
        var strPass = document.Form1.password.value;
        
        //Make the URL for the request
        url = "http://radio.javaranch.com/pascarello/files/" + strName + strPass + ".html";

        //determine if the browser is Moz, FF, NN, Op
        if (window.XMLHttpRequest){ 
          reqXML = new XMLHttpRequest();            //set the request
          reqXML.onreadystatechange = LoginUser;    //function to call on each set
          reqXML.open("GET", url, true);            //set the page to request
          reqXML.send(null);                        //initialize the request 
        }
        //ActiveX - can we say IE?
        else if(window.ActiveXObject){ 
          //Create our RequestObject
          reqXML = new ActiveXObject("Microsoft.XMLHTTP"); 
          if(reqXML){ 
            reqXML.onreadystatechange = LoginUser  //function to call on each step
            reqXML.open("GET", url, true);         //set the page to request
            reqXML.send(null);                     //initialize the request
          }
        }
        else{  //I do not support this so I need to do something!
           window.location.href = url;
        }       
      }
          
      function LoginUser(){

        //Look to see if the request is in the 4th stage (complete)         
        if(reqXML.readyState == 4){
          //Make sure that we get a sucess page status   
          if(reqXML.status == 200){
            //change our location
            window.location.href = url;
          }
          //For all of the wrong error pages here
          else{
            document.getElementById("spanLog").innerHTML = "<span style='color:red'> Error: username and password is not correct!</span>";
          }
        }
      }
    </script>
  </head>
  <body>
    <form name="Form1" onsubmit="VerifyLogin();return false;">
      <span style="font-family:courier">User Name: </span><input type="text" name="username"><br/>
      <span style="font-family:courier">Password:  </span><input type="password" name="password"><br/>
      <input type="submit" name="btnSub" value="Login" style="font-family:courier">
    </form>
  </body>
</html>

Now I added the event handler to the form to allow us to submit it, I did not think that needed a comment! Now you may be wondering what some things actually mean.

Now the XMLHttpRequest Object has an event handler onreadystatechange that we set to call LoginUser. Now when the XMLHttpRequest is executed we go through 5 stages:

  • 0 - un-initialized
  • 1 - loading
  • 2 - loaded
  • 3 - interactive
  • 4 - complete

We also need to check the status of the document that has been returned. We are looking for a status code of 200 since that means success! We do not want to see that 404 error!

I know I just went over this fast, but you can get more details in AJAX in Action when it comes out. But you may be saying why would I ever want to use this? Well with some minor changes, creating a JS file, and creating a bookmarklet, we can make a very very very very (did I say very) useful tool for a web master that has to check pages to see if all of the links are correct.

Let’s try this out then I will give you the source code. The first step is create a bookmarklet. Take the link below, right click on it, and save it as a bookmark. Agree to the security warning because the link is a JavaScript statement that executes some code. You will be shown the code for the bookmark on the example page.

Verify Links!

After you bookmarked that link above, you need to do open up this link below, go to your bookmarks/favorites and select the one that you just saved. It will then got through all of the links and verify them if they are good or bad. Good is marked in green and bad are marked in red! Give this code to your webmaster!

The test page for you.

There are good and bad links for you!

Now have you seen anyone else use AJAX like this? I do not think so. Hopefully you can see why AJAX is not hype. You can make it do things that you can run from a command in your bookmarks! Now below is the source code so you can save it to your server. Change the bookmark to point to where you saved this document.

      //Set those global variables!
      var reqXML;
      var url;
      var arrLinks;
      var intErrors = 0;
      var currentLink = 0; //We need a counter!
      var timeOutTimer;
      var maxWaitTime = 10000; //Milliseconds!
      var strErrColor = "red";
      var strValidColor = "green";

      function TestThatLink(){
        window.status = "testing: " + url.href;
        timeOutTimer = setTimeout("reqXML='';intErrors++;FinishRequest('" + strErrColor + "');",maxWaitTime);
        try {
	  if (netscape.security.PrivilegeManager.enablePrivilege) {
		netscape.security.PrivilegeManager.enablePrivilege('UniversalBrowserRead');
	  }
        }
        catch (ex) { // eat it
        }
        if (window.XMLHttpRequest){ 
          reqXML = new XMLHttpRequest(); 
          reqXML.onreadystatechange = TestLink;
          reqXML.open("GET", url.href, true); 
          reqXML.send(null);
        }
        else if(window.ActiveXObject){ 
          reqXML = new ActiveXObject("Microsoft.XMLHTTP"); 
          if(reqXML){ 
            reqXML.onreadystatechange = TestLink;
            reqXML.open("GET", url.href, true); 
            reqXML.send(); 
          } 
        }
        else{
          alert("Test browser does not support this!");
        }       
      }
          
      function TestLink(){         
        try {
	  if (netscape.security.PrivilegeManager.enablePrivilege) {
		netscape.security.PrivilegeManager.enablePrivilege('UniversalBrowserRead');
	  }
        } 
        catch (ex) { // eat it
        }
        if(reqXML.readyState == 4){
          window.clearTimeout(timeOutTimer);
          try {
          if(reqXML.status == 200){
            strColor = strValidColor; 
          }
          else{
            strColor = strErrColor;
            intErrors++;
          }
          }
          catch(ex){
            strColor = strErrColor;
            intErrors++;
          }

          FinishRequest(strColor);
        }
      }

      function FinishRequest(xColor){
        window.clearTimeout(timeOutTimer);
        url.style.backgroundColor = xColor;
        currentLink++;
        if(arrLinks.length > currentLink){
          url = arrLinks[currentLink];
          TestThatLink();
        }
        else{
          alert(intErrors + " broken link(s) were found!");
          window.status = "done";
        }
      }

      arrLinks = document.links;  //Grab those Links
      url = arrLinks[currentLink];  //Get the link

      TestThatLink()

Hopefully you can understand what is going on in the code. We are grabbing all of the links, checking to see if they exist, and showing the result on the page. See AJAX does not need to use server side code like everyone says! If you want to understand more about this code, ask away in the comments in this page. (If I do not answer, it is because I am sitting on the beach!)

Now it is Friday, so I think we need to put your brain to rest until Monday where we will talk about AJAX with server side code! But if you want to see a Moderator’s game that uses AJAX, take a look at Bear’s Blackbox here: Blackbox. Or you can sit back and play my JavaScript game (no AJAX) until my bandwidth is used up: Reversi.



Eric Pascarello
Moderator of HTML/JavaScript at www.JavaRanch.com
Author of: JavaScript: Your Visual Blueprint for Dynamic Web Pages

Posted by 1010
06.Ajax2008. 7. 8. 18:09
반응형

AJAX EXAMPLE CODES / DEMO'S

  1. Ajallerix : AJAX, simple, fast Web image gallery demo ; at Novell
  2. AJAX - microlink pattern tutorial : A microlink is a link that opens up content below it.
  3. Ajax BBC News RSS Reader : demo by Nigel Crawley
  4. AJAX Chat in Python with Dojo : at AquaAjax
  5. Ajax Chess : multiplayer chess
  6. Ajax examples at BackBase : examples demonstrating several aspects of the Backbase technology.
  7. Ajax examples at Rico : Inner HTML, JavaScript updater etc.
  8. Ajax examples using ColdFusionMX, SQLServer, SOAP : Contact Manager, NOAA 7 Day Forecast code and demos.
  9. Ajax Feed TV : News feed
  10. Ajax inline dictionary : Highlight any text on this site then right click. A tooltip containing the definition of the selected word should show up.
  11. Ajaxload : Ajax loading gif generator.
  12. Ajax Login Demo : Creating a secure login system using XMLHttpRequest
  13. Ajax Newsletter Signup : A newsletter signup form that shows Thank You on the same page.
  14. ajaxProject : Project Management applicaiton with rich UI
  15. Ajax Rater : A star rating system that uses Ajax.
  16. AJAX-S : An Ajax-based slideshow system.
  17. AJAX Spell Checker : spell check text / form content.
  18. Ajax Toolbox : Tools for the Ajax Developer
  19. Amazon Catalog Tree : Amazon Catalog Tree
  20. Amazon Zuggest : Amazon product suggestion (like google suggest)
  21. Askeet by symfony : Digg-like AJAX interactions; open source
  22. Backbase - Ajax Demos : Ajax demos at BackBase
  23. Basic Ajax Examples : Ping, track changes, drop down, Google suggest hack etc at Clearnova
  24. Behaviour : Fading lists, Sortable lists, Dropout boxen, Shaky lists
  25. chat.app : ajax chat
  26. Chihuahua Word Puzzle : daily word puzzles
  27. Coloir : Ajax Slideshow
  28. DHTML arcade/action games : a collection that demonstrate the power of DHTML
  29. DomAPI : Windows Desktop, Outlook-like, RSS Reader
  30. Drag and Drop Shopping Cart Demo : at CyberDummy
  31. Easy AJAX inline text edit 2.0 : edit a piece of text inline
  32. FileChucker : File upload and progress bar at Encodable.com
  33. Gmail Style Check Username AJAX Demo : at CyberDummy
  34. Google Web Toolkit Example Projects : Hello World, Dynamic Table, Desktop App Clone etc
  35. GreyBox : Pop up window using idea of light box.
  36. FiftyFourEleven: Ajax Examples
  37. IntuiCat - ajax Catalogue : Ajax-based Catalogue Demo
  38. jsLINB programming demos : LINB(Lazy INternet and Browser)
  39. JSlog : Ajax logging tool.
  40. JS/UIX Unix Shell : JS/UIX is an UN*X-like OS for standard web-browsers, written entirely in JavaScript.
  41. Lace : free web chat application
  42. Lightbox : simple, unobtrusive script used to overlay images on the current page.
  43. Leightbox : Light Box with inline div’s instead of AJAX calls.
  44. Live Quote Demo : Simple way of creating an updating stock quote table in ajax.
  45. Magnetic Poetry : drag and drop poetry
  46. Metatron Chat Engine : PHP/MySQL/JavaScript powered chat engine
  47. Monket Calendar : online calendar
  48. Multi List Drag Drop Demo : at CyberDummy
  49. NetDirector : open and extensible framework for managing configurations of common open source network services.
  50. nexImage : Image processing demo
  51. Opera Platform : Enabling AJAX applications on mobile phones
  52. Orbeon examples : various examples illustrating the capabilities of OPS, from the OPS Tutorial examples to XForms examples
  53. OVO Suite : Online Virtual Office : virtual office limited demo
  54. phpFreeChat : php Free Chat
  55. S5: A Simple Standards-Based Slide Show System : S5 is a slide show format based entirely on XHTML, CSS, and JavaScript.
  56. script.aculo.us Reflector : image reflector script that uses uses opacity-based fades
  57. Slider Bar Demo : at CyberDummy
  58. SmallestAjax : Smallest Ajax example in the world?
  59. Spell Check demo : by Primal Grasp
  60. Super Maryo World : Japanese game demo
  61. Tacos : Tacos provides a library of useful Tapestry components. This application provides some examples to get you started.
  62. theList : to-do list / bug-tracker
  63. ThickBox : ThickBox is a Lightbox than can show html pages as well as images.
  64. Tooltip.js : Tooltip.js is a simple class to make it possible to add tooltips to your page.
  65. Treehouse Chat : ajax chat
  66. Tudu Lists : open-source to-do lists
  67. WeBoggle : Ajax Boggle
  68. XHTML live Chat : ajax chat
  69. YahooSearchAsYouType : Yahoo search as you type
  70. ZK Demo : demo programs for various components
Posted by 1010
06.Ajax2008. 7. 8. 17:58
반응형

These examples demonstrate JavaScript used together with XML (AJAX).


Examples Using the XMLHttpRequest Object

Load a textfile into an HTML element with XML HTTP
How to use an XMLHttpRequest to retrieve new content in an HTML element.

Load an XML file with XML HTTP
How to send an XMLHttpRequest to retrieve data when the user clicks a button.

Make a HEAD request with XML HTTP
How to send an XMLHttpRequest to retrieve HTML header data.

Make a specified HEAD request with XML HTTP
How to send an XMLHttpRequest to retrieve a specific part of the HTML header data.

Display an XML file as an HTML table
How to display an XML file as an HTML table

Examples Explained


Using XMLHttp when user types in an input field:

Online communication with server while typing input using XML HTTP

Example Explained

Posted by 1010
06.Ajax2008. 7. 8. 17:57
반응형

While responseText returns the HTTP response as a string, responseXML returns the response as XML.

The ResponseXML property returns an XML document object, which can be examined and parsed using W3C DOM node tree methods and properties.


AJAX ResponseXML Example

In the following AJAX example we will demonstrate how a web page can fetch information from a database using AJAX technology. The selected data from the database will this time be converted to an XML document, and then we will use the DOM to extract the values to be displayed.


Select a Name in the Box Below

Select a Customer:





AJAX Example Explained

The example above contains an HTML form, several <span> elements to hold the returned data, and a link to a JavaScript:

<html>
<head>
<script src="selectcustomer_xml.js"></script>
</head>
<body>
<form action=""> 
Select a Customer:
<select name="customers" onchange="showCustomer(this.value)">
<option value="ALFKI">Alfreds Futterkiste</option>
<option value="NORTS ">North/South</option>
<option value="WOLZA">Wolski Zajazd</option>
</select>
</form>
<b><span id="companyname"></span></b><br />
<span id="contactname"></span><br />
<span id="address"></span>
<span id="city"></span><br/>
<span id="country"></span>
</body>
</html>

The example above contains an HTML form with a drop down box called "customers".

When the user selects a customer in the dropdown box, a function called "showCustomer()" is executed. The execution of the function is triggered by the "onchange" event. In other words: Each time the user change the value in the drop down box, the function showCustomer() is called.

The JavaScript code is listed below.


The AJAX JavaScript

This is the JavaScript code stored in the file "selectcustomer_xml.js":

var xmlHttp
function showCustomer(str)
{ 
xmlHttp=GetXmlHttpObject();
if (xmlHttp==null)
  {
  alert ("Your browser does not support AJAX!");
  return;
  }
var url="getcustomer_xml.asp";
url=url+"?q="+str;
url=url+"&sid="+Math.random();
xmlHttp.onreadystatechange=stateChanged;
xmlHttp.open("GET",url,true);
xmlHttp.send(null);
}
function stateChanged() 
{ 
if (xmlHttp.readyState==4)
{
var xmlDoc=xmlHttp.responseXML.documentElement;
document.getElementById("companyname").innerHTML=
xmlDoc.getElementsByTagName("compname")[0].childNodes[0].nodeValue;
document.getElementById("contactname").innerHTML=
xmlDoc.getElementsByTagName("contname")[0].childNodes[0].nodeValue;
document.getElementById("address").innerHTML=
xmlDoc.getElementsByTagName("address")[0].childNodes[0].nodeValue;
document.getElementById("city").innerHTML=
xmlDoc.getElementsByTagName("city")[0].childNodes[0].nodeValue;
document.getElementById("country").innerHTML=
xmlDoc.getElementsByTagName("country")[0].childNodes[0].nodeValue;
}
}

function GetXmlHttpObject()
{
var xmlHttp=null;
try
  {
  // Firefox, Opera 8.0+, Safari
  xmlHttp=new XMLHttpRequest();
  }
catch (e)
  {
  // Internet Explorer
  try
    {
    xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");
    }
  catch (e)
    {
    xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
    }
  }
return xmlHttp;
}

The showCustomer() and GetXmlHttpObject() functions above are the same as in previous chapters. The stateChanged() function is also used earlier in this tutorial, however; this time we return the result as an XML document (with responseXML) and uses the DOM to extract the values we want to be displayed.


The AJAX Server Page

The server page called by the JavaScript, is a simple ASP file called "getcustomer_xml.asp".

The page is written in VBScript for an Internet Information Server (IIS). It could easily be rewritten in PHP, or some other server language. Look at a corresponding example in PHP.

The code runs an SQL query against a database and returns the result as an XML document:

<%
response.expires=-1
response.contenttype="text/xml"
sql="SELECT * FROM CUSTOMERS "
sql=sql & " WHERE CUSTOMERID='" & request.querystring("q") & "'"

on error resume next
set conn=Server.CreateObject("ADODB.Connection")
conn.Provider="Microsoft.Jet.OLEDB.4.0"
conn.Open(Server.Mappath("/db/northwind.mdb"))
set rs=Server.CreateObject("ADODB.recordset")
rs.Open sql, conn
if err <> 0 then
response.write(err.description)
set rs=nothing
set conn=nothing
else
response.write("<?xml version='1.0' encoding='ISO-8859-1'?>")
response.write("<company>")
response.write("<compname>" &rs.fields("companyname")& "</compname>")
response.write("<contname>" &rs.fields("contactname")& "</contname>")
response.write("<address>" &rs.fields("address")& "</address>")
response.write("<city>" &rs.fields("city")& "</city>")
response.write("<country>" &rs.fields("country")& "</country>")
response.write("</company>")
end if
on error goto 0
%>

Notice the second line in the ASP code above: response.contenttype="text/xml". The ContentType property sets the HTTP content type for the response object. The default value for this property is "text/html". This time we want the content type to be XML.

Then we select data from the database, and builds an XML document with the data.

Posted by 1010
06.Ajax2008. 7. 8. 17:56
반응형

AJAX can be used for interactive communication with a database.


AJAX Database Example

In the AJAX example below we will demonstrate how a web page can fetch information from a database using AJAX technology.


Select a Name in the Box Below

Select a Customer:
Customer info will be listed here.

AJAX Example Explained

The example above contains a simple HTML form and a link to a JavaScript:

<html>
<head>
<script src="selectcustomer.js"></script>
</head>
<body>
<form> 
Select a Customer:
<select name="customers" onchange="showCustomer(this.value)">
<option value="ALFKI">Alfreds Futterkiste
<option value="NORTS ">North/South
<option value="WOLZA">Wolski Zajazd 
</select>
</form>
<p>
<div id="txtHint"><b>Customer info will be listed here.</b></div>
</p>
</body>
</html>

As you can see it is just a simple HTML form with a drop down box called "customers".

The paragraph below the form contains a div called "txtHint". The div is used as a placeholder for info retrieved from the web server.

When the user selects data, a function called "showCustomer()" is executed. The execution of the function is triggered by the "onchange" event. In other words: Each time the user change the value in the drop down box, the function showCustomer is called.

The JavaScript code is listed below.


The AJAX JavaScript

This is the JavaScript code stored in the file "selectcustomer.js":

var xmlHttp

function showCustomer(str)
{ 
xmlHttp=GetXmlHttpObject();
if (xmlHttp==null)
  {
  alert ("Your browser does not support AJAX!");
  return;
  } 
var url="getcustomer.asp";
url=url+"?q="+str;
url=url+"&sid="+Math.random();
xmlHttp.onreadystatechange=stateChanged;
xmlHttp.open("GET",url,true);
xmlHttp.send(null);
}

function stateChanged() 
{ 
if (xmlHttp.readyState==4)
{ 
document.getElementById("txtHint").innerHTML=xmlHttp.responseText;
}
}

function GetXmlHttpObject()
{
var xmlHttp=null;
try
  {
  // Firefox, Opera 8.0+, Safari
  xmlHttp=new XMLHttpRequest();
  }
catch (e)
  {
  // Internet Explorer
  try
    {
    xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");
    }
  catch (e)
    {
    xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
    }
  }
return xmlHttp;
}


The AJAX Server Page

The server page called by the JavaScript, is a simple ASP file called "getcustomer.asp".

The page is written in VBScript for an Internet Information Server (IIS). It could easily be rewritten in PHP, or some other server language. Look at a corresponding example in PHP.

The code runs an SQL against a database and returns the result as an HTML table:

<%
response.expires=-1
sql="SELECT * FROM CUSTOMERS WHERE CUSTOMERID="
sql=sql & "'" & request.querystring("q") & "'"

set conn=Server.CreateObject("ADODB.Connection")
conn.Provider="Microsoft.Jet.OLEDB.4.0"
conn.Open(Server.Mappath("/db/northwind.mdb"))
set rs = Server.CreateObject("ADODB.recordset")
rs.Open sql, conn

response.write("<table>")
do until rs.EOF
  for each x in rs.Fields
    response.write("<tr><td><b>" & x.name & "</b></td>")
    response.write("<td>" & x.value & "</td></tr>")
  next
  rs.MoveNext
loop

response.write("</table>")
%>
Posted by 1010
06.Ajax2008. 7. 8. 17:56
반응형

AJAX Source Code to Suggest Example

The source code below belongs to the AJAX example on the previous page.

You can copy and paste it, and try it yourself.


The AJAX HTML Page

This is the HTML page. It contains a simple HTML form and a link to a JavaScript.

<html>
<head>
<script src="clienthint.js"></script> 
</head>
<body>
<form> 
First Name:
<input type="text" id="txt1"
onkeyup="showHint(this.value)">
</form>
<p>Suggestions: <span id="txtHint"></span></p> 
</body>
</html>

The JavaScript code is listed below.


The AJAX JavaScript

This is the JavaScript code, stored in the file "clienthint.js":

var xmlHttp

function showHint(str)
{
if (str.length==0)
  { 
  document.getElementById("txtHint").innerHTML="";
  return;
  }
xmlHttp=GetXmlHttpObject();
if (xmlHttp==null)
  {
  alert ("Your browser does not support AJAX!");
  return;
  } 
var url="gethint.asp";
url=url+"?q="+str;
url=url+"&sid="+Math.random();
xmlHttp.onreadystatechange=stateChanged;
xmlHttp.open("GET",url,true);
xmlHttp.send(null);
} 

function stateChanged() 
{ 
if (xmlHttp.readyState==4)
{ 
document.getElementById("txtHint").innerHTML=xmlHttp.responseText;
}
}

function GetXmlHttpObject()
{
var xmlHttp=null;
try
  {
  // Firefox, Opera 8.0+, Safari
  xmlHttp=new XMLHttpRequest();
  }
catch (e)
  {
  // Internet Explorer
  try
    {
    xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");
    }
  catch (e)
    {
    xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
    }
  }
return xmlHttp;
}


The AJAX Server Page - ASP and PHP

There is no such thing as an AJAX server. AJAX pages can be served by any internet server.

The server page called by the JavaScript in the example from the previous chapter is a simple ASP file called "gethint.asp".

Below we have listed two examples of the server page code, one written in ASP and one in PHP.


AJAX ASP Example

The code in the "gethint.asp" page is written in VBScript for an Internet Information Server (IIS). It just checks an array of names and returns the corresponding names to the client:

<%
response.expires=-1
dim a(30)
'Fill up array with names
a(1)="Anna"
a(2)="Brittany"
a(3)="Cinderella"
a(4)="Diana"
a(5)="Eva"
a(6)="Fiona"
a(7)="Gunda"
a(8)="Hege"
a(9)="Inga"
a(10)="Johanna"
a(11)="Kitty"
a(12)="Linda"
a(13)="Nina"
a(14)="Ophelia"
a(15)="Petunia"
a(16)="Amanda"
a(17)="Raquel"
a(18)="Cindy"
a(19)="Doris"
a(20)="Eve"
a(21)="Evita"
a(22)="Sunniva"
a(23)="Tove"
a(24)="Unni"
a(25)="Violet"
a(26)="Liza"
a(27)="Elizabeth"
a(28)="Ellen"
a(29)="Wenche"
a(30)="Vicky"
'get the q parameter from URL
q=ucase(request.querystring("q"))
'lookup all hints from array if length of q>0
if len(q)>0 then
  hint=""
  for i=1 to 30
    if q=ucase(mid(a(i),1,len(q))) then
      if hint="" then
        hint=a(i)
      else
        hint=hint & " , " & a(i)
      end if
    end if
  next
end if
'Output "no suggestion" if no hint were found
'or output the correct values
if hint="" then 
  response.write("no suggestion")
else
  response.write(hint)
end if
%>


AJAX PHP Example

The code above rewritten in PHP.

Note: To run the entire example in PHP, remember to change the value of the url variable in "clienthint.js" from "gethint.asp" to "gethint.php".

PHP Example

<?php
header("Cache-Control: no-cache, must-revalidate");
 // Date in the past
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");

// Fill up array with names
$a[]="Anna";
$a[]="Brittany";
$a[]="Cinderella";
$a[]="Diana";
$a[]="Eva";
$a[]="Fiona";
$a[]="Gunda";
$a[]="Hege";
$a[]="Inga";
$a[]="Johanna";
$a[]="Kitty";
$a[]="Linda";
$a[]="Nina";
$a[]="Ophelia";
$a[]="Petunia";
$a[]="Amanda";
$a[]="Raquel";
$a[]="Cindy";
$a[]="Doris";
$a[]="Eve";
$a[]="Evita";
$a[]="Sunniva";
$a[]="Tove";
$a[]="Unni";
$a[]="Violet";
$a[]="Liza";
$a[]="Elizabeth";
$a[]="Ellen";
$a[]="Wenche";
$a[]="Vicky";
//get the q parameter from URL
$q=$_GET["q"];
//lookup all hints from array if length of q>0
if (strlen($q) > 0)
{
  $hint="";
  for($i=0; $i<count($a); $i++)
  {
  if (strtolower($q)==strtolower(substr($a[$i],0,strlen($q))))
    {
    if ($hint=="")
      {
      $hint=$a[$i];
      }
    else
      {
      $hint=$hint." , ".$a[$i];
      }
    }
  }
}

// Set output to "no suggestion" if no hint were found
// or to the correct values
if ($hint == "")
{
$response="no suggestion";
}
else
{
$response=$hint;
}

//output the response
echo $response;
?>
Posted by 1010
06.Ajax2008. 7. 8. 17:53
반응형

Introduction

This document describes a simple approach of implementing AJAX functionality in ASP.NET web applications. Pros and cons of using AJAX are also discussed. The document contains a working JavaScript and C#.NET code demonstrating the suggested solution.

Why AJAX

Most of you already know that AJAX stands for Asynchronous JavaScript and XML. This technology was introduced first by Microsoft (from my best knowledge) back in 1999, and had been known as “DHTML / JavaScript web application with remote calls”. The whole idea of the technology was to allow an internet browser to make an asynchronous HTTP call to remote pages/services, and update a current web page with the received results without refreshing the whole page. By creators’ opinion, this should have improved customers’ experience, making HTTP pages look and feel very similar to Windows applications.

Because the core implementation of this technology was based on internet browser functionality, the usability was very limited at that time. But several years later, the technology has been reborn with new browsers support and massive implementation by such giants as Google, Amazon.com, eBay, etc.

Today, it’s known as AJAX, and considered as a natural part of any dynamic web page with advanced user experience.

Solution Description

The suggested approach provides a very simple, yet effective implementation of the AJAX functionality. It’s very easy to maintain and change, does not require any special skills from developers, and, from our best knowledge, is cross-browser compatible.

Basically, a regular AJAX-like implementation includes two main components: a client HTML page with JavaScript code making an AJAX call and receiving a response, and a remote page that can accept a request and respond with the required information. The JavaScript code on the client page is responsible for instantiating an XmlHttp object, then providing this object with a callback method which will be responsible for processing the received information, and finally, sending a request to the remote page via the XmlHttp object. All this is done by the JavaScript code.

Our approach is intended for use in ASP.NET applications, and considers the following possible scenarios:

  • AJAX calls may be performed on different ASP.NET pages of the web application to different remote pages;
  • A remote page URL may contain dynamically calculated parameters, and it may be more convenient to build a URL string in the code-behind of the ASP.NET page;
  • A remote page may respond with a complex data requiring parsing before updating an HTML page, that once again may be done in the code-behind of the ASP.NET page;
  • A remote page may be either an external third party page, or the web application’s own page or service.

All these considerations are illustrated by the diagram below:

Solution diagram

Implementation

Basic AJAX JavaScript methods

I divided all the JavaScript methods into two parts: calling page specific JavaScript methods, and AJAX JavaScript methods common for all the calling pages. Specific methods include a callback method as well, as it is responsible for updating the page content. Common AJAX methods are responsible for instantiating an XmlHttp object and sending an asynchronous request to the remote page.

Getting an XmlHttp object differs depending on the type of the browser. I distinguish two basic types: a Microsoft browser which is one of the IE family, and a Mozilla browser which is one of Mozilla Firefox, Netscape, or Safari. I tested the code with the Opera browser too, but I would not guarantee that it will always be working well.

Collapse
function GetXmlHttpObject(handler)
{ 
    var objXmlHttp = null;
    if (!window.XMLHttpRequest)
    {
        // Microsoft
        objXmlHttp = GetMSXmlHttp();
        if (objXmlHttp != null)
        {
            objXmlHttp.onreadystatechange = handler;
        }
    } 
    else
    {
        // Mozilla | Netscape | Safari
        objXmlHttp = new XMLHttpRequest();
        if (objXmlHttp != null)
        {
            objXmlHttp.onload = handler;
            objXmlHttp.onerror = handler;
        }
    } 
    return objXmlHttp; 
} 

function GetMSXmlHttp()
{
    var xmlHttp = null;
    var clsids = ["Msxml2.XMLHTTP.6.0","Msxml2.XMLHTTP.5.0",
                 "Msxml2.XMLHTTP.4.0","Msxml2.XMLHTTP.3.0", 
                 "Msxml2.XMLHTTP.2.6","Microsoft.XMLHTTP.1.0", 
                 "Microsoft.XMLHTTP.1","Microsoft.XMLHTTP"];
    for(var i=0; i<clsids.length && xmlHttp == null; i++) {
        xmlHttp = CreateXmlHttp(clsids[i]);
    }
    return xmlHttp;
}

function CreateXmlHttp(clsid) {
    var xmlHttp = null;
    try {
        xmlHttp = new ActiveXObject(clsid);
        lastclsid = clsid;
        return xmlHttp;
    }
    catch(e) {}
}

According to Umut Alev, the code for the GetMSXmlHttp method can be simplified considering that we do not have to refer MSXML5 as it has been designed only for Office applications. Correspondingly, the simplified revision of the GetMSXmlHttp method may look as follows:

function GetMSXmlHttp() {
    var xmlHttp = null;
    var clsids = ["Msxml2.XMLHTTP.6.0",
                  "Msxml2.XMLHTTP.4.0",
                  "Msxml2.XMLHTTP.3.0"];
    for(var i=0; i<clsids.length && xmlHttp == null; i++) {
        xmlHttp = CreateXmlHttp(clsids[i]);
    }
    return xmlHttp;
}

As you see, GetXmlHttpObject methods accept a handler parameter which is a name of the callback method that should be defined in the page-specific code. Now that we already have an XmlHttp object, we can send an asynchronous request.

function SendXmlHttpRequest(xmlhttp, url) { 
    xmlhttp.open('GET', url, true); 
    xmlhttp.send(null); 
}

I use a GET HTTP method to a given URL, but this can be easily changed by changing the JS code above.

Page-specific methods

Now we have all the methods we need to perform a call to the remote page. In order to do this, we need to pass the callback method name to the GetXmlHttpObject method and then pass the URL string to the SendXmlHttpRequest method.

Collapse
var xmlHttp; 

function ExecuteCall(url)
{ 
    try 
    { 
        xmlHttp = GetXmlHttpObject(CallbackMethod); 
        SendXmlHttpRequest(xmlHttp, url); 
    }
    catch(e){} 
} 
    
//CallbackMethod will fire when the state 
//has changed, i.e. data is received back 
function CallbackMethod() 
{ 
    try
    {
        //readyState of 4 or 'complete' represents 
        //that data has been returned 
        if (xmlHttp.readyState == 4 || 
            xmlHttp.readyState == 'complete')
        {
            var response = xmlHttp.responseText; 
            if (response.length > 0)
            {
                //update page
                document.getElementById("elementId").innerHTML 
                                                   = response; 
            } 
        }
    }
    catch(e){}
}

The CallbackMethod is responsible for updating the page content. In our example, it simply updates the inner HTML of the given HTTP element. But in real life, it can be much more complex.

The last question regarding the calling page implementation is how we call the ExecuteCall JS method. Well, it depends on what the page is doing. In some cases, the ExecuteCall method can be called when the JS event is fired. But if that is not the case, we can register the method as a startup script for the page using the corresponding C# code in the page's code-behind.

Page.RegisterStartupScript("ajaxMethod", 
   String.Format("<script>ExecuteCall('{0}');</script>", url));

We can add this line of code either in the Page_Prerender or Page_Load method of the ASP.NET code-behind file.

Remote Page

Let’s find out what a remote page could look like. If this is an ASP.NET page (what we assume), we are interested in the code-behind only. We can easily remove all the code from the .aspx file: it won’t affect the behavior of the page in any way.

For example, we take a public web service that converts temperature values in Celsius to Fahrenheit and vice versa. The service is available here. If you add this URL as a web reference to your project, Visual Studio will generate a proxy class with the name com.developerdays.ITempConverterservice in your current namespace. Our remote ASP.NET page, let’s name it getTemp.aspx, will accept a query string parameter with the name “temp” which should contain an integer value of a temperature in Celsius to convert. So the target URL to the remote page will look like this: http://localhost/getTemp.aspx?temp=25. And the code-behind for this page is shown below:

private void Page_Load(object sender, EventArgs e)
{
    Response.Clear();
    string temp = Request.QueryString["temp"];
    if (temp != null)
    {
        try
        {
            int tempC = int.Parse(temp);
            string tempF = getTempF(tempC);
            Response.Write(tempF);
        }
        catch
        {
        }
    }
    Response.End();
}

private string getTempF(int tempC)
{
    com.developerdays.ITempConverterservice 
          svc = new ITempConverterservice();
    int tempF = svc.CtoF(tempC);
    return tempF.ToString();
}

According to our convention, we can now build a URL string for the remote page that we will pass to the RegisterStartupScript method in the example above, like this:

int tempC = 25;
string url = String.Format("http://localhost/" + 
             "getTemp.aspx?temp={0}", tempC);

Using the approach with an intermediate ASP.NET page, calling in its turn a remote service, allows simplifying response processing, especially if it requires parsing. In simple cases when the response contains just text, we can pass the remote service URL directly to the JS ExecuteCall method.

Conclusion

This article is aimed to illustrate the simplicity of using the AJAX technology in any ASP.NET application. While AJAX has some drawbacks, it also provides some advantages from the user experience perspective. It’s completely up to the developer whether to use the AJAX technology or not, but I have just demonstrated that in simple cases, it does not take a long time or require any special skills.

Credits

I would like to thank my colleagues Oleg Gorchkov and Chris Page who helped me out with testing and optimizing the approach described in the article.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Alexander Turlov


Alexander Turlov has been working in IT industry since 1987. His programming experience includes such languages as FORTRAN, Pascal, and Basic, C, C++ and C#. He's been working for different industries like science, manufacturing, retail, utilities, finance, insurance, health care, education and so on. His current area of interests is .NET, C#, and ASP.NET programming. He is working in software development doing architecture, design and development on .NET platform and using Microsoft products such as Visual Studio, SQL Server, P&P Software Factories, and Enterprise Library. He holds a M.Sc. degree in physics and an MCSD.NET certification.

View my profile on LinkedIn

View my blog
Occupation: Architect
Location: Canada Canada

Other popular Ajax and Atlas articles:

Posted by 1010
06.Ajax2008. 7. 8. 17:21
반응형

http://code.google.com/apis/ajaxsearch/samples.html


Google AJAX Search API Samples

Simple Hello World

This sample application is the canonical "Hello World" of Google AJAX Search API. This simple application instantiates the search control in read-only mode.

Custom Search EnginesNew!

This sample demonstrates how to use Google Custom Search Engines in conjunction with the Google AJAX Search API. The sample integrates four custom search engines along with blog, video, and news search.

Video Bar SolutionNew!

This sample demonstrates the brand new GSvideoBar() solution. This is a very light weight solution that allows you to place a dynamic video bar vertically or horizontally on your page or blog. You can have multiple Video Bars on a page, all sharing a common video player. The Video Bar also composes nicely with the Video Search Control Solution. Take a look, and be sure to also visit our AJAX Search API Playground blog where we have integrated the Video Bar into the template.

Google AJAX Search API in TypePad

This sample demonstrates the use of the Google AJAX Search API including core web and blog search, the video search solution, and the map search control solution, all hosted in a TypePad blog. The sample includes links to the TypePad module templates and instructions for applying this to your own TypePad based blog.

Google AJAX Search API in Blogger

Identical to the TypePad based solution, but designed for Blogger

Video Search Control Solution

This sample demonstrates the brand new GSvideoSearchControl() solution. This solution allows you to easily embed a rich video search control on your site, blog, etc. The control lets you search, tag, and play videos without leaving the page. The page is very easy to integrate into your applications and can be integrated in just a few lines of code. Feel free to copy and clone the solution to meet your needs, or use it as it stands.

Map Search Solution

This sample uses the brand new GSmapSearchControl() solution to show you how to add a a simple geo-oriented search control anywhere on your site with just a few lines of code. Feel free to copy and clone the solution to meet your needs, or use it as it stands. The sample linked to above demonstrates how to use it. If you can write this, new GSmapSearchControl(container, "1000 NE Multnomah, Portland, OR");, then you can easily add a nice little local search control to your site.

Phone List

This sample demonstrates how to build a "Phone List" of favorite restaurants, etc, using the Google Ajax Search API.

Blog Comment Form

This sample application demonstrates how you can incorporate the AJAX Search API in user composition. In this case, users can clip Google search results to their comments on a blog post.

My Favorite Places

This sample application shows how to to use the Google AJAX Search API to create a collection of favorite places. From a programming perspective, it demonstrates the use of a custom input element and direct use of GSearch objects.

Searchers and Options

This sample application demonstrates many of the programmable options of the Search Control, allowing you to select various searchers, drawing modes, etc.

Locale Selection

This sample application demonstrates the Google AJAX Search API running its UI in a variety of languages.

My Favorite Places #2

This sample application builds on the original My Favorite Places sample and is designed to demonstrate search result and search control dynamic styling, controlling the location of clipped search results, etc. Before diving into this sample, if would be a good idea to become familiar with the previous samples.

Wish List

Similar to the Lead Manager sample, this sample demonstrates building more complex lists, something like a "what I want for christmas list, or what I want for my birthday." This sample deomstrates search result clipping as well as site restricted search.

Video Search + Social Networks

This sample demonstrates how video search might integrate into social networking applications. Note the use of search result clipping to add a little video into a message as well as the ability to remember a search result into a stack of favorites.

Posted by 1010