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

JavaScript : Safari for Windows 5.0.3 の困ったバグとその対処方法 : alert、confirm でフォーカスがセットされていない。

Windows XP だけで起きていたり、環境によって違うかもしれませんが、
結構致命的で、Safari の為だけにコードを書かないといけないので困ります。
これは操作するほうが注意しないといけない内容ですが、対応したい場合は
setTimeout を使います。

10 ミリセカンド後でいいので、alert や confirm の処理を含んだ function
を setTimeout で呼び出す事で正しく動作します。これをしないと、表示している
メッセージボックスは、クリックしても一度目は反応しません。それでころか、1
度目にボタンをクリックすると、その後ろ側にある HTML に対して反応してしまい
ます。

かなり、致命的です

HTML のインラインで書く場合は、無名 function を使い、イベント用の文字列
はシングルクォートで表現するといいです。そうすると、プログラム出現率の高
い、ダブルクォートを心おきなく使えます。

※ シングルクォートが必要な場合は、&#39; を使えます。
<input type="button" value="action" onclick='alert("I can&#39;t fly.")'>

<input type="button" value="action" onclick='

	setTimeout(function(){
		alert("I can&#39;t fly.")
	},10);

'>



posted by at 2011-01-24 15:28 | JavaScript | このブログの読者になる | 更新情報をチェックする

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

2011年01月19日


land.to でも結構簡単に PHP で ImageMagick が使えるようになります

いくつかコマンドを実行しますので、サーバーに負荷をかけないように
一つ一つ実行します。テストしたのは、sp サーバーです。

まず public_html の下で以下のコマンドを実行します。
(.cgi は、755 に変更しました。)
t01.cgi
#!/bin/sh
echo "Content-Type: text/plain"
echo
echo "<pre>"
echo
pecl bundle imagick-3.0.1
echo
echo "</pre>"

実行すると、imagick ディレクトリが作成されるので、中に入って
前回と同様にして、3回に分けて以下のコマンドを実行します。

1) phpize
2) ./configure
3) make

phpize に関しては、良く知らないですが、参考にしたサイトのサンプルに記述されていたので実行しました。
make が終わると、imagick/modules にモジュールが作成されるので、 ftp のルートにある php.ini のエントリを以下のようにします extension_dir = "/home/httpd/username/public_html/imagick/modules" username は、land.to の登録 id です。このパスは、phpinfo() の php.ini パスで確認できます。 最後に、php.ini の該当場所で、extension=imagick.so とすれば使える ようになります。但し、sp サーバーでは残念な事に、本体の ImageMagick のバージョンが古く、アイコン(.ico) の作成がうまくいきませんでした。 データ部分は正しいようですが、ヘッダが間違っているような気がします。 もし、そうなら自分で書き換えれば使えるようになるかもしれません 参考になりそうなページ GDで作成した画像をICO形式で出力する - 讃容日記 関連する記事 さくらインターネットでは、PHP で extension=imagick.so するだけで ImageMagick が使えます さくらインターネット : Ruby : rubygems-1.3.5 のインストール( + mechanize ) land.to で ruby に mechanize をインストール 以下はテストしたコードです( writeImagesFile は使えませんでした )
<?php

$img = new Imagick();
$img->readImage("in.png");
$img->writeImage ( "out.jpg" );

$img->clear();
$img->destroy(); 

?>
OK



posted by at 2011-01-19 11:31 | レンタルサーバー | このブログの読者になる | 更新情報をチェックする

2011年01月18日


さくらインターネットでは、PHP で extension=imagick.so するだけで ImageMagick が使えます



今日調べてて解ったのですが、さくらインターネットで使用可能なPHP5 の各バージョンで、最初から imagick.so が作成されてました。

利用しているのは、デフォルトの 5.2.17 ですが、phpinfo() で表示される、extension_dir に設定しているディレクトリを見に行くと、存在していました(/usr/local/php/5.2.17/lib/php/extensions/no-debug-non-zts-20060613)

(/usr/local/php/5.3.27/lib/php/extensions/no-debug-non-zts-20090626)
(/usr/local/php/5.4.17/lib/php/extensions/no-debug-non-zts-20100525)
2013/11/23 現在、5.2.17、5.3.27、5.4.17 それぞれにあります。
また、oauth.so も存在します

更新日付は、2013/07/23 になっています
テストは以下のコードで行いました。 ※ .gif より .ico への変換です
<?php
$img = new Imagick();
$img->readImageBlob(file_get_contents("heart.gif"));
$img->setImageFormat("ICO");

$handle = fopen("test.ico", "wb");

$img->writeImagesFile( $handle );
?>
OK

関連する記事

land.to でも結構簡単に PHP で ImageMagick が使えるようになります


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

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

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

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

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


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

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

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

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

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