SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

特集記事

JaxerによるサーバーサイドJavaScript

Jaxerのインストールと簡単な使い方を紹介


スクリプトを実行する

 では、実際にJaxerを使って、サーバー側でJavaScriptを実行させてみましょう。「public」フォルダ内に「index.html」というファイルを作成し、簡単なサンプルコードを記述します。

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
        "http://www.w3.org/TR/html4/loose.dtd">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
        <title>index</title>
        <script runat="server">
        function server_init(){
            document.getElementById('msg').innerHTML = "Jaxer version: " + Jaxer.buildNumber;
        }
        </script>
    </head>
    <body onserverload="server_init();">
        <h3>Jaxer Sample</h3>
        <div id="msg">initialize...</div>
    </body>
</html>

 記述したら、Webブラウザからhttp://localhost:8081/にアクセスしてみましょう。画面には、タイトル名の後に「Jaxer version: 1.0.3.4547」といったバージョン番号が表示されるはずです。このバージョン番号の表示を行っている処理こそ、サーバーサイドで実行されたものなのです。

図5 アクセスするとバージョン番号が表示される。
図5 アクセスするとバージョン番号が表示される。

 念のために、表示されたページのHTMLソースコードを調べてみてください。<script runat="server">で指定されたスクリプトタグ部分が消えているはずです。今回、実行したこのスクリプトは、サーバーサイドで実行されていたため、クライアントには表示されないのです。

 ここで記述されているタグには、<script runat="server">というようにrunatという属性が用意されています。これは、「スクリプトが実行される場所」を示すものです。場所というのは、つまり「サーバー側か、クライアント側か」を示すものと考えてください。ここには以下のいずれかの値が指定されます。

runatに指定する値
説明
server サーバー側で実行します。これはサーバーでソースコードが読まれる際に実行され、実行済みの状態をクライアントに送ります。ですから、クライアント側に届いた段階では既に実行は終わっていますので、アクセスはできません。またこのスクリプトタグの部分も、クライアント側に送られる段階では削除されています。
client クライアント側で実行します。通常のスクリプトと考えてください。なお、runat属性を省略した場合にも、runat="client"が指定されたものとみなされます。
both サーバー側とクライアント側の両方で利用されます。server/clientの両方をあわせたものと考えればよいでしょう。
server-proxy クライアント側からサーバー側にあるスクリプトにアクセスする際に指定します。ページのロードが完了した後で、クライアントからサーバにある処理を呼び出すことができます。

 今回は、serverを指定してスクリプトを実行させました。見れば分かるように、runatの指定があるだけで、それ以外はすべてまったく通常のスクリプトと変わりません。非常に面白いのは、サーバー側で実行されるものなのに、document.getElementByIdでDOMを操作している点でしょう。これは、「runat="server"は、サーバーで実行した結果をクライアントに送り返す」ということを理解すれば納得できます。クライアントに返送した後で、サーバーからクライアントを操作しているわけではないのです。

 また、<body>タグに、「onserverload」という属性が用意されている点にも注目しましょう。これは、onloadのサーバー版といったイベントで、サーバー側でロードされたら実行されます。ここに処理を記述することで、サーバー側で自動的に実行されるようにしていたのです。

クライアントからサーバーの処理を呼び出す

 ここまでは、実行する場所がクライアントからサーバーに変わっただけですからすんなり理解できるでしょう。が、これだけでは、わざわざ「サーバーサイドJavaScript」と大げさに名づけるほどでもありません。「Ajaxサーバー」といわれるからには、「Ajaxでサーバー側の処理を実行する」ことが簡単にできないといけません。

 Ajaxは、クライアント側からサーバー側に非同期通信を行い、必要な情報などを取得する技術です。通常、これはXMLHttpRequestオブジェクトというものを使い、通信状態によって呼び出されるコールバック関数を定義するなどして対処をします。ブラウザによる互換性の問題などもあり、ちょっとした処理で面倒くさいコードを書くことになります。

 が、Jaxerの場合、「サーバーとの通信」は驚くほど簡単です。runat="server-proxy"を指定して関数などを用意し、ただ単にそれを呼び出せばいいのです。実際にやってみましょう。

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
        "http://www.w3.org/TR/html4/loose.dtd">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
        <title>index</title>
        <script runat="server-proxy">
        function getVer(){
            var result = ""
            for(obj in Jaxer.request.headers){
                result += "<b>" + obj + "</b> = " + Jaxer.request.headers[obj] + "<br>";
            }
            return result;
        }
        </script>
        <script type="text/javascript" runat="client">
        <!--
        function writeVersion(){
            document.getElementById('msg').innerHTML = getVer();
        }
        //-->
        </script>
    </head>
    <body>
        <h3>Jaxer Sample</h3>
        <div id="msg">initialize...</div>
        <a href="javascript:void(0);" onclick="writeVersion();">Click</a>
    </body>
</html>
図6 リンクをクリックすると、サーバーからリクエスト情報を受け取り表示する。
図6 リンクをクリックすると、サーバーからリクエスト情報を受け取り表示する。

 ブラウザからこのページにアクセスをしたら、「Click」というリンクをクリックしてみてください。サーバーからリクエストに関する情報を取得し表示します。ここでは、「Jaxer.request.headers」というものを利用しています。Jaxer.requestは、リクエストの情報を管理するオブジェクトが設定されたプロパティで、headersは、ヘッダー情報がまとめられた配列です。ここから値を取り出して書き出すことで、リクエストのさまざまな情報を表示させています。

 ソースコードを見れば分かるように、ここで行っていることは、<script runat="server-proxy">を指定してgetVerという関数を定義し、クライアント側のwriteVersion内からそれを呼び出して表示するだけです。writeVersionが呼び出されると、その中でサーバーにアクセスしてgetVerの結果を受け取っているのです。

 一体、どうやってクライアントのスクリプトから簡単にサーバーの処理を呼び出せるのか。それは実際にブラウザで実行されているスクリプトを見れば分かります。ページのソースコードを見ると、以下のようにスクリプトが出力されていることが確認できるでしょう(見やすいように一部改行などをして整えてあります)。

<script type="text/javascript"
    src="/jaxer/framework/clientFramework_compressed.js?version=1.0.3.4547"></script> 
<script type="text/javascript">
Jaxer.Callback.pageSignature = 1305683418;
Jaxer.Callback.pageName = 'localhost:8081/';
Jaxer.Callback.callingPage = 'http://localhost:8081/';
Jaxer.CALLBACK_URI = '/jaxer-callback';
Jaxer.ALERT_CALLBACK_ERRORS = false;
</script> 

<title>index</title> 
<script> 
eval(Jaxer.Callback.createProxies(['getVer']));
</script> 
<script type="text/javascript"> 
<!--
function writeVersion(){
document.getElementById('msg').innerHTML = getVer();
}
//-->
</script> 

 clientFramework_compressed.jsというライブラリをロードし、Jaxer.Callbackというものの設定を行っています。そして、サーバー側からgetVerの結果を取得するため、Jaxer.Callback.createProxiesというもの結果をevalしています。これらは一体、何か? というと、要するに「サーバーにあるgetVer関数にアクセスするための仕組み」を自動生成していたのです。これにより、クライアント側ではgetVerをそのまま呼び出すだけで実行できるようになっていたのです。

 なんだか複雑そうに見えますが、これらは自動生成されるものであり、実際にプログラマが理解する必要はありません。プログラマが行うのは、ただ単に<script runat="server-proxy">で関数を書くことだけです。ただ、「どういう仕組みで動いているのか」という基本的な形ぐらいは頭に入れておくと良いでしょう。

次のページ
サービスを作成する

修正履歴

この記事は参考になりましたか?

特集記事連載記事一覧

もっと読む

この記事の著者

掌田 津耶乃(ショウダ ツヤノ)

三文ライター&三流プログラマ。主にビギナーに向けたプログラミング関連の執筆を中心に活動している。※現在、入門ドキュメントサイト「libro」、カード型学習サイト「CARD.tuyano.com」を公開...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/4389 2009/10/02 10:37

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー