2011年02月03日


クロスドメインで、showModalDialog を使用する

toolbox.winofsql.jp にある、modalDialog.htm を showModalDialog で呼び出して
データ交換を行います。IFRAME として、modalDialogServer.htm を組み込む必要が
あります。データは、toolbox.winofsql.jp 用の localStorage を使用して保存され
ますが、一時的な中間データとして扱います。
Opera は showModalDialog を使用できないので、同等の処理を行うにはそれ相当の工夫と努力が必要になります。


modalDialogServer.htm
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<meta content="text/html; charset=euc-jp" http-equiv="Content-Type">
<title>モーダルダイアログサーバー</title>
<style type=text/css>
* {
	font-size: 12px;
}

textarea {
	width:700px;
	height:400px;
}
</style>
<script type=text/javascript>

var text;

if ( window.attachEvent ) {
	window.attachEvent('onmessage',function(e) {
		text = e.data;
		// 先頭コマンド 'A' で、ローカル保存
		if ( text.substr(0,1) == 'A' ) {
			if ( text.substr(1) == '' ) {
				localStorage['serverText'] = new String("");
			}
			else {
				localStorage['serverText'] = text.substr(1);
			}
		}
		// 先頭コマンド 'B' で、ローカル保存されていたデータを親ウインドウに POST
		if ( text.substr(0,1) == 'B' ) {
			parent.postMessage(localStorage['serverText'], "*");
		}
	});
}
else {
	window.addEventListener('message',function(e) {
		text = e.data;
		// 先頭コマンド 'A' で、ローカル保存
		if ( text.substr(0,1) == 'A' ) {
			if ( text.substr(1) == '' ) {
				localStorage['serverText'] = new String("");
			}
			else {
				localStorage['serverText'] = text.substr(1);
			}
		}
		// 先頭コマンド 'B' で、ローカル保存されていたデータを親ウインドウに POST
		if ( text.substr(0,1) == 'B' ) {
			parent.postMessage(localStorage['serverText'], "*");
		}
	}, false);
}

</script>
</head>
<body>
</body>
</html>


ダイアログと呼び出し側のコード

関連する記事

showModalDialog の使い方と使う場所


posted by at 2011-02-03 14:16 | クロスドメイン | このブログの読者になる | 更新情報をチェックする

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 | クロスドメイン | このブログの読者になる | 更新情報をチェックする

2011年01月22日


JavaScript : 別ドメイン間のデータ転送



こちら側のコード
<script type="text/javascript">

	if ( window.attachEvent ) {
		window.attachEvent('onmessage',function(e) {
			document.getElementById("msg").value = e.data;
			document.getElementById("origin").value = e.origin;
		});
	}
	else {
		window.addEventListener('message',function(e) {
			document.getElementById("msg").value = e.data;
			document.getElementById("origin").value = e.origin;
		}, false);
	}

</script>
<input type="text" id="msg">
<input type="text" id="origin" style='width:400px;'>
<br><br>
<iframe
	src="http://lightbox.on.coocan.jp/message.htm"
	name="myframe"
	frameborder="1"
	scrolling="yes"
	width="500"
	height="100"
></iframe>

別ドメインの IFRAME 内のコード

parent で直接 HTML 内のオブジェクトにはアクセスできませんが、
parent の postMessage で、そのウインドウにメッセージを post
可能です。これは、逆でも同じで、こちらがわから IFRAME に対して
post するには、IFRAME のオブジェクトの contentWindow.postMessage
を実行します。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<meta http-equiv="Content-type" content="text/html; charset=EUC-JP">
</head>
<body>

<input
	type="text"
	id="message"
	style='width:200px;'
	value="日本語表示"
>
<input
	type="button"
	value="post"
	onclick='parent.postMessage(document.getElementById("message").value, "*")'
>

</body>
</html>



posted by at 2011-01-22 04:27 | クロスドメイン | このブログの読者になる | 更新情報をチェックする
Seesaa の各ページの表示について
Seesaa の 記事がたまに全く表示されない場合があります。その場合は、設定> 詳細設定> ブログ設定 で 最新の情報に更新の『実行ボタン』で記事やアーカイブが最新にビルドされます。

Seesaa のページで、アーカイブとタグページは要注意です。タグページはコンテンツが全く無い状態になりますし、アーカイブページも歯抜けページはコンテンツが存在しないのにページが表示されてしまいます。

また、カテゴリページもそういう意味では完全ではありません。『カテゴリID-番号』というフォーマットで表示されるページですが、実際存在するより大きな番号でも表示されてしまいます。

※ インデックスページのみ、実際の記事数を超えたページを指定しても最後のページが表示されるようです

対処としては、このようなヘルプ的な情報を固定でページの最後に表示するようにするといいでしょう。具体的には、メインの記事コンテンツの下に『自由形式』を追加し、アーカイブとカテゴリページでのみ表示するように設定し、コンテンツを用意するといいと思います。


※ エキスパートモードで表示しています

アーカイブとカテゴリページはこのように簡単に設定できますが、タグページは HTML 設定を直接変更して、以下の『タグページでのみ表示される内容』の記述方法で設定する必要があります

<% if:page_name eq 'archive' -%>
アーカイブページでのみ表示される内容
<% /if %>

<% if:page_name eq 'category' -%>
カテゴリページでのみ表示される内容
<% /if %>

<% if:page_name eq 'tag' -%>
タグページでのみ表示される内容
<% /if %>
この記述は、以下の場所で使用します