Jaxer+prototype.jsでちょっと本格:"JavaScriptだけ"でここまでできる

白石俊平
2008/02/07 09:00

Jaxerが持つ豊富なAPIを使用して、これまでより本格的なアプリケーションのソースコードをお見せする。JavaScriptだけでここまでできるというのはおどろきだ。

リスト: login.html

<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <!-- (1) prototype.jsを読み込む -->
    <script src="lib/prototype/prototype-1.6.0.2.js" type="text/javascript"></script>
    <!-- (2) setup.jsを読み込む -->
    <script runat="server" src="lib/setup.js"></script>
    <script runat="server-proxy">
      function authenticate(userId, password) {
        // (3)指定されたIDとパスワードで、ユーザを検索
        var result = Jaxer.DB.execute(
          "select * from account where user_id = ? and password = ?",
          [userId, password]);
        // (4) ユーザが存在したら、セッションにオブジェクトをセット
        if (result.rows.length > 0) {
          var user = result.rows[0];
          Jaxer.session.set("user", user);
          return user;
        }
        return null;
      }
    </script>
    <script type="text/javascript">
      // (5) クライアント側で動作するコード
      function login() {
        var userId = $F("userId");
        var password = $F("password");
        if (!userId || !password) {
          alert("ユーザID、もしくはパスワードが入力されていません。");
          return;
        }
        authenticateAsync(authResult, userId, password);
      }
      function authResult(user) {
        if (user)
          location.href = "main.html";
        else
          alert("ユーザID、もしくはパスワードが不正です。");
      }
    </script>
  </head>
  <body>
    <h2>ログイン</h2>
    ユーザID:<input id="userId" type="text"/><br/>
    パスワード:<input id="password" type="password"/><br/>
    <button onclick="login()">ログイン</button>
    <a href="createAccount.html">アカウント作成</a>
  </body>
</html>
  • (1) prototype.jsの読み込みを行っている。この画面においてはクライアントサイドでしか使用しないため、runatの指定は行っていない。
  • (2) setup.jsと言う、外部のJavaScriptファイルを読み込んでいる。サーバでしか利用しないスクリプトであるため、runat="server"を指定していることには注意が必要。

 setup.jsの内容は以下。Jaxer.DB.execute()は、DBに対しSQLを発行するためのAPIだ。特に何の設定をしなくても、Jaxerに組み込まれたSQLiteと呼ばれるDBを、ストレージとして利用することができる。

  Jaxer.DB.execute(
    "create table if not exists account(" +
    "  user_id primary key, password not null" +
    ")")

 ここでは、ユーザ情報を格納するためのaccountテーブルを作成している。「if not exists」句はSQLite固有の方言で、「テーブルが存在しないときに限って作成する」と言う効果を持つ。

 (3) ログイン処理を行うためのauthenticate()と言う関数の定義を行っている。この関数はクライアント側から呼び出されることを想定しているため、スクリプトブロックに対してrunat="server-proxy"を指定している。authenticate()は次のような処理を行うメソッドとする。

 「指定されたユーザIDとパスワードでDBを検索し、ユーザが存在したら、セッションにユーザ情報を格納して返す。存在しない場合はnullを返す」

ここでもJaxer.DB.execute()を用いてSQLを発行している。

var result = Jaxer.DB.execute(
    "select * from account where user_id = ? and password = ?",
    [userId, password]);

 見て分かるの通り、SQL文中に「?」をプレースホルダとして用い、それを置き換えるための引数を配列で指定することができる。

 Jaxer.DB.execute()の戻り値はJaxer.ResultSetクラスのインスタンスで、行のデータを取得するためのrowsプロパティなどを備えている(APIドキュメントを参照してほしい)。

  • (4) ここで行っているのは、DBから取得したユーザ情報をセッションスコープに格納する、と言う処理だ。検索結果(Jaxer.ResultSetのオブジェクト)のrowsプロパティは、行データを格納したオブジェクトの配列となっている。

    // (4) ユーザが存在したら、セッションにオブジェクトをセット if (result.rows.length > 0) { var user = result.rows[0]; Jaxer.session.set("user", user); return user; }

 Jaxer.sessionは、ユーザのログインセッションを表しており、set()get()というメソッドを用いてオブジェクトを格納しておくことができる。サーブレットに置ける「スコープ」とほぼ同じだ。

 こうしたスコープは、やはりサーブレットと同じく複数定義されている。以下にその一覧を示す。

  • Jaxer.application ・・・アプリケーションスコープ(「アプリケーション」の定義は、configRoutes.jsと言うファイルで設定可能)
  • Jaxer.session ・・・セッションスコープ。ユーザごとに区別され、全てのページで共有される。
  • Jaxer.sessionPage ・・・セッションと同じだが、ページ間で共有されることはない。
  • Jaxer.page ・・・ページごとに存在するスコープ。ユーザのセッションとは関係がない。

    • (5) クライアント側で動作するコードは以下のようになる。$F()はprototype.jsのAPIで、入力要素の値を取得するためのものだ。入力されたユーザIDとパスワードを、authenticate()メソッドの非同期版(前回記事参照)である「authenticateAsync()」を呼び出す。非同期呼び出しの結果は、関数「authResult()」で受け取り、認証OKの場合はメイン画面に遷移する。

      // (5) クライアント側で動作するコード function login() { var userId = $F("userId"); var password = $F("password"); if (!userId || !password) { alert("ユーザID、もしくはパスワードが入力されていません。"); return; } authenticateAsync(authResult, userId, password); } function authResult(user) { if (user) location.href = "main.html"; else alert("ユーザID、もしくはパスワードが不正です。"); }

ログイン画面で学んだことのまとめ

  • JaxerはデータベースアクセスのためのAPIを備えており、Jaxer.DB.execute()でSQLを発行することができる。execute()の戻り値はJaxer.ResultSetクラスのインスタンス。
  • Jaxerには、最初からSQLiteデータベースが組み込まれており、特に設定をせずともデータベースアクセスを行うことができる。
  • Jaxer.sessionプロパティは、セッションスコープのコンテナを表す。他にも様々なスコープコンテナが存在する。
  • サーバプロキシの呼び出し方法
記事の感想やご意見をコメントでお寄せください(CNET_IDログインが必要です)
ログイン パスワードを忘れた方  |  新規登録
米フォレスター・リサーチ社 シニアアナリスト Jeremiah K.Owyang氏を迎え、同氏が提唱するソーシャルテクノロジーを効果的に活用方法するための方法『POST』を日本で初めて紹介する注目のリアルイベント
  • 今日のトップ記事
  • 昨日
  • 2日前
  • 5日前
  • 6日前
  • 7日前
  • 新着記事
  • 人気記事
  • 特集
  • ブログ