ほとんどの Web アプリケーションは、リクエスト/レスポンス モデルを使用して、サーバーから完全な HTML ページを取得します。多くの場合、ボタンをクリックし、サーバーの応答を待ち、別のボタンをクリックし、再度待つという繰り返しのプロセスになります。 Ajax と XMLHttpRequest オブジェクトを使用すると、ユーザーがサーバーからの応答を待つ必要のない要求/応答モデルを使用できます。この記事では、Brett McLaughlin が、さまざまなブラウザーに適応し、リクエストを確立して送信し、サーバーに応答できる XMLHttpRequest インスタンスを作成する方法を説明します。
このシリーズの前の記事 (リンクについては「参考文献」を参照) では、Ajax アプリケーションを紹介し、Ajax アプリケーションを推進する基本概念を検討しました。この中心となるのは、JavaScript、HTML、XHTML、少しの動的 HTML、DOM (Document Object Model) など、おそらくすでにご存知の多くのテクノロジです。この記事では、1 つの点に焦点を当て、特定の Ajax の詳細に焦点を当てます。
この記事では、Ajax に関連する最も基本的なオブジェクトとプログラミング メソッドである XMLHttpRequest オブジェクトについて学び始めます。このオブジェクトは実際には、すべての Ajax アプリケーションにまたがる共通のスレッドにすぎません。ご想像のとおり、プログラミングの可能性を最大限に発揮するには、このオブジェクトを徹底的に理解する必要があります。実際、XMLHttpRequest を正しく使用するために、明らかに XMLHttpRequest を使用できないことがわかることがあります。何が起こっているのか?
Web 2.0 の概要
コードを詳しく説明する前に、最近の視点を見てみましょう。Web 2.0 の概念を明確に理解することが重要です。 Web 2.0 という言葉を聞いたとき、まず「Web 1.0 とは何ですか?」と尋ねる必要があります。Web 1.0 について言及する人はほとんどいませんが、実際には、まったく異なるリクエストとレスポンスのモデルを持つ従来の Web を指します。たとえば、Amazon.com の Web サイトにアクセスし、ボタンをクリックするか、検索語を入力します。リクエストがサーバーに送信され、レスポンスがブラウザに返されます。リクエストは単なる書籍とタイトルのリストではなく、別の完全な HTML ページです。したがって、Web ブラウザが新しい HTML でページを再描画するときに、ちらつきやジッターが発生する場合があります。実際、新しいページが表示されるたびに、リクエストとレスポンスがはっきりと表示されます。
Web 2.0 では、この目に見えるやり取りが (大幅に) 排除されます。たとえば、Google マップや Flickr などのサイトにアクセスします (これらの Web 2.0 および Ajax 対応サイトへのリンクについては、「参考文献」を参照してください)。たとえば、Google マップでは、最小限の再描画で地図をドラッグして拡大または縮小できます。もちろん、まだリクエストやレスポンスはありますが、それらは舞台裏に隠されています。ユーザーとしては、エクスペリエンスがより快適になり、デスクトップ アプリケーションのように感じられます。この新しい感覚とパラダイムは、誰かが Web 2.0 について言及したときに得られるものです。
懸念されるのは、こうした新しい相互作用を可能にすることです。もちろん、引き続きリクエストを作成し、レスポンスを受信する必要がありますが、リクエストとレスポンスの対話ごとに HTML が再描画されるため、Web 対話が遅くてぎこちない印象を与えます。したがって、HTML ページ全体ではなく、必要なデータのみを含むリクエストを送信し、レスポンスを受信する方法が必要であることは明らかです。新しい HTML ページ全体を取得する必要があるのは、ユーザーに新しいページを表示する場合だけです。
ただし、ほとんどのインタラクションでは、既存のページに詳細を追加したり、メイン テキストを変更したり、元のデータを上書きしたりします。このような場合、Ajax および Web 2.0 メソッドを使用すると、HTML ページ全体を更新せずにデータを送受信できます。オンラインで多くの時間を費やす人にとって、この機能によりアプリケーションの速度と応答性が向上し、アプリケーションが時々サイトに戻ってくるようになります。
XMLHttpRequest の概要
この素晴らしい奇跡を真に実現するには、JavaScript オブジェクト、つまり XMLHttpRequest についてよく知っている必要があります。この小さなオブジェクトは実際、しばらくの間いくつかのブラウザで存在しており、Web 2.0、Ajax、そして今後数か月間このコラムで取り上げる他の多くのものの中心となっています。簡単に概要を説明するために、このオブジェクトで使用されるメソッドとプロパティのほんの一部をここに示します。
·open(): サーバーへの新しいリクエストを確立します。
・send(): サーバーにリクエストを送信します。
·abort(): 現在のリクエストを中止します。
·readyState: 現在の HTML の準備完了状態を提供します。
·responseText: サーバーから返されたリクエスト応答テキスト。
これら (またはそのいずれか) を知らなくても心配する必要はありません。各メソッドとプロパティについては、次のいくつかの記事で説明します。ここで知っておくべきことは、まさに XMLHttpRequest をどうするかということです。これらのメソッドとプロパティは、要求の送信と応答の処理に関連していることに注意してください。実際、XMLHttpRequest のすべてのメソッドとプロパティを見ると、それらはすべて非常に単純な要求/応答モデルに関連していることがわかります。明らかに、特に新しい GUI オブジェクトや、ユーザー インタラクションを作成するための非常に難解な方法に遭遇することはなく、非常に単純なリクエストと非常に単純な応答を使用します。大したことではないように聞こえるかもしれませんが、このオブジェクトをうまく使用すると、アプリケーションに革命を起こすことができます。
Simple New
では、まず新しい変数を作成し、それに XMLHttpRequest オブジェクト インスタンスを割り当てる必要があります。これは、リスト 1 に示すように、JavaScript でオブジェクト名に new キーワードを使用するだけで簡単です。
リスト 1. 新しい XMLHttpRequest オブジェクトの作成
<script language="javascript" type="text/javascript">
var request = 新しい XMLHttpRequest();
</script>
難しくないですか? JavaScript では変数の型を指定する必要がないため、リスト 2 で行うこと (Java 言語では行う可能性があります) を行う必要がないことに注意してください。
リスト 2. XMLHttpRequest を作成するための Java 疑似コードXMLHttpRequest
request = new XMLHttpRequest();
したがって、JavaScript では、var を使用して変数を作成し、それに名前 (「request」など) を付けて、それに新しい XMLHttpRequest インスタンスを割り当てます。その後、オブジェクトを関数で使用できるようになります。
エラー処理
実際にはあらゆる種類のエラーが発生する可能性があり、上記のコードはエラー処理を提供しません。より良いアプローチは、オブジェクトを作成し、何か問題が発生した場合に正常に終了することです。たとえば、古いブラウザ (信じられないかもしれませんが、古いバージョンの Netscape Navigator を使用している人がまだいます) は XMLHttpRequest をサポートしていないため、これらのユーザーに問題があることを知らせる必要があります。リスト 3 は、問題が発生したときに JavaScript 警告を発行するこのオブジェクトを作成する方法を示しています。
リスト 3. エラー処理機能を備えた XMLHttpRequest の作成
<script language="javascript" type="text/javascript">
var リクエスト = false;
試す {
リクエスト = 新しい XMLHttpRequest();
} キャッチ (失敗) {
リクエスト = 偽;
if
(!リクエスト)
alert("XMLHttpRequest の初期化中にエラーが発生しました!");
</script>
次の手順を必ず理解してください。
1. 新しい変数リクエストを作成し、値 false を割り当てます。 Falseは、後の判定条件として使用されます。これは、XMLHttpRequestオブジェクトがまだ作成されていないことを意味します。
2. try/catch ブロックを追加します。
1) XMLHttpRequest オブジェクトを作成してみます。
2) 失敗した場合 (catch (failed))、request の値は false のままであることが保証されます。
3. リクエストがまだ false であるかどうかを確認します (すべてが正常であれば false にはなりません)。
4. 問題が発生した場合 (リクエストが false)、JavaScript 警告を使用して問題が発生したことをユーザーに通知します。
コードは非常に単純で、ほとんどの JavaScript および Web 開発者にとって、コードを読み書きするよりもコードを真に理解するのに時間がかかります。これで、エラー チェックされ、何が問題だったかを知ることができる XMLHttpRequest オブジェクト作成コードが完成しました。
少なくとも Internet Explorer でコードを試すまでは、
Microsoft では
すべて問題ないようです。このように実験してみると、図 1 に示すような悪い状況がわかります。
図 1. Internet Explorer のレポート エラー
明らかに何かが間違っています。Internet Explorer は世界の 70% で使用されているため、決して古いブラウザではありません。つまり、Microsoft と Internet Explorer をサポートしていなければ、Web の世界で人気はありません。したがって、Microsoft ブラウザでは別のアプローチを取る必要があります。
Microsoft が Ajax をサポートしていることが確認されましたが、その XMLHttpRequest バージョンの名前は異なります。実際、それはいくつかの異なる呼び名です。新しいバージョンの Internet Explorer を使用する場合は、オブジェクト Msxml2.XMLHTTP を使用する必要がありますが、古いバージョンの Internet Explorer は Microsoft.XMLHTTP を使用します。両方のオブジェクト タイプ (および Microsoft 以外のブラウザ) をサポートする必要があります。リスト 4 を見てください。このコードは前述のコードを基にして Microsoft のサポートを追加しています。
マイクロソフトは関与していますか?
Ajax と Microsoft のこの分野への関心と関与の高まりについては、多くのことが書かれています。実際、Microsoft の Internet Explorer の最新バージョン (2006 年後半にリリース予定のバージョン 7.0) では、XMLHttpRequest の直接サポートが開始され、すべての Msxml2.XMLHTTP 作成コードの代わりに新しいキーワードを使用できるようになると言われています。ただし、あまり興奮しないでください。古いブラウザも引き続きサポートする必要があるため、クロスブラウザ コードがすぐになくなるわけではありません。
リスト 4. Microsoft ブラウザーのサポートの追加
<script language="javascript" type="text/javascript">
var リクエスト = false;
試す {
リクエスト = 新しい XMLHttpRequest();
キャッチ (trymicrosoft) {
試す {
request = new ActiveXObject("Msxml2.XMLHTTP");
} キャッチ (その他マイクロソフト) {
試す {
request = new ActiveXObject("Microsoft.XMLHTTP");
} キャッチ (失敗) {
リクエスト = 偽;
}
}
if
(!リクエスト)
alert("XMLHttpRequest の初期化中にエラーが発生しました!");
</script>
これらの中括弧によって混乱しやすいため、各手順を以下に紹介します。
1. 新しい変数リクエストを作成し、値 false を割り当てます。判定条件はXMLHttpRequestオブジェクトがまだ作成されていないことを意味するfalseを指定します。
2. try/catch ブロックを追加します。
1) XMLHttpRequest オブジェクトを作成してみます。
2) 失敗した場合 (キャッチ (trymicrosoft)):
1>新しいバージョンの Microsoft ブラウザを使用して、Microsoft 互換オブジェクト (Msxml2.XMLHTTP) を作成してみてください。
2> 失敗した場合 (catch (othermicrosoft))、古いバージョンの Microsoft ブラウザを使用して Microsoft 互換オブジェクト (Microsoft.XMLHTTP) の作成を試みます。
2) 失敗した場合 (catch (failed))、request の値は false のままであることが保証されます。
3. リクエストがまだ false であるかどうかを確認します (すべてがうまくいけば false にはなりません)。
4. 問題が発生した場合 (リクエストが false)、JavaScript 警告を使用して問題が発生したことをユーザーに通知します。
この方法でコードを変更し、Internet Explorer を使用してテストすると、作成されたフォームが (エラー メッセージなしで) 表示されるはずです。私の実験結果を図 2 に示します。
図 2. Internet Explorer が正常に動作している
静的と動的
リスト 1、3、および 4 をもう一度見てください。このコードはすべて script タグ内に直接ネストされていることに注目してください。このように、メソッドや関数の本体に配置されていない JavaScript コードは、静的 JavaScript と呼ばれます。これは、ページがユーザーに表示される前のある時点でコードが実行されることを意味します。 (仕様では、このコードが実行されるときにブラウザーにどのような影響を与えるかは正確にはわかりませんが、ユーザーがページを操作する前にコードが実行されることが保証されています。) これは、ほとんどの場合の一般的な方法でもあります。 Ajax プログラマは XMLHttpRequest オブジェクトを作成します。
つまり、このコードをリスト 5 のようなメソッドに組み込むこともできます。
リスト 5. XMLHttpRequest 作成コードをメソッドに移動する
<script language="javascript" type="text/javascript">
var リクエスト
関数 createRequest() {
試す {
リクエスト = 新しい XMLHttpRequest();
キャッチ (trymicrosoft) {
試す {
request = new ActiveXObject("Msxml2.XMLHTTP");
} キャッチ (その他マイクロソフト) {
試す {
request = new ActiveXObject("Microsoft.XMLHTTP");
} キャッチ (失敗) {
リクエスト = 偽;
}
}
if
(!リクエスト)
alert("XMLHttpRequest の初期化中にエラーが発生しました!");
}
</script>
この方法でコードを作成した場合は、Ajax を処理する前にこのメソッドを呼び出す必要があります。したがって、リスト 6 のようなコードも必要になります。
リスト 6. XMLHttpRequest を使用したメソッドの作成
<script language="javascript" type="text/javascript">
var リクエスト
関数 createRequest() {
試す {
リクエスト = 新しい XMLHttpRequest();
キャッチ (trymicrosoft) {
試す {
request = new ActiveXObject("Msxml2.XMLHTTP");
} キャッチ (その他マイクロソフト) {
試す {
request = new ActiveXObject("Microsoft.XMLHTTP");
} キャッチ (失敗) {
リクエスト = 偽;
}
}
if
(!リクエスト)
alert("XMLHttpRequest の初期化中にエラーが発生しました!");
関数
getCustomerInfo() {
createRequest();
// リクエスト変数を使って何かを行う
}
</script>
このコードの唯一の問題は、エラー通知が遅れることです。そのため、ほとんどの Ajax プログラマはこのアプローチを使用しません。 10 または 15 のフィールド、選択ボックスなどを含む複雑なフォームがあり、ユーザーが 14 番目のフィールド (フォームの順序で上から下) にテキストを入力したときに Ajax コードをアクティブにしたいとします。この時点で getCustomerInfo() を実行すると XMLHttpRequest オブジェクトの作成が試行されますが、(この場合は) 失敗します。その後、ユーザーには、アプリを使用できないことを明確に示す警告が表示されます。しかし、ユーザーはすでにフォームにデータを入力することに多くの時間を費やしています。これは非常に煩わしいことであり、煩わしいとユーザーが再びサイトに戻ってくることは明らかではありません。
静的 JavaScript を使用すると、ユーザーがページをクリックするとすぐにエラー メッセージが表示されます。それも面倒ですよね。ユーザーは、Web アプリケーションが自分のブラウザでは実行できないと誤解する可能性があります。しかし、情報入力に 10 分を費やして後で同じエラーが表示されるよりは、確実に良いでしょう。したがって、ユーザーが問題をできるだけ早く検出できるように静的コードを作成することをお勧めします。
XMLHttpRequest でリクエストを送信し
、リクエスト オブジェクトを取得した後、リクエスト/レスポンス サイクルに入ることができます。 XMLHttpRequest の唯一の目的は、リクエストを送信してレスポンスを受信できるようにすることであることに注意してください。それ以外のすべては、ユーザー インターフェイスの変更、画像の切り替え、サーバーから返されたデータの解釈など、ページ内の JavaScript、CSS、またはその他のコードの仕事です。 XMLHttpRequest を準備したら、リクエストをサーバーに送信できます。
サンドボックスへようこそ
Ajax はサンドボックス セキュリティ モデルを使用します。したがって、Ajax コード (具体的には XMLHttpRequest オブジェクト) は、それが配置されているのと同じドメインにのみリクエストを送信できます。セキュリティと Ajax については今後の記事で詳しく説明しますが、ここでは、ローカル マシンで実行されているコードは、ローカル マシン上のサーバー側スクリプトにのみリクエストを送信できることだけを知っておいてください。 Ajax コードをwww.breakneckpizza.comで実行したい場合は、 www.breakneck.comで実行されているスクリプトからリクエストを送信する必要があります。
サーバー URL を設定するには、
まず接続するサーバーの URL を決定する必要があります。これは Ajax の特別な要件ではありませんが、接続を確立する必要があるため、URL の構築方法を知っておく必要があります。ほとんどのアプリケーションでは、この URL は、いくつかの静的データとユーザーが処理するフォームからのデータの組み合わせから構築されます。たとえば、リスト 7 の JavaScript コードは電話番号フィールドの値を取得し、それを使用して URL を構築します。
リスト 7. リクエスト URL の作成
<script language="javascript" type="text/javascript">
var リクエスト = false;
試す {
リクエスト = 新しい XMLHttpRequest();
キャッチ (trymicrosoft) {
試す {
request = new ActiveXObject("Msxml2.XMLHTTP");
} キャッチ (その他マイクロソフト) {
試す {
request = new ActiveXObject("Microsoft.XMLHTTP");
} キャッチ (失敗) {
リクエスト = 偽;
}
}
if
(!リクエスト)
alert("XMLHttpRequest の初期化中にエラーが発生しました!");
function getCustomerInfo() {
var Phone = document.getElementById("phone").value;
var url = "/cgi-local/lookupCustomer.php?phone=" +エスケープ(電話);
}
</script>
ここでは理解するのが難しいことは何もありません。まず、コードは新しい変数phoneを作成し、IDが「phone」のフォームフィールドの値をそれに割り当てます。リスト 8 は、このフォームの XHTML を示しています。ここでは、phone フィールドとその id 属性が確認できます。
リスト 8. Break Neck Pizza フォーム
<body>
<p><img src="breakneck-logo_4c.gif" alt="ブレイクネックピザ" /></p>
<form action="POST">
<p>電話番号を入力してください:
<input type="text" size="14" name="電話" id="電話"
onChange="getCustomerInfo();" />
</p>
<p>ご注文は配達されます</p>
<div id="アドレス"></div>
<p>ここに注文を入力してください:</p>
<p><textarea name="order" rows="6"cols="50" id="order"></textarea></p>
<p><input type="submit" value="ピザを注文する" id="submit" /></p>
</form>
また、ユーザーが電話番号を入力するか電話番号を変更すると、リスト 8 に示す getCustomerInfo() メソッドがトリガーされることにも注意してください
。
このメソッドは電話番号を取得し、url 変数に格納される URL 文字列を構築します。 Ajax コードはサンドボックス化されており、同じドメインにのみ接続できるため、実際には URL にドメイン名は必要ないことに注意してください。この例のスクリプトは /cgi-local/lookupCustomer.php という名前です。最後に、電話番号が GET パラメーターとしてスクリプトに追加されます (「phone= +エスケープ(phone)」)。
これまでにエスケープ() メソッドを見たことがない方のために説明します。このメソッドは、クリア テキストで正しく送信できない文字をエスケープするために使用されます。たとえば、電話番号内のスペースは文字 %20 に変換され、これらの文字を URL に渡すことができるようになります。
パラメータは必要なだけ追加できます。たとえば、別のパラメータを追加する必要がある場合は、そのパラメータを URL に追加し、アンパサンド (&) 文字で区切ります (最初のパラメータは疑問符 (?) でスクリプト名から区切られます)。
リクエストを開く
接続先の URL を取得したら、リクエストを構成できます。これは、XMLHttpRequest オブジェクトの open() メソッドを使用して実現できます。このメソッドには 5 つのパラメータがあります。
request-type: 送信するリクエストのタイプ。一般的な値は GET または POST ですが、HEAD リクエストを送信することもできます。
url: 接続先の URL。
asynch: 非同期接続を使用する場合は true、それ以外の場合は false。このパラメータはオプションであり、デフォルトは true です。
ユーザー名: 認証が必要な場合は、ここでユーザー名を指定できます。このオプションのパラメータにはデフォルト値はありません。パスワード: 認証が必要な場合は、ここでパスワードを指定できます。このオプションのパラメータにはデフォルト値はありません。
open()は開きますか?
インターネット開発者は、open() メソッドが正確に何を行うかについて意見が一致していません。しかし、実際にはリクエストは開かれません。 XHTML/Ajax ページとその接続スクリプト間のネットワークとデータ転送を監視すると、open() メソッドが呼び出されたときに通信が表示されません。なぜこの名前が選ばれたのかは不明ですが、明らかに良い選択ではありません。
通常、最初の 3 つのパラメータが使用されます。実際、非同期接続が必要な場合でも、3 番目のパラメータを「true」に指定する必要があります。これはデフォルトですが、リクエストが非同期か同期かを明示的に指定する方が理解しやすいです。
これらを組み合わせると、通常はリスト 9 に示すようなコード行になります。
リスト 9. オープンリクエスト
関数 getCustomerInfo() {
var Phone = document.getElementById("phone").value;
var url = "/cgi-local/lookupCustomer.php?phone=" +エスケープ(電話);
request.open("GET", url, true);
URL を設定したら、あとは簡単です
。
ほとんどのリクエストでは、GET と URL で十分です (後の記事で POST が必要な場合について説明します)。open() メソッドを使用する必要があるのはそれだけです。
非同期性への挑戦
このシリーズの次の記事では、非同期コードの作成と使用に多くの時間を費やしますが、open() の最後のパラメータがなぜそれほど重要なのかを理解する必要があります。 Web 1.0 などの一般的なリクエスト/レスポンス モデルでは、クライアント (ローカル マシン上で実行されているブラウザまたはコード) がサーバーにリクエストを送信します。リクエストは同期的です。つまり、クライアントはサーバーからの応答を待ちます。クライアントが待機している場合、少なくとも何らかの形式で待機が通知されます。
· 砂時計 (特に Windows の場合)。
· 回転ボール (通常 Mac マシン上)。
・基本的にアプリケーションがフリーズし、しばらくするとカーソルが変化します。
これがまさに、Web アプリケーションがぎこちなく感じられたり、遅く感じられたり、真の対話性が欠けている理由です。ボタンが押されると、トリガーされたばかりのリクエストが応答されるまで、アプリケーションは事実上使用できなくなります。リクエストに大量のサーバー処理が必要な場合、待ち時間が長くなる可能性があります (少なくともこのマルチプロセッサ、DSL 待ち時間のない世界では)。
非同期リクエストはサーバーからの応答を待ちません。アプリケーションはリクエストの送信後も実行を続けます。ユーザーは Web フォームにデータを入力したり、フォームから移動したりすることもできます。回転するボールや砂時計はなく、アプリが著しくフリーズすることもありません。サーバーは静かにリクエストに応答し、それが完了すると、元のリクエスタにジョブが完了したことを伝えます (どれくらい早く完了するかはわかります)。その結果、アプリの遅延や動作の遅さは軽減され、応答性、インタラクティブ性が向上し、より速く感じられるようになります。これは Web 2.0 の一部にすぎませんが、重要な部分です。古い GUI コンポーネントと Web デザイン パラダイムはすべて、遅い同期リクエスト/レスポンス モデルを克服できません。
リクエストの送信
open() で設定したら、リクエストを送信できます。幸いなことに、リクエストを送信するメソッドには open() よりも適切な名前が付けられています。それは send() です。
send() にはパラメータが 1 つだけあり、それが送信されるコンテンツです。ただし、この方法を検討する前に、URL 自体を通じてデータをすでに送信していることを思い出してください。
var
url = "/cgi-local/lookupCustomer.php?phone= +scape(phone);
, ただし、URL 自体を介してデータを送信することもできます。実際、GET リクエスト (一般的な Ajax アプリケーションの約 80% で発生) では、URL を使用してデータを送信する方がはるかに簡単です。安全な情報または XML を送信する必要がある場合は、send() を使用してコンテンツを送信することを検討してください (安全なデータと XML メッセージについては、このシリーズの後続の記事で説明します)。 send() を通じてデータを渡す必要がない場合は、このメソッドのパラメータとして null を渡すだけです。したがって、この記事の例で行う必要があるのはこれだけであることがわかります (リスト 10 を参照)。
リスト 10. 送信リクエスト
関数 getCustomerInfo() {
var Phone = document.getElementById("phone").value;
var url = "/cgi-local/lookupCustomer.php?phone=" +エスケープ(電話);
request.open("GET", url, true);
request.send(null);
、
新しいこと、革新的なこと、または非同期的なことはほとんどありません
。
open() メソッド内の小さなキーワード「true」が非同期リクエストを確立することを認めなければなりません。ただし、それ以外のコードは、Java サーブレットと JSP、PHP、または Perl を使用したプログラミングと何ら変わりません。では、Ajax と Web 2.0 の最大の秘密は何でしょうか?その秘密は、XMLHttpRequest の単純なプロパティ onreadystatechange にあります。
最初にこのコードの流れを理解してください (必要に応じてリスト 10 を参照してください)。リクエストを作成してからリクエストを実行します。さらに、リクエストは非同期であるため、JavaScript メソッド (この例では getCustomerInfo()) はサーバーを待機しません。したがって、コードは引き続き実行されます。つまり、メソッドが終了し、コントロールがフォームに返されます。ユーザーは情報の入力を続けることができ、アプリケーションはサーバーを待機しません。
これにより、サーバーがリクエストを完了した後はどうなるのかという興味深い疑問が生じます。答えは、少なくとも現在のコードでは何も起こらないということです。明らかにこれは機能しないため、サーバーは、XMLHttpRequest 経由で送信されたリクエストの処理が完了した後に何を行うかについて、ある種の指示を必要とします。
JavaScript の参照関数:
JavaScript は型指定が弱い言語であり、変数を使用してあらゆるものを参照できます。したがって、関数 updatePage() を宣言すると、JavaScript は関数名も変数として扱います。つまり、変数名 updatePage を使用してコード内で関数を参照できます。
リスト 11. コールバック メソッドの設定
function getCustomerInfo() {
var Phone = document.getElementById("phone").value;
var url = "/cgi-local/lookupCustomer.php?phone=" +エスケープ(電話);
request.open("GET", url, true);
request.onreadystatechange = updatePage;
request.send(null);
このプロパティがコード内のどこに設定されているかに注意することが重要です。このプロパティは、send() が呼び出される前に設定されます
。
このプロパティは、サーバーが完了したリクエストに応答した後に表示できるように、リクエストを送信する前に設定する必要があります。あとは updatePage() メソッドを記述するだけです。これがこの記事の最後のセクションの焦点です。
処理サーバーが
リクエストに応答し、ユーザーは (サーバーがリクエストを処理している間) Web フォームを快適に使用しており、サーバーはリクエストの処理を完了しています。サーバーは、onreadystatechange 属性を調べて、どのメソッドを呼び出すかを決定します。それ以外の場合は、非同期であるかどうかに関係なく、アプリケーションを他のアプリケーションと同様に扱います。つまり、サーバーに応答するメソッドを作成するために必ずしも特別なアクションを実行する必要はなく、フォームを変更したり、ユーザーが別の URL にアクセスできるようにしたり、応答サーバーが必要とするあらゆる操作を行うだけで済みます。このセクションでは、サーバーへの応答と、ユーザーに表示されるフォームの一部を即座に変更する典型的なアクションに焦点を当てます。
コールバックと Ajax
これで、完了時にサーバーに何を行うかを指示する方法がわかりました。XMLHttpRequest オブジェクトの onreadystatechange プロパティを、実行する関数の名前に設定します。このようにして、サーバーがリクエストを処理した後、関数が自動的に呼び出されます。関数のパラメータについても心配する必要はありません。リスト 12 に示す簡単な方法から始めます。
リスト 12. コールバック メソッドのコード
<script language="javascript" type="text/javascript">
var リクエスト = false;
試す {
リクエスト = 新しい XMLHttpRequest();
キャッチ (trymicrosoft) {
試す {
request = new ActiveXObject("Msxml2.XMLHTTP");
} キャッチ (その他マイクロソフト) {
試す {
request = new ActiveXObject("Microsoft.XMLHTTP");
} キャッチ (失敗) {
リクエスト = 偽;
}
}
if
(!リクエスト)
alert("XMLHttpRequest の初期化中にエラーが発生しました!");
function getCustomerInfo() {
var Phone = document.getElementById("phone").value;
var url = "/cgi-local/lookupCustomer.php?phone=" +エスケープ(電話);
request.open("GET", url, true);
request.onreadystatechange = updatePage;
request.send(null);
関数
updatePage() {
alert("サーバーは完了しました!");
}
</script>
サーバーがタスクを完了したことを知らせるために、いくつかの簡単な警告を発行するだけです。このコードを独自の Web ページで試し、ブラウザで開いてください (この例の XHTML を確認したい場合は、リスト 8 を参照してください)。電話番号を入力してフィールドを離れると、ポップアップ警告ウィンドウ (図 3 を参照) が表示されますが、[OK] をクリックすると再び表示されます...
図 3. ポップアップ警告の Ajax コード
ブラウザによっては、フォームのポップアップが停止する前に 2 つ、3 つ、または 4 つの警告が表示される場合があります。どうしたの?要求/応答サイクルの重要な部分である HTTP 準備状態を考慮していないことがわかりました。
HTTP 準備完了状態
前述したように、サーバーはリクエストの完了後に XMLHttpRequest の onreadystatechange 属性で呼び出されるメソッドを探します。これは真実ですが、不完全です。実際、HTTP の準備完了ステータスが変化するたびに、このメソッドが呼び出されます。これはどういう意味ですか?まず、HTTP の準備状態を理解する必要があります。
HTTP 準備完了ステータスは、リクエストのステータスまたは条件を表します。これは、リクエストが開始されたか、レスポンスを受信したか、リクエスト/レスポンス モデルが完了したかを判断するために使用されます。また、サーバーから提供された応答テキストやデータを読んでも安全かどうかを判断するのにも役立ちます。 Ajax アプリケーションでは、次の 5 つの準備状態に注意する必要があります。
·0: リクエストは発行されていません (open() が呼び出される前)。
·1: リクエストは確立されていますが、まだ送信されていません (send() が呼び出される前)。
·2: リクエストは送信され、処理中です (コンテンツ ヘッダーは通常、レスポンスから取得できます)。
·3: リクエストは処理されており、通常は応答で一部のデータが利用可能ですが、サーバーは応答を完了していません。
·4: 応答が完了し、サーバー応答にアクセスして使用できるようになります。
ほとんどのクロスブラウザーの問題と同様、これらの準備完了状態は一貫して使用されません。タスクの準備状況が 0 から 1、2、3、4 に変化することを期待するかもしれませんが、実際にはそうではありません。ブラウザによっては、0 や 1 を報告せず、直接 2 から始まり、次に 3 と 4 を報告するものもあります。他のブラウザはすべてのステータスを報告します。他の人は準備完了ステータス 1 を複数回報告します。前のセクションで見たように、サーバーは updatePage() を複数回呼び出し、呼び出されるたびに警告ボックスがポップアップ表示されます。これは予期したものと異なる場合があります。
Ajax プログラミングの場合、直接処理する必要がある唯一の状態は準備完了状態 4 です。これは、サーバーの応答が完了し、応答データが安全に使用できることを示します。これに基づくと、コールバック メソッドの最初の行はリスト 13 のようになります。
リスト 13. 準備状況のチェック
関数 updatePage() {
if (request.readyState == 4)
alert("サーバーは完了しました!");
、
サーバーの処理が完了したことを確認できます。新しいバージョンの Ajax コードを実行してみると、予想通り、警告メッセージが 1 回だけ表示されることがわかります。
HTTPステータスコード
リスト13のコードは問題ないようですが、問題があります - サーバーがリクエストに応答して処理を完了したがエラーを報告した場合はどうなりますか?サーバー側のコードは、Ajax、JSP、プレーン HTML フォーム、またはその他の種類のコードによって呼び出されていることを理解する必要がありますが、従来の Web 固有のメソッドを使用した情報しかレポートできないことに注意してください。 Web の世界では、HTTP コードはリクエストで発生する可能性のあるさまざまな問題を処理できます。
たとえば、間違った URL リクエストを入力して、ページが存在しないことを意味する 404 エラー コードが表示されたという状況に遭遇したことがあるはずです。これは、HTTP リクエストで受信できる多くのエラー コードの 1 つにすぎません (ステータス コードの完全なリストについては、「参考文献」のリンクを参照してください)。アクセス中のデータが保護または禁止されていることを示す 403 と 401 も一般的です。いずれの場合も、これらのエラー コードは完了した応答から取得されます。つまり、サーバーはリクエストを実行しましたが (つまり、HTTP 準備完了ステータスは 4)、クライアントが予期したデータを返しませんでした。
したがって、準備完了ステータスに加えて、HTTP ステータスも確認する必要があります。予期されるステータス コードは 200 で、すべてが正常に完了したことを意味します。準備完了ステータスが 4 でステータス コードが 200 の場合、サーバーのデータを処理できます。そのデータは (エラーやその他の問題のある情報ではなく) 要求されたデータであるはずです。したがって、リスト 14 に示すように、コールバック メソッドにステータス チェックを追加する必要もあります。
リスト 14. HTTP ステータス コードのチェック
function updatePage() {
if (request.readyState == 4)
if (request.status == 200)
alert("サーバーは完了しました!");
1
つまたは 2 つ追加することで過度の複雑化を回避するには、リスト 15 の updatePage() の修正バージョンを見てください。
リスト 15. 小さなエラーチェック
関数を追加します updatePage() {
if (request.readyState == 4)
if (request.status == 200)
alert("サーバーは完了しました!");
else if (request.status == 404)
alert("リクエスト URL が存在しません");
それ以外
alert( "エラー:ステータスコードは" + request.status);
、
getCustomerInfo() の URL を存在しない URL に変更して、何が起こるかを確認します。要求された URL が存在しないことを示す警告メッセージが表示されます。これは素晴らしいことです。すべてのエラー条件を処理することは困難ですが、この小さな変更は、典型的なWebアプリケーションの問題の80%をカバーできます。
応答テキストを読み取ると
、リクエストが(準備が整ったステータスを介して)処理され、サーバーが通常の応答(ステータスコードを介して)を提供し、最後にサーバーが返すデータを処理できます。返されたデータは、XMLHTTPREQUESTオブジェクトのRespondTextプロパティに保存されます。
形式や長さなどの応答テキストでのテキストの内容は、意図的に曖昧なままです。このようにして、サーバーはテキストをあらゆるものに設定できます。たとえば、1つのスクリプトはコンマ区切りの値を返す場合があり、別のスクリプトはパイプ(|文字)を使用して値を分離し、さらに別のスクリプトは長いテキスト文字列を返します。どこに行くべきかを決めるのはサーバー次第です。
この記事で使用した例では、サーバーはパイプ文字で区切られた顧客の最後の注文と顧客アドレスを返します。次に、順序とアドレスを使用して、フォームの要素値を設定します。
リスト16。サーバー応答
機能updatepage(){
if(request.readystate == 4){
if(request.status == 200){
var response = request.responsetext.split( "|");
document.getElementById( "order")。value = response [0];
document.getElementById( "address")。innerhtml =
応答[1] .replace(/ n/g、 "");
} それ以外
alert( "status is" + request.status);
}
}
最初に、ResponseTextを取得し、JavaScript split()メソッドを使用してパイプから分割します。結果の配列は応答して配置されます。配列の最初の値 - 前の注文 - は応答[0]でアクセスされ、ID「順序」を使用してフィールドの値に設定されます。顧客アドレスである2番目の値応答[1]には、もう少し処理が必要です。アドレス内の線は通常のラインセパレーター( " n"文字)で区切られているため、コードは代わりにxhtmlスタイルのラインセパレーター<br />を使用する必要があります。交換プロセスは、交換()関数と正規表現を使用して行われます。最後に、変更されたテキストは、HTMLフォームDivの内側のHTMLとして使用されます。その結果、図4に示すように、フォームは顧客情報で突然更新されます。
図4。顧客データを受け取った後の首の形式
この記事を終了する前に、XMLHTTPREQUESTの別の重要な属性、ResponseXMLを紹介したいと思います。このプロパティには、サーバーがXML応答を使用することを選択した場合、XML応答が含まれています(推測した可能性があります)。 XML応答の処理は、解析、ドキュメントオブジェクトモデル(DOM)、およびその他の問題を含む通常のテキストの処理とは大きく異なります。 XMLについては、後の記事でさらに取り上げます。ただし、responsexmlは通常ResponseTextと一緒に議論されるため、ここで言及に値します。多くの単純なAJAXアプリケーションの応答テキストで十分ですが、すぐにXMLがAJAXアプリケーションでうまく処理できることがわかります。
結論
あなたはXmlhttpRequestに少し疲れているかもしれません。ただし、Ajaxを使用して記述するすべてのページとアプリケーションでこのオブジェクトを何度も使用します。率直に言って、xmlhttprequestについては何か言わなければならないことがあります。次の記事では、リクエストにコンテンツヘッダーを設定し、サーバーの応答からコンテンツヘッダーを読み取り、リクエストをエンコードしてリクエスト/応答モデルでXMLを処理する方法を理解する方法を紹介します。
後で一般的なAJAXツールボックスを紹介します。これらのツールボックスは、この記事で説明されている詳細の多くを実際に非表示にし、Ajaxプログラミングを容易にします。非常に多くのツールボックスがあるのに、なぜ低レベルの詳細をコーディングする必要があるのか疑問に思うかもしれません。答えは、アプリケーションが何をしているかを知らずにアプリケーションで問題を見つけることは困難であるということです。
したがって、詳細を無視したり、単に閲覧したりしないでください。この便利でゴージャスなツールボックスに何か問題が発生した場合は、頭を掻いたり、サポートのためにメールを送信したりする必要はありません。 xmlhttprequestを直接使用する方法を理解している場合は、最も奇妙な問題をデバッグして解決するのが簡単です。ツールボックスは、問題を解決させた場合にのみ良いことです。
xmlhttprequestに精通してください。実際、ツールボックスを使用するAJAXコードがある場合は、XMLHTTPREQUESTオブジェクトとそのプロパティとメソッドを使用して書き換えてみてください。これは、あなたが原則をよりよく理解するのに役立つ良い演習です。
次の記事では、このオブジェクトについてさらに説明し、そのより興味深いプロパティ(ResponseXMLなど)のいくつかを調査し、投稿リクエストを使用してさまざまな形式でデータを送信する方法について説明します。コードを書き始めてください。1か月以内にもう一度話し合います。