2011-11-10 3 views
0

私のサイトでは、ユーザーの詳細を編集するなどの作業にajaxを頻繁に使用しています。管理者モードで管理者がログインしなくても、ユーザーの詳細を編集できるようにする(パスワードを知る必要があります)Request/Request.JSONのsend()メソッドをオーバーライドして、定義されたデータを追加しますか?

私のサイトのすべてのユーザー詳細ページを取得する予定ですパラメータid。ページ訪問者が管理者としてログインしている場合、このidを送信されたすべてのAjaxリクエストのデータに追加します。したがって、ユーザーがadminとしてログインしている場合は、mootoolsライブラリのロード後にページにjavascriptを注入します。これにより、Requestメソッドが要求を行うときに必ずこのIDを保持します。

どうすれば実装できますか?

これは、Requestクラスのためのsendメソッドである:私はマークされている場所で

send: function(options){ 
    if (!this.check(options)) return this; 

    this.options.isSuccess = this.options.isSuccess || this.isSuccess; 
    this.running = true; 

    var type = typeOf(options); 
    if (type == 'string' || type == 'element') options = {data: options}; 

    var old = this.options; 
    options = Object.append({data: old.data, url: old.url, method: old.method}, options); 
    var data = options.data, url = String(options.url), method = options.method.toLowerCase(); 

    switch (typeOf(data)){ 
     case 'element': data = document.id(data).toQueryString(); break; 
     case 'object': case 'hash': data = Object.toQueryString(data); 
    } 

    //--------- 
    //LOOK HERE 
    //--------- 
    if (this.options.format){ 
     var format = 'format=' + this.options.format; 
     data = (data) ? format + '&' + data : format; 
    } 

    if (this.options.emulation && !['get', 'post'].contains(method)){ 
     var _method = '_method=' + method; 
     data = (data) ? _method + '&' + data : _method; 
     method = 'post'; 
    } 

    if (this.options.urlEncoded && ['post', 'put'].contains(method)){ 
     var encoding = (this.options.encoding) ? '; charset=' + this.options.encoding : ''; 
     this.headers['Content-type'] = 'application/x-www-form-urlencoded' + encoding; 
    } 

    if (!url) url = document.location.pathname; 

    var trimPosition = url.lastIndexOf('/'); 
    if (trimPosition > -1 && (trimPosition = url.indexOf('#')) > -1) url = url.substr(0, trimPosition); 

    if (this.options.noCache) 
     url += (url.contains('?') ? '&' : '?') + String.uniqueID(); 

    if (data && method == 'get'){ 
     url += (url.contains('?') ? '&' : '?') + data; 
     data = null; 
    } 

    var xhr = this.xhr; 
    if (progressSupport){ 
     xhr.onloadstart = this.loadstart.bind(this); 
     xhr.onprogress = this.progress.bind(this); 
    } 

    xhr.open(method.toUpperCase(), url, this.options.async, this.options.user, this.options.password); 
    if (this.options.user && 'withCredentials' in xhr) xhr.withCredentials = true; 

    xhr.onreadystatechange = this.onStateChange.bind(this); 

    Object.each(this.headers, function(value, key){ 
     try { 
      xhr.setRequestHeader(key, value); 
     } catch (e){ 
      this.fireEvent('exception', [key, value]); 
     } 
    }, this); 

    this.fireEvent('request'); 
    xhr.send(data); 
    if (!this.options.async) this.onStateChange(); 
    if (this.options.timeout) this.timer = this.timeout.delay(this.options.timeout, this); 
    return this; 
} 

、この方法は、リクエストにいくつかの余分なデータを追加しているようです。私はこれが私のコードを追加するのに良い場所だと思った。それは、送信に変更、ライブラリ内の()関数がある場合に、自分のコードになるだろうことを意味するので

if (_USER_ID_TO_EDIT){ 
    var id= 'userIdToEdit=' + _USER_ID_TO_EDIT; 
data = (data) ? id+ '&' + data : id; 
} 

しかし、これは偉大な解決策ではありません。私はこのようなものを含めるようにする方法を上書きする可能性が同期外れ(最新のライブラリバージョンを使用したい)

これを行うには良い方法がありますか? Requestクラスから送信されたすべてのリクエストに〜20個の.jsファイルを変更せずにコンテンツを追加するにはどうすればよいですか?

答えて

1

えーと、私はこのような行為があることだろうか信頼できる疑問だろうが、いずれにしても、あなたは自分の管理のための要求の特別なインスタンスを使用することができます。

Request.admin = new Class({ 

    Extends: Request, 

    initialize: function(options) { 
     this.parent(options); 
    }, 

    send: function(options) { 
     // example, add to the data being sent admin id and a delay 
     options = Object.merge({ 
      data: { 
       adminid: "foo", 
       delay: 5 // testing with 5 sec delay 
      } 
     }, options || this.options); 
     this.parent(options); 
    } 

}); 

new Request.admin({ 
    url: '/echo/html/', 
    data: { 
     html: "<p>original data here. foobar</p>"   
    }, 
    method: 'post', 
    onComplete: function() { 
     document.id('target').set("html", this.response.text); 
    } 
}).send(); 

http://jsfiddle.net/dimitar/x2pBu/

私は、この検討しますより良い練習。また、.getメソッドをオーバーライドする必要があります。

別の解決策は、それを直接編集していない、それをリファクタリングによって要求プロトタイプ自体を変更することです - あなたがからClass.refactorを使用することができますMooToolsは、より多くのまたはRequest.implement({send: ... });ので(Request.HTMLとRequest.JSONとリクエストからリクエストの利益のすべてのサブクラス.Queueなど)。

あなたも、このような変化に

欠点は、あなたのリクエストクラスで予期しない動作を得ることであるなどなどvar orig = Request.prototype.send; Request.prototype.send = function() {... something to options; orig.call(this, options); }を行うことができます(特定の物事が起こることを期待すなわちMooToolsのdevのはアウト巻き込まれ、データますそのことを知っている人はいない、バリデーターは失敗するかもしれない、などなど)。デバッグが難しい場合があります。それを暗黙の拡張クラスとして持つことは、保守の観点からも、最小限の抽象化にも意味があります。

将来の互換性についてはあまり気にしないでください - mootools 2.0(別名MILK)はAMDの方法になり、古いmootoolsのコードは互換性の観点から廃止されますが、APIは残っています)。 1.4ブランチにはもっと多くのリリースが存在しないでしょう。

+0

ありがとう、私はあなたが提案する最初のものを使用すると思います。信頼性/セキュリティに関しては、ログインしたユーザーがサーバー上の他の人々の詳細を編集する権利を持っていることを検証しますので、これは安全ではありません。 – Oliver

関連する問題