Ajaxは、最新のWebアプリケーション開発の重要なツールです。これにより、サーバーに非同期にデータを送信および受信し、JavaScriptで解析できます。 Ajaxは、非同期JavaScriptとXML(非同期JavaScriptおよびXML)の略語です。
Ajax Core仕様の名前は、リクエストの作成と開始に使用されるJavaScriptオブジェクトから継承されます:xmlhttprequest。この仕様には2つのレベルがあります。すべての主流ブラウザは、機能の基本レベルを表す最初のレベルを実装します。 2番目のレベルでは、初期仕様を拡張し、追加のイベントといくつかの機能を組み込んで、フォーム要素とのコラボレーションを容易にし、関連する仕様をサポートします。
1。AJAXが始まります
ajaxの鍵はxmlhttprequestオブジェクトにあり、このオブジェクトを理解する方法は、例を見ることです。次のコードは、xmlhttprequestオブジェクトの単純な使用法を示しています。
<!doctype html> <html lang = "en"> <head> <meta charset = "utf-8"> <title>例ボタン= document.getElementsByTagname( "ボタン"); for(var i = 0; i <bottons.length; i ++){buttons [i] .onclick = handlebuttonpress; } //スクリプトはこの関数を呼び出してボタンコントロールのクリックイベント関数HandleButtonPress(e){//新しいXMLHTTPREQUESTオブジェクトVAR HTTPREQUEST = NEW XMLHTTPREQUEST();を作成します。 // onreadystatechangeイベントhttprequest.onreadystatechange = handleresponseのイベントハンドラーを設定します。 // openメソッドを使用して、httpメソッドとurlを指定する(つまり、httprequestオブジェクトに何をしたいかを伝えます)httprequest.open( "get"、e.target.innerhtml+"。html"); //ここでサーバーにデータが送信されないため、送信メソッドにはパラメーターがありませんhttprequest.send(); } //応答の処理//スクリプトが送信メソッドを呼び出すと、ブラウザはバックグラウンドのサーバーにリクエストを送信します。リクエストはバックグラウンドで処理されるため、Ajaxはイベントに依存してリクエストの進捗状況を通知します。 function handleresponse(e){// onreadystatechangeイベントがトリガーされると、ブラウザはイベントオブジェクトを指定されたハンドラー関数に渡し、ターゲットプロパティはこのイベントに関連付けられたXMLHTTPREQUESTに設定されます(e.target.readystate == xmlhhttprequest.done && constertus.status.status.status.status.status.status = = document.getElementById( "ターゲット")。innerhtml = e.target.responsetext; //要求されたドキュメントのコンテンツを表示}} </script> </body> </html>3つの追加ドキュメントは非常に簡単です。
<!doctype html> <html lang = "en"> <head> <meta charset = "utf-8"> <title> apples </title> <style> img {float:left; padding:2px; margin:5px; border:medium double black; backgrach color:lightgrey;幅:100px;高さ:100px;} </style> </head> <body> <p> <img src = "../ img/show-page/img_apples.jpg"/> Applesのページ</p> </body> </html>効果は、下の図に示されています。
ユーザーが各フルーツボタンをクリックすると、ブラウザは非同期に実行され、要求されたドキュメントを取得しますが、メインドキュメントはリロードされていません。これは典型的なAJAXの動作です。
2。AJAXイベントの使用
簡単な例を作成して探索した後、XMLHTTPREQUESTオブジェクトによってサポートされている機能とリクエストの使用方法を掘り下げ始めることができます。出発点は、第2レベルの仕様で定義されている追加のイベントです。
これらのイベントのほとんどは、リクエスト中の特定の時点でトリガーされます。 2つのイベントは例外、ReadyStateChangeと進捗状況であり、進行状況の更新を提供するために複数回トリガーできます。
これらのイベントがスケジュールされると、ブラウザはReadyStateChangeイベントに通常のイベントオブジェクトと、他のイベントに進行率のオブジェクトを使用します。 ProgressEventオブジェクトは、イベントオブジェクトのすべてのメンバーを定義し、次の図に説明するこれらのメンバーを追加します。
次のコードは、これらのイベントの使用方法を示しています。
<!doctype html> <html lang = "en"> <head> <meta charset = "utf-8"> <title>例</title> <style>テーブル{マージン:10px;境界線崩壊:崩壊; float:左;} div {マージン:10px;} td、th {padding:4px;} </style> </head> <body> <div> <butth> apples </button> <butth> cherries </button> <ボタン> bananas </button> </div> <table id = "events"> </table> <div div </div </div </div < type = "application/javascript"> var bottons = document.getElementsByTagname( "ボタン"); for(var i = 0; i <bottons.length; i ++){buttons [i] .onclick = handlebuttonpress; } var httprequest; function handlebuttonpress(e){clearEventDetails(); httpRequest = new XMLHTTPREQUEST(); httprequest.onededystatechange = handleresponse; httprequest.onerror = handleerror; httprequest.onload = handleload ;; httprequest.onloadend = handleloadend; httprequest.onloadstart = handleloadstart ;; httprequest.onprogress = handleprogress; httprequest.open( "get"、e.target.innerhtml+"。html"); httprequest.send(); } function handleresponse(e){displayeventDetails( "readystate("+httprequest.readystate+")")if(e.target.readystate == xmlhttprequest.done && e.target.status == 200){documentelementbyid(target ")。 }} function handleError(e){displayeventdetails( "error"、e);} function handleload(e){displayeventdetails( "load"、e);} function handleloadend(e){displayeventDetails( "loadend"、e);関数HandleLoAdstart(e){displayeventDetails( "loadstart"、e);} function handleprogress(e){displayeventDetails( "progress"、e);} function cleareventdetails(){document.getElementByid( "events")。 "<tr> <th> event </th> <th> lengthcomputable </th> <th>ロード</th> <th>合計</th>"; } function displayEventDetails(eventName、e){if(e){document.getElementById( "events")。innerhtml+= "<tr> <td>"+eventname+"</td> <td>"+e.lengtumputable+"</td> <td>" e.total+"</td> </tr>"; } else {document.getElementById( "events")。innerhtml+= "<tr> <td>"+eventname+"</td> <td> na </td> <td> na </td> <td> na </td> <td> na </td> </tr>"; }} </script> </body> </html>これは前の例のバリエーションであり、一部のイベントのハンドラーを登録し、テーブル要素で処理された各イベントのレコードを作成します。次の画像から、Firefoxブラウザがこれらのイベントをどのようにトリガーするかを確認できます。
3.エラーを処理します
AJAXを使用する場合、2種類のエラーに注意する必要があります。それらの違いは、異なる視点に由来します。
最初のタイプのエラーは、xmlhttprequestオブジェクトの観点から見られる問題です。いくつかの要因は、リクエストがサーバーに送信されるのを防ぎます。たとえば、DNSはホスト名を解決できず、接続要求が拒否されたり、URLが無効です。
2番目のタイプの問題は、XMLHTTPREQUESTオブジェクトではなく、アプリケーションの観点から見られる問題です。リクエストが正常にサーバーに送信されたときに発生します。サーバーは、リクエストを受信し、処理し、応答を生成しますが、応答は期待を指していません。たとえば、要求されたURLが存在しない場合、この種の問題が発生します。
次のコードに示すように、これらのエラーに対処するには3つの方法があります。
3.1設定エラーの取り扱い
対処する必要がある最初のタイプの問題は、誤ったURLなどのXMLHTTPRESQUESTオブジェクトに誤ったデータを渡すことです。ユーザー入力に基づいてURLを生成するときに発生する傾向があります。この種の問題をシミュレートするために、上記のドキュメントには、タグBad URL(間違ったURL)を追加するボタンがあります。このボタンを押すと、次の形式のオープンメソッドを呼び出します。
httprequest.open( "get"、 "http://")
これは、リクエストが実行されるのを防ぐエラーであり、このようなイベントがxmlhttprequestオブジェクトで発生するとエラーがスローされます。これは、このようなリクエストを設定するコードを囲むために、試してみる...キャッチステートメントが必要であることを意味します。
try {... httprequest.open( "get"、 "http://")... httprequest.send(); } catch(error){displayerrormsg( "try/catch"、error.message)}Catch句は、エラーから回復する機会を与えます。ユーザーに値を促すことを選択するか、デフォルトのURLに戻るか、単にリクエストを破棄することを選択できます。この例では、displayerrormsg関数が呼び出され、エラーメッセージが表示されます。
3.2処理要求エラー
2番目のタイプのエラーは、要求が生成されたときに発生しますが、他のエラーがあります。このタイプの問題をシミュレートするために、この例には、悪いホスト(エラーホスト)というラベルの付いたボタンが追加されました。このボタンが押されると、開かれたメソッドが呼び出され、利用できないURLにアクセスします。
httprequest.open( "get"、http://www.ycdoitt.com/nopage.html)
このURLには2つの問題があります。最初の問題は、ホスト名をDNSによって解決できないため、ブラウザがサーバー接続を生成できないことです。この問題は、xmlhttprequestオブジェクトがリクエストの生成を開始したときにのみ明らかになることを知っているため、2つの方法でエラーを通知します。リスナーをエラーイベントに登録すると、ブラウザはリスナーにイベントオブジェクトを送信します。例で使用される関数は次のとおりです。
function handleError(e){displayerrormsg( "エラーイベント"、httprequest.status + httprequest.statustext); }このようなエラーが発生すると、XMLHTTPREQUESTオブジェクトから取得できる情報の程度はブラウザに依存します。残念ながら、ほとんどの場合、0の値と空白のStatustext値のステータスが取得されます。
2番目の問題は、URLと生成された要求に異なるソースがあることですが、これはデフォルトでは許可されていません。通常、スクリプトをロードする同性のURLにAjaxリクエストのみを送信できます。ブラウザがこの問題を報告すると、エラーがスローされるか、エラーイベントがトリガーされる場合があります。異なるブラウザはそれを異なって処理します。また、異なるブラウザは、さまざまな時点でソースをチェックします。つまり、ブラウザが常に同じ問題を強調しているとは限りません。クロスオリジンリソース共有は、相同制限をバイパスするために使用できます。
3.3アプリケーションエラーの処理
最後のタイプのエラーは、要求が正常に完了したときに発生します(xmlhttprequestオブジェクトの観点から)が、必要なデータを返さない。このような問題を作成するには、上記の例にラベルキュウリのボタンを追加します。このボタンを押すと、リンゴ、チェリー、バナナのボタンに似たリクエストURLが生成されますが、Cucumber.htmlドキュメントはサーバーに存在しません。
このプロセス自体にエラーはありません(リクエストが完了したため)。ステータス属性に基づいて何が起こっているかを判断する必要があります。既存のドキュメントを要求すると、ステータスコード404が取得されます。つまり、サーバーは要求されたドキュメントを見つけることができません。この例では、200以外のステータスコードを処理する方法を確認できます(OKを意味します):
if(httprequest.status == 200){target.innerhtml = httprequest.responsetext; } else {document.getElementById( "statusmsg")。innerhtml = "status:" + httprequest.status + "" + httprequest.statustext; }この例では、ステータスとstatustextの値が単純に表示されます。実際のアプリケーションでは、リカバリを有用で意味のある方法で実行する必要があります(アプリケーションに適したものに応じて、代替コンテンツの表示や問題があることをユーザーに警告するなど)。
4.ヘッダーを取得して設定します
XMLHTTPREQUESTオブジェクトを使用して、サーバーに送信されたリクエストヘッダーとサーバーの応答でヘッダーを設定できます。
4.1リクエストのHTTPメソッドを上書きします
通常、AJAXリクエストにヘッダーを追加または変更する必要はありません。ブラウザは何を送信するかを知っており、サーバーは応答方法を知っています。ただし、いくつかの例外があります。最初のものはX-HTTP-Method-Overrideヘッダーです。
HTTP標準は、多くの場合、インターネット上のHTMLドキュメントを要求および送信するために使用され、多くの方法を定義します。ほとんどの人は、最も広く使用されているため、Getと投稿について知っています。ただし、サーバーに要求されたURLに意味を与えるために使用される他のメソッド(Put and Deleteを含む)があり、この使用法は増加しています。たとえば、ユーザーレコードを表示する場合は、そのようなリクエストを生成できます。
httprequest.open( "get"、 "http:// myserver/records/freeman/adam");
HTTPメソッドと要求されたURLのみがここに表示されます。このリクエストがスムーズに動作するためには、サーバー側がアプリケーションによる要求を理解し、それを適切なデータに変換してサーバーに送り返すことができる必要があります。データを削除する場合は、次のように記述できます。
httprequest.open( " delete "、 "http:// myserver/records/freeman/adam");
ここで重要なのは、何らかの方法でURLにエンコードするのではなく、サーバーにHTTPを介して何をしたいかを表現することです。
この方法でHTTPメソッドを使用することの問題は、多くの主流のWebテクノロジーがGETと投稿のみをサポートし、多くのファイアウォールではGETおよびPOSTリクエストのみがパスできることです。この制限を回避するための慣用的なアプローチがあります。これは、X-HTTP-Method-Overrideヘッダーを使用して使用するHTTPメソッドを指定することですが、フォームは販売され、POSTリクエストを送信します。コードのデモンストレーションは次のとおりです。
<!doctype html> <html lang = "en"> <head> <meta charset = "utf-8"> <title>例document.getElementsByTagname( "ボタン"); for(var i = 0; i <bottons.length; i ++){buttons [i] .onclick = handlebuttonpress; } var httprequest; function handlebuttonpress(e){httprequest = new xmlhttprequest(); httprequest.onededystatechange = handleresponse; httprequest.open( "get"、e.target.innerhtml+"。html"); httprequest.setRequestheader( "x-http-method-override"、 "delete"); httprequest.send(); } function handleError(e){displayerrormsg( "エラーイベント"、httprequest.status+httprequest.statustext); } function handleresponse(){if(httprequest.readystate == 4 && httprequest.status == 200){document.getElementById( "ターゲット")。 }} </script> </body> </html>この例では、XMLHTTPREQUESTオブジェクトのSetRequestHeaderメソッドを使用して、リクエストがHTTP Deleteメソッドの形で処理されることを示すことを示します。オープンメソッドを呼び出した後にのみ、このヘッダーを設定してください。 Openメソッドの前にSetRequestHeaderメソッドを使用しようとすると、XMLHTTPREQUESTオブジェクトはエラーをスローします。
PS:上書きHTTPでは、X-HTTP-Method-overRideの慣習を理解するためにサーバー側のWebアプリケーションフレームワークが必要であり、サーバー側のアプリケーションを設定して、それらのHTTPメソッドをより少ない方法で見つけて理解する必要があります。
4.2コンテンツキャッシングを無効にします
AJAX要求に追加できる2番目の有用なヘッダーはキャッシュコントロールです。これは、スクリプトを作成およびデバッグするときに特に役立ちます。一部のブラウザは、AJAX要求を介して取得したコンテンツをキャッシュし、ブラウジングセッション中に再びリクエストしません。前の例では、apples.html、cherries.html、bananas.htmlの変更がブラウザにすぐに反映されないことを意味します。次のコードは、これを回避するためにヘッダーを設定する方法を示しています。
httpRequest = new XMLHTTPREQUEST(); httprequest.onededystatechange = handleresponse; httprequest.open( "get"、e.target.innerhtml+"。html"); httprequest.setRequestHeader( "Cache-Control"、 "No-Cache"); httprequest.send();
ヘッダーを設定する方法は前の例と同じですが、今回はヘッダーはキャッシュ制御であり、望ましい値はキャッシュなしです。このステートメントを配置した後、AJAXを通じて要求されたコンテンツが変更された場合、次にドキュメントが要求されるときに反映されます。
4.3応答ヘッダーを読みます
Ajax要求に応答するときにサーバーが送信したHTTPヘッダーは、getResponseHeaderおよびgetAllResponseHeadersメソッドを読み取ることができます。ほとんどの場合、ブラウザとサーバーの間のインタラクティブなトランザクションの一部であるため、ヘッダーに何があるかを気にする必要はありません。次のコードは、このプロパティの使用方法を示しています。
<!doctype html> <html lang = "en"> <head> <meta charset = "utf-8"> <meta content = "width = device-width、no scalable = no" name = "viewport" /> <meta name = "著者" content = "ye chaoluka" /> <meta name = <pittent " href = "../ img/ycdoit.ico" type = "image/x-icon" rel = "ショートカットアイコン"/> <style>#オールヘッダー、#cheader {border:medium solid black; padding:2px; margin:2px;} </style> </head> <body> </button </buttun <button> bananas </button> </div> <div id = "cheader"> </div> <div id = "allheaders"> </div> <div id = "ターゲット">ボタンを押す</div> <script> var bottons = document.getelementsbytagname( "ボタン"); for(var i = 0; i <bottons.length; i ++){buttons [i] .onclick = handlebuttonpress; } var httprequest; function handlebuttonpress(e){httprequest = new xmlhttprequest(); httprequest.onededystatechange = handleresponse; httprequest.open( "get"、e.target.innerhtml+"。html"); httprequest.setRequestHeader( "Cache-Control"、 "No-Cache"); httprequest.send(); } function handleresponse(){if(httprequest.readystate == 2){document.getElementById( "allheaders")。innerhtml = httprequest.getAllResponseHeaders(); document.getElementById( "Cheader")。innerhtml = httprequest.getResponseHeader( "Content-Type"); } else if(httprequest.readystate == 4 && httprequest.status == 200){document.getElementById( "ターゲット")。 }} </script> </body> </html>レンダリングは次のとおりです。
この数字によると、開発サーバーが実行しているWebサーバーソフトウェアはIntellij Idea 15.0.4であり、Apples.htmlドキュメントが6月27日に変更されたのは最後でした(ただし、スクリーンショットは7月5日でした)。