2011年01月24日


prototype.js を クロスドメイン対応にするパッチ

google.load で実装される prototype.js でテストしています。

prototype.js でクロスドメインの Ajax の読み込みテスト
では、prototype.js そのものを変更しましたが、変更できない場合の対応
方法です。リンク先に書いていますが、サーバー側が適正なヘッダを返す
事が必要となり、ブラウザ側ではヘッダを変更しない事が必要になります。

Opera は動作しませんが、php 等が動くサイトを持っていて、かつ postMessage
を使えば、IFRAME 経由でクロスドメインデータを取得できると思います。
<script type="text/javascript" src="https://www.google.com/jsapi"></script>
<script type="text/javascript">
google.load("prototype", "1.7.0.0");
</script>

<script type="text/javascript">
// *********************************************************
// バッチその1
//
// XDomainRequest を使えるようにするのが目的です
// *********************************************************
Ajax.getTransport = function() {
    return Try.these(
      function() {return new window.XDomainRequest()},
      function() {return new XMLHttpRequest()},
      function() {return new ActiveXObject('Msxml2.XMLHTTP')},
      function() {return new ActiveXObject('Microsoft.XMLHTTP')}
    ) || false;
}

// *********************************************************
// バッチその2
//
// XDomainRequest 用の処理を追加します
// ※ onComplete のみ使えるように( 実際は onload )
// *********************************************************
Ajax.Request.prototype.request = function(url) {
    this.url = url;
    this.method = this.options.method;
    var params = Object.isString(this.options.parameters) ?
          this.options.parameters :
          Object.toQueryString(this.options.parameters);

    if (!['get', 'post'].include(this.method)) {
      params += (params ? '&' : '') + "_method=" + this.method;
      this.method = 'post';
    }

    if (params && this.method === 'get') {
      this.url += (this.url.include('?') ? '&' : '?') + params;
    }

    this.parameters = params.toQueryParams();

    try {
      var response = new Ajax.Response(this);
      if (this.options.onCreate) this.options.onCreate(response);
      Ajax.Responders.dispatch('onCreate', this, response);

      this.transport.open(this.method.toUpperCase(), this.url,
        this.options.asynchronous);

      if (this.options.asynchronous) this.respondToReadyState.bind(this).defer(1);

      // ここから : 変更した部分
      if ( Prototype.Browser.IE ) {
          var ieparam1 = this.options.onComplete;
          var ieparam2 = this.transport;
          this.transport.onload = function() { ieparam1(ieparam2) };
      }
      else {
          this.transport.onreadystatechange = this.onStateChange.bind(this);
      }
      // ここまで : 変更した部分
      this.setRequestHeaders();

      this.body = this.method == 'post' ? (this.options.postBody || params) : null;
      this.transport.send(this.body);

      /* Force Firefox to handle ready state 4 for synchronous requests */
      if (!this.options.asynchronous && this.transport.overrideMimeType)
        this.onStateChange();

    }
    catch (e) {
      this.dispatchException(e);
    }
}

// *********************************************************
// バッチその3
//
// とりあえず、処理を空にしていますが、パッチ2のほうで変更
// する事もできます
// *********************************************************
Ajax.Request.prototype.setRequestHeaders = function() {}

</script>

<input
	type="text"
	value="http://lightbox.on.coocan.jp/ver.php"
	id="xurl"
	style='width:400px;'
>
<input type="button" value="実行" onclick='testCall();'>
<script type="text/javascript">
function testCall() {
	new Ajax.Request($("xurl").value, {
		method: "get",
		asynchronous: true,
		onComplete: function(response) {
			alert(response.responseText);
		}
	});
}
</script>



【クロスドメインの最新記事】
posted by at 2011-01-24 18:33 | クロスドメイン | このブログの読者になる | 更新情報をチェックする