javascript로 xmlhttprequest 객체를 작성중에..

sh.의 이미지

function AJAX() {
    this.Response;
    this.RequestObject;
    this.DOMDocument;
 
    this._constructor();
}
 
AJAX.prototype._constructor = function() {
    log('call AJAX::_constructor');
    this.Response      = null;
    this.RequestObject = null;
    this.DOMDocument   = null;
    this.initRequestObject();
}
 
AJAX.prototype.initRequestObject = function() {
    log('call AJAX::initRequestObject');
    try {
        if (window.XMLHttpRequest) {
            var obj = new XMLHttpRequest();
        } else if (window.ActiveXObject) {
            var obj = new ActiveXObject("Msxml2.XMLHTTP.3.0");;
        }
        obj.onreadystatechange = this._httpHandler;
        this.RequestObject = obj;
    } catch(e) {
        log(e);
    }
}
 
AJAX.prototype._httpHandler = function() {
    log('call AJAX::_httpHandler state = [' + '' + ']');
    /*
    switch (this.RequestObject.resdyState) {
        case 4:
            if (window.DOMParser) {
                var dom = new DOMParser();
                this.DOMDocument = dom.parseFromString(this.RequestObject.responseText, 'text/xml');
            } else if (window.ActiveXObject) {
                this.DOMDocument = new ActiveXObject("Msxml2.DOMDocument.3.0");
                this.DOMDocument.async = false;
                this.DOMDocument.loadXML(this.RequestObject.responseText);
            }
 
        break;
 
        default:
        break;
    }
     */
}
 
AJAX.prototype.sendRequest = function(method, url, body) {
    log('call::sendRequest([' + method + '], [' + url + '], [' + body + '])');
    try {
        this.RequestObject.open(method, url, true);
        this.RequestObject.send(body);
    } catch(e) {
        if (e.indexOf('거부') != -1 || e.indexOf('denide') != -1) {
            log('exception AJAX::sendRequest ' + e);
            log('      domain확인');
        }
    }
}

대략 이런 스크립트를 만들고 있습니다
그런데 난감해진것이.. 막 코딩을 하다보니 onreadystatechange 이벤트 핸들러가 호출이 될때는 global 문맥에서 실행이 되기 때문에 AJAX._httphandler 에서 this 로 참조를 할수가 없다는 점입니다.

그렇다고 해서 xmlhttprequest객체를 global로 놓고 핸들러 역시 일반 함수로 만들자니.. 너무너무 찜찜하네요;;

혹시 이런 경우에 해법을 알고 계시는 분께 조언을 구합니다.

nohmad의 이미지

onreadystatechange 이벤트 핸들러를 호출하는 부분을 AJAX 스코프 안에 두면 될 것 같네요. 이럴 경우에는 핸들러 함수를 익명함수로 전달해야 합니다.

크로스 브라우저 환경을 염두에 두고 코딩하시는 것 같은데, dojo.io.bind나 RubyOnRails 프레임웍을 지원하기 위해 만들어진 Prototype 라이브러리의 AJAX 부분을 보시면 참고가 될 것 같습니다. Prototype 라이브러리는 현재 AJAX와 FAT(Fade Anything Technique) 지원 정도가 들어있는데, 곧 Event쪽 코드도 추가될 예정이어서 라이브러리를 한 번 익히면 크로스 브라우징 문제를 상당 부분 해결할 수 있어서 기대하고 있습니다.

참고로 저는 XMLHttpRequest 인터페이스를 크로스 브라우저를 위한 wrapping 없이 직접 사용할 수 있도록 다음과 같이 클래스를 생성해둡니다.

/**
 * Cross-browser XMLHttpRequest class
 */

if (typeof XMLHttpRequest == 'undefined') {
  XMLHttpRequest = function () {
    var msxmls = ['MSXML3', 'MSXML2', 'Microsoft']
    for (var i = 0; i < msxmls.length; i++) {
      try {
        return new ActiveXObject(msxmls[i]+'.XMLHTTP')
      } catch (e) { }
    }
    throw new Error("No XML component installed!")
  }
}
sh.의 이미지

prototype 의 소스를 참고해보고 있습니다.
그리고 같이 올려주신 방법도 아주 유용할거같네요.
감사합니다.
그런데 혹시 prototype에 대한 레퍼런스 문서는 없나요? 위에 알려주신 사이트에도 따로 문서가 나와있지는 않네요..

nohmad의 이미지

사실 프로토타입 라이브러리는 RubyOnRails 프레임웍을 지원할 목적으로 만들어져서, 다른 곳에서 직접 불러쓰기가 그렇게 쉽지는 않습니다. 자바스크립트 자체에 대한 문서도 없고, RubyOnRails 메일링리스트에나 간간이 팁들이 올라오는 정도입니다. 일단 제가 데모용으로 만든 페이지 하나를 알려드리겠습니다.

http://nohmad.sub-port.net/dummy/zipcode

프로토타입 라이브러리가 지원하는 Observer 패턴을 이용해서 주소 찾기 기능을 LiveSearch로 구현해본 것입니다.

sh.의 이미지

Quote:
사실 프로토타입 라이브러리는 RubyOnRails 프레임웍을 지원할 목적으로 만들어져서, 다른 곳에서 직접 불러쓰기가 그렇게 쉽지는 않습니다.

한참을 prototype.js 를 쳐다봤습니다^^
Ajax.Updater 를 보고서 뭔가 이게 단순한 라이브러리는 아니구나 싶더라고요..

함수를 선언하는 방식등이 생소하네요. literal로 object를 만들 수 있는것은 알았지만 이렇게 사용한것은 처음 봤습니다.
Ajax.Request.prototype = (new Ajax.Base()).extend({ ....
이런식으로 된 코드도 뭔가 했더니 상속을 구현한것이네요

그리고 제가 해결하고자 했던 부분인 핸들러에 객체를 전달하는 방법은

Function.prototype.bind = function(object) {
    var method = this;
    return function() {
        method.apply(object, arguments);
    }
}

이런 형식으로 해결을 했네요.
일단은 prototype적인 방법을 익힐 시간이 없어서 위의 bind를 차용해다가 해결했습니다.
[/code]

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.