« BPMオフ会に参加してきた(飲み会だけ) | メイン | IEのメモリリーク検出 »

JAXERでサーバサイドjQueryが超便利

 一昨日に引き続きJaxerの話。

今回は、jQueryをサーバサイドでも使えるよという内容です。

jQueryを一度でも使ったことのある方は、その便利さに、もうjQueryなしには生きられない感じになってしまってるのではないでしょうか(僕だけか?)。

John Resigのサンプルコード

jQueryを作ったJohn Resigさんのブログで、jQueryをサーバサイドでも使うというサンプルコードが公開されています

<html>
<head>
  <script src="http://code.jquery.com/jquery.js" runat="both"></script>
  <script>
    jQuery(function($){
      $("form").submit(function(){
        save( $("textarea").val() );
        return false;
      });
    });
  </script>
  <script runat="server">
    function save( text ){
      Jaxer.File.write("tmp.txt", text);
    }
    save.proxy = true;
   
    function load(){
      $("textarea").val(
        Jaxer.File.exists("tmp.txt") ? Jaxer.File.read("tmp.txt") : "");
    }
  </script>
</head>
<body onserverload="load()">
  <form action="" method="post">
    <textarea></textarea>
    <input type="submit"/>
  </form>
</body>
</html>

とりあえず、上記コードをテキストにコピペして、index.htmlと名前をつけ、jaxerのpublicフォルダの下に配置しましょう。

サーバが起動している状態であれば、http://localhost:8081/ でアクセスすることができます。

すると↓こんな画面が表示されます。

jaxer_003.png

この画面で、テキストエリアに文字を入力し、「クエリ送信」をクリックすると、index.htmlを配置しているディレクトリに、テキストエリアの内容が書かれたtmp.txtが出力されます。

一度画面を閉じ、再度ページを表示すると、先ほど入力した値が、デフォルト値としてテキストエリア内に表示されます。

というわけで、サンプルコードのコード解説です。

1~3行目

<html>
<head>
  <script src="http://code.jquery.com/jquery.js" runat="both"></script>

jQueryを読み込み、runat="both"で、このコードをサーバとクライアントの両方で利用することを宣言しています。

4~11行目 

 <script>
    jQuery(function($){
      $("form").submit(function(){
        save( $("textarea").val() );
        return false;
      });
    });
  </script>

ドキュメント中のformエレメントのsubmitイベントに、テキストエリア内の値を引数としてsave関数を実行するようにバインドしています。このscriptタグにrunat属性はないので、必然的にクライアント側でのコードとなります。

12~22行目

  <script runat="server">
    function save( text ){
      Jaxer.File.write("tmp.txt", text);
    }
    save.proxy = true;
   
    function load(){
      $("textarea").val(
        Jaxer.File.exists("tmp.txt") ? Jaxer.File.read("tmp.txt") : "");
    }
  </script>

runat="server"なので、サーバ側での関数定義です。

saveは、引数で渡された値を、tmp.txtとしてファイルに書き出します。

loadは、tmp.txtが存在すれば、その内容をページ中のテキストエリアの値としてセットします。

save関数は、proxy=trueとされており、これでクライアント側のJavaScriptからsave関数をコールすることができます。逆に、load関数は指定がないので、クライアント側から呼び出すことはできません。

また、サーバ側で動作するこのコードで、$("textarea").val()と、jQueryのコードが書けているのも注目です。

23~30行目

</head>
<body onserverload="load()">
  <form action="" method="post">
    <textarea></textarea>
    <input type="submit"/>
  </form>
</body>
</html>

bodyタグのonserverloadという指定で、ページ表示時にload関数が実行されるようになっています。

サーバ側でjQueryを使うことで何が便利になるのか?

基本的にjQueryはDOMを簡単に直感的に利用できるライブラリになっており、サーバサイドでの出番はあまりないようにも思えます。

では、サーバサイドでjQueryを使うメリットはどんな点なのか。

1つは、「入力フォームの値をset / get しやすい」という点です。

これは今回のサンプルでも明らかだと思います。

もしjQueryを利用していなければ、値のset / get は以下のようになって、コードも長くなり少々面倒です。

document.getElementById('hoge').value = 'moge';

document.forms[0].hoge.value = 'moge';

もう1つは、「スクレイピングしやすい」という点です。

Jaxerでは、以下のコードで任意のページのHTMLを取得できます。

Jaxer.Web.get(url);

これを利用すると、以下のようにjQueryのselectorを用いて取得したHTMLを操作することができます。

$('selector',Jaxer.Web.get(url))

例えば、ページ中のaタグのhref要素を全部取得する場合は、

     var txt = '';
     $('a',Jaxer.Web.get(url)).each(function(){
       txt += $(this).attr('href') + '\n';
     });

こんな感じで。

このままだと正規表現の方が簡単じゃんってことかもしれませんが、ページ中の特定の部分の中身からurlを抜き出したりとかできて、個人的には正規表現でゴリゴリ書くよりやりやすいです(まあ僕が正規表現苦手なだけですが)。

ただ、jQueryのメソッドすべてがサポートされているわけではないので、注意が必要。

Jaxer付属のサンプルページで、jQueryのユニットテストの動作結果が確認できます。

<関連エントリ>