スクリプトを実行する
では、実際に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」といったバージョン番号が表示されるはずです。このバージョン番号の表示を行っている処理こそ、サーバーサイドで実行されたものなのです。

念のために、表示されたページのHTMLソースコードを調べてみてください。<script runat="server">で指定されたスクリプトタグ部分が消えているはずです。今回、実行したこのスクリプトは、サーバーサイドで実行されていたため、クライアントには表示されないのです。
ここで記述されているタグには、<script runat="server">というように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>
ブラウザからこのページにアクセスをしたら、「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">で関数を書くことだけです。ただ、「どういう仕組みで動いているのか」という基本的な形ぐらいは頭に入れておくと良いでしょう。

