Ajax でちょっとしたサンプルを作ってみた。
2006-05-28


禺画像]

ホットスポットをクリックすると、ページのリロードなしにカウントを増やすプログラム。 Perl の CGI として書いてますが、mod_perl の ModPerl::Registry としても問題なく動作します。プログラムを設置するディレクトリにファイルを書き出せる権限がないと、カウント値を書き出すファイルを作れないのでご注意ください。なお、ファイル形式はシグネチャなしの UTF-8 を想定しています。

use strict;

my ($current, $myself) = $0 =~ m!^(.*/)([^/]+)$!;

unless (-e "$0.count"){
        open fout, ">$0.count"     or die "cannot open file (write): $myself.count";
        print fout '1';
        close fout;
}

my %query;
sub decode_url {
        ${$_[0]} =~ tr/+/ /;
        ${$_[0]} =~ s/%([0-9a-f][0-9a-f])/pack 'H2', $1/ieg;
}
foreach (split /&/, $ENV{'QUERY_STRING'}){
        my ($name, $val) = split /=/;
        &decode_url(\$name);
        &decode_url(\$val);
        $query{$name} = $val;
}

if ($query{'m'} eq 'ajax'){     # XMLHttpRequest からの読み込みへの応答
        open fin, "<$0.count"      or die "cannot open file (read): $myself.count";
        my $counter = <fin>;
        close fin;
        
        # IE で XmlHttp からの読み込みがキャッシュされてしまうために
        # カウンタが更新されない不具合への対策として、
        # HTTP ヘッダにいろいろと記入している。
        print <<ENDLINE;
Pragma: no-cache
Cache-Control: no-cache
Content-type: text/plain; Charset=UTF-8

{
        "counter"     : $counter
}
ENDLINE
        
        $counter++;
        open fout, ">$0.count"     or die "cannot open file (write): $myself.count";
        print fout "$counter";
        close fout;
}

else {                          # ページ読み込みへの応答
        print <<ENDLINE;
Content-type: text/html; Charset=UTF-8

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html lang="ja">

<head>
        <meta http-equiv="content-type" content="text/html; charset=UTF-8">
        <meta name="generator" content="$myself">
        <meta http-equiv="content-style-type" content="text/css">
        <meta http-equiv="content-script-type" content="text/javascript">
        <title>テストページ</title>
        <script language="JavaScript" type="text/javascript"><!--
// XMLHttpRequest オブジェクトを取得する
function createHttpRequest()
{
        if (window.XMLHttpRequest){
                return new XMLHttpRequest();
        }
        else if (window.ActiveXObject){ // Microsoft IE 6.0 or older
                try {
                        return new ActiveXObject("Msxml2.XMLHTTP");
                }
                catch (e1) {
                        try {
                                return new ActiveXObject("Microsoft.XMLHTTP");
                        }
                        catch (e2) {
                                return null;
                        }
                }
        }
        else {                          // Ajax 未対応の UA
                return null;
        }
}

// XMLHttpRequest によるリクエストを発行し、カウンター値を取得して、
// ページの表示に反映する
function getCount(request){
        request.open("GET", "$myself?m=ajax");
        request.send("");
        if (typeof ScriptEngine == "function"){
                request.onreadystatechange = function (){
                        if (request.readyState == 4){
                                callback_get_count(request.responseText);
                        }
                }
        }
        else {
                request.onload = function (){
                        callback_get_count(request.responseText);
                }
        }
}

function callback_get_count(text){
        eval("res = " + text);
        document.getElementById('counter-view').innerHTML = res.counter;
}

// ページ読み込み時にカウンターを更新
var request = createHttpRequest();
getCount(request);
//      --></script>
</head>

<body>

<p>てすと。</p>

<div><!-- カウンターはここに表示される -->
カウンター : <span id="counter-view"></span>
</div>

<!-- クリックするとカウンターが更新されるホットスポット -->
<p><a href="javascript: void(0)" onclick="getCount(request)">くりっく</a></p>

</body>

</html>

ENDLINE
}

なお、Javascript のデバッグは、Firefox と Venkman JavaScript Debugger で行うことができます。デバッグしたい (ブレークポイントを張りたい) コードを関数の中に収めるように記述するのがポイントです。


続きを読む

[設計・開発]
[個人的メモ]

コメント(全0件)
コメントをする


記事を書く
powered by ASAHIネット