0

AJAX XML-RPC と REST のより深い知識を得たいので、Matthew Eernise 著「独自の AJAX Web アプリケーションを構築する」という本のチュートリアルに基づいて、JavaScript を使用して基本的な Ajax ライブラリを作成しようとしています (こちらを参照)。本に基づいて、AJAX または XMLHttpRequest を実行する JavaScript コンストラクター関数を作成しましたが、どういうわけか範囲外の問題に悩まされているようで、Ajax クラスは次のスクリプトで定義されていません。

function Ajax() {
    // properties 
    this.req = null;
    this.url = null;
    this.method = 'GET';
    this.asynch = true;
    this.status = null;
    this.statusText = '';
    this.postData = null;
    this.readyState = null;
    this.responseText = null;
    this.responseXML = null;
    this.handleResp = null;
    this.responseFormat = 'text',
    // 'text', 'html', 'xml' or 'object'
    this.mimeType = null;

} // End Constructor

//Create XMLHttpRequest method with  XMLHttpRequest object
this.init = function() {
    if (!this.req) {
        try {
            //Try to create objects for Firefox, Safari, IE7, etc.
            this.req = newXMLHttpRequest();
        }

        catch(e) {
            try {
                //Try to create object for later versions of IE.
                this.req = new ActiveXObject('MSXML2.XMLHTTP');
            }

            catch(e) {
                try {
                    //Try to create for early versions of IE.
                    this.req = new ActiveXObject('Microsoft.XMLHTTP');
                }

            catch(e) {
                //Could not create XMLHttpRequest object.
                return false;
            }
        }
    }
}
return this.req;
};


//Sending a Request method
this.doReq = function() {
    if (!this.init()) {
        alert('Could not create XMLHttpRequest object.');
        return;
    }
    //Setting up a request
    //open methods with method, url and asycn yes or no
    this.req.open(this.method, this.url, this.asynch);
    //Make sure mimetype is OK
    if (this.mimeType) {
    try {
        req.overrideMimeType(this.mimeType);
    }
    catch(e) {
        //couldn't override MIME type ... IE6 or Opera?
        }
}

var self = this; // fix loss-of-scope in inner function
this.req.onreadystatechange = function() {
    var resp = null;
    if (self.req.readyState == 4) {
        //do stuff to handle response
            switch (self.reponseFormat) {
            case 'text':
                resp = self.req.responseText;
                break;
            case 'xml':
                resp = self.req.responseXML;
                break;
            case 'object':
                resp = req;
                break;
            }
            if (self.req.status >= 200 && self.req.status <= 299) {
                self.handleResp(resp);
            }
            else {
                self.handleErr(resp);
            }
        }

};
this.req.send(this.postData);
};

this.handleErr = function() {
    var errorWin;
    try {
        errorWin = window.open('', 'errorWin');
        errorWin.document.body.innerHTML = this.responseText;
    }
    catch(e) {
        alert('An error occured, but this error message cannot be '
        + 'displayed. This is probably because of your browser\'s '
        + 'pop-up blocker. \n'
        + 'Please  allow pop-ups from this website if you want to '
        + 'see the full error messages. \n'
        + '\n'
        + 'Status Code: ' + this.req.status + '\n'
        + 'Status description: ' + this.req.statusText);
    }
};

this.abort = function() {
    if (this.req) {
        this.req.onreadystatechange = function() {};
        this.req.abort();
        this.req = null;
    }
};

this.doGet = function (url, hand, format) {
    this.url = url;
    this.handleResp = hand;
    this.responseFormat = format || 'text' ;
    this.doReq();
};

このスクリプトをロードするページで発生するエラー

var hand = function (str) {
    alert(str);
}
var Ajax = new Ajax(); // new instance as can ben done with PHP5 constructor classes
ajax.doGet ('/fakeserverpage.php', hand);

スコープの問題を修正するためにajax is not defined追加したにもかかわらず、Ajaxの新しいインスタンスを起動するとエラーが発生します。var self = this; // fix loss-of-scope in inner function 私は何が欠けていますか?

更新 1

ここのヒントのおかげで、新しいインスタンスに別の名前を付けて、衝突しないようにします。

var hand = function (str) {
    alert(str);
}
var ajax = new Ajax(); // new instance as can ben done with PHP5 constructor classes
ajax.doGet ('/fakeserverpage.php', hand);

今、私はもう少し進んでいます。今、私は新しいエラーを受け取ります:Uncaught TypeError: Object #<Ajax> has no method 'doGet'

更新 2

Ajax.prototype.initここで共同開発者が推奨する代わりに 使用してみthis.initましたが、それでも同じエラーが発生します..

更新 3 @Soufiana Hassou のおかげで、Ajax.prototypeすべてのメソッドに追加してコードを改善しました。すべてがコンストラクターで動作する必要があることを知りませんでしたが、そうです。コードはこちらhttp://pastebin.com/g86k0z8dです。Could not create XMLHttpRequest object.This error message is built into the method so it is working, but it cannot create the objectどういうわけか. これは、すべてのケースをカバーし、ローカル MacPorts MAMP のコードを使用して Firefox 11 for Mac でこれをテストしたため、XMLHttpRequest のリクエストにエラーがあるに違いないことを意味します。それか、私が知らない何かが他にあります..

更新 4

タイプミスを修正しました。次に、偽のサーバーページをロードする 404 を受け取りました。パスが修正されajax.doGet ('/ajax/fakeserverpage.php', hand);たので、今はOKです。コードを生成するために PHP を取得する必要があるだけなので、OK を取得します。ヘッダーの応答は問題ありませんが、AJAX アラートはまだ表示されません。次に、コンソールを確認したところ、次のエラーが見つかりました。

self.req is undefined
http://localhost/ajax/ajax.js
Line 78

最新のコードを参照してください: http://pastebin.com/g86k0z8dAjax.prototypeまだ必要だと思ったところにさらに追加しました。今私は得る:

this.req is null
http://localhost/ajax/ajax.js
Line 100

更新 5

var を使用して範囲外の問題に最初に使用されたいくつかの自己を削除するいくつかの変更を加えましたself = this。コードは同じペーストビンのままですが、更新しました。今私が持っています:

Ajax.prototype.handleResp is not a function
http://localhost/ajax/ajax.js
Line 92

アップデート 6

関数で犯したいくつかの間違いを片付けreq.onreadystatechange = function()、今では実行しています。localhost の Firefox ポップアップ ブロッカーをオフにし、リロードすると別のタブが開き、テキストが表示されundefinedました。だからほとんどそこに。エラーはありません。OK のポップアップはありません。undefinedChrome は、本文に が表示されたポップアップを表示しました。ここで更新されたコード:いつものようにhttp://pastebin.com/g86k0z8d

4

2 に答える 2

3

インスタンスとクラス自体に同じ名前を使用しています。また、 Javascript は大文字Ajaxajax小文字を区別します。

于 2012-04-09T06:40:07.800 に答える
1

まず、あなたは代わりに持ってvar Ajax = new Ajax();いるべきです。var ajax = new Ajax();

第 2 にthis、コンストラクターの外部での使用は Ajax オブジェクトを参照していません。代わりにそのプロトタイプを使用してみてください:

function Ajax() {
    // Set properties here
}
Ajax.prototype.init = function() {
    // ...
}

詳細については、Javascript クラスに関するこの記事を参照してください。

于 2012-04-09T07:03:14.133 に答える