HTAによるクロスドメインAJAXの可能性

AJAXで使用するXMLHttpRequestには、異なるサーバーにアクセスできない(クロスドメインで使用できない)という大きな弱点があります。このため、Webサービスの利用など他サーバーのXMLアクセスを行う場合はWebブラウザに変わってHTTPアクセスを行うサーバー側の代理アクセスプログラムを作成したりIFrameでフレームを切ってアクセスしたりと様々な方策が講じられていますが、実行環境をIEに限れば、XMLHttpRequestではなくXMLHttpRequestの元祖とも言うべきMSXMLオブジェクトを使用することでこの問題を回避できます。
ただ、どうせIE限定にするのなら、WebにこだわらずHTAにしてしまうのも良いかもしれません。HTAなら、記述法はWebとほぼ同じ(HTML+CSS+スクリプト)でクロスドメインアクセスはもちろん、ローカルのファイルやActiveX(COM)までアクセスできるので、一気に可能性が広がりますからね。
複数のサーバー上のWebサービスにアクセスし、取得、処理した情報をローカルにファイルとして保存する。そんなことも可能になるのです。

今回は、そんなHTAベースのWebサービスを利用したAJAX(と言えるのかな?)アプリケーションとして、指定キーでWikiの情報を取得するHTAを作成してみましょう。

wikipediaデータ取得Webサービスの利用

今回使用させていただくのは、WikipediaAPIというXMLベースのWebサービスです。これは、REST形式で検索キーワードなどの引数を付けて指定URLにアクセスすると、その引数を元にwikipediaのデータを検索し関連データがXMLで返されるWebサービスで、外部から自由に利用できるよう公開されています。

返されるXMLは、

<results>
  <result>
    ・
    ・
    <title>タイトル</title>
    <body>本文</title>
    ・
    ・
  </result>
  <result>
    ・
    ・
    <title>タイトル</title>
    <body>本文</title>
    ・
    ・
  </result>
</results>

という形式で、指定キーワードに前方一致したwikipedia記事の一覧データが返されてきます。今回は、このWebサービスを利用して指定キーワードに一致した文書のタイトルと本文を表示するHTAを作ってみました。

HTAの構造

今回のHTAは、検索するキーの入力欄と検索ボタンというGUIフォームと実際にWebサービスにアクセスするなどの処理を行うJavaScriptの関数から構成されています。流れとしては、まずテキスト入力欄に検索キーを入力して検索ボタンをクリックすると、Webサービスを呼び出して検索結果を取得し、配列に保存、表示領域にタイトルの一覧を表示します。続いて、タイトルの部分をクリックするとそのタイトルに対応した本文がタイトルの下に表示される、という形にしてみました。
WebサービスへのアクセスとHTML要素の動的変更というAJAXの基本的な流れを確認するわけですね。まぁ、ボタンをクリックして情報取得というのは、あまりAJAXらしくない気もしますが。

Webサービスのアクセスには、Microsoft.XMLDOMオブジェクトを使用しています。検索ボタンがクリックされたらloadDocument()が呼び出され、その中でMicrosoft.XMLDOMのインスタンスを作成、入力欄の内容からWebサービスに渡す引数を埋め込んだURLを作成し、XMLを取得しています。
XMLを取得したら、そこからresultタグのリストを取得して各文書のタイトルと本文を配列に保存、タイトル一覧のHTMLを表示領域のinnerHTMLに設定して表示するようにしてみました。

  resultTitleList = new Array();
  resultBodyList = new Array();

  function loadDocument() {

    // 検索キー取得
    key = document.control.key.value;

    // XMLDOMオブジェクト作成
    var doc = new ActiveXObject("Microsoft.XMLDOM");

    // 非同期設定
    doc.async = false;

    // WebサービスURL設定
    url = 'http://wikipedia.simpleapi.net/api';
    url += '?keyword=' + encodeURI(key);

    // XML文書取得
    doc.load(url);

    // XML内resultタグ取得
    var results = doc.selectNodes('//results/result');

    // タイトル、文書保存配列作成
    resultTitleList = new Array();
    resultBodyList = new Array();

    // resultタグの内容を保存
    for(i = 0;i < results.length;i++){

      var body = results.item(i).selectSingleNode('body');
      var title = results.item(i).selectSingleNode('title');

      resultBodyList[i] = body.nodeTypedValue;
      resultTitleList[i] = title.nodeTypedValue;

    }

    var resultHtml = new String;

    // タイトルを列挙したHTMLタグ作成
    for (i = 0;i < results.length;i++) {
      resultHtml += '<h2 onClick="showBody(' + i + ')">' + resultTitleList[i] + "</h2>";
    }

    // 表示領域に表示
    result.innerHTML = resultHtml;

  }

こうして表示されたタイトルがクリックされると、そのタイトルに応じた本文をshowBody()でタイトルの下に表示します。これは、先に保存しておいた本文の内容を追加して表示用のHTMLを差し替えるだけですね。

  // 選択タイトルの文書を表示
  function showBody(index) {

    if (index < 0 || index >= resultBodyList.length) {
      return;
    }

    resultHtml = '';

    for (i = 0;i < resultTitleList.length;i++) {

      resultHtml += '<h2 onClick="showBody(' + i + ')">' + resultTitleList[i] + "</h2>";

      if (i == index) {
        resultHtml += resultBodyList[i];
      }

    }

    result.innerHTML = resultHtml;

  }

ネットで面白そうなWebサービスを見つけたら、そのWebサービスを利用してHTAを作成してみましょう。

HTAダウンロード

戻る