XMLhttpRequestオブジェクトの利用方法について
XMLhttpRequestオブジェクトは、ページを再読み込みせずにデータの送受信をおこなえる便利な機能です。
対象データはtxt形式・XML形式・json形式と様々なデータをやり取りする事ができます。
取得したデータを抽出したり加工したりする事でパフォーマンスを維持しつつ自在にデータを操作する事ができます。
XMLhttpRequestオブジェクトとは
XMLHttpRequestは、JavaScriptを使ってブラウザとWEBサーバー間でデータの送受信を行う際に利用する機能です。
WEBページの読込とは別にデータの送受信を行うことができるため、ページ自体をリロードせずに情報を追加したり・書き換える事が可能です。
XMLHttpRequestを使ったデータ送受信は今のWEBサービスにおいて必須の機能ですので、基本を理解しておきましょう。
XMLhttpRequestの特徴
名前に「XML」と付いていますがXMLファイルに限らず,テキスト形式やDOMなど様々なデータを送受信できます。
利用用途としては以下のようなものがあります。
XMLhttpRequestでできる事
・ページをリロードせずにWEBページを更新する
・ページが読み込まれた後にサーバーにデータを送信or受信する
・バックグラウンドでサーバーにデータを送信する
XMLhttpRequestのセキュリティ
XMLhttpRequestは基本的にドメインやスキーム・ポート等、全てが一致したURL内でしか通信ができません。
このセキュリティ制限により比較的安全にサーバーと通信する事ができている訳ですね。
外部ドメインのデータを読み込むためには、クロスドメイン等による通信が必要です。
このドメイン間でのやり取りによく使われるのが、jsonファイルです。
※jsonファイルについては後述します。
XMLHttpRequestの記述
最新のブラウザには全て、XMLHttpRequestオブジェクトが組み込まれています。
下記の様なコードとファイルを準備するだけですぐに実装が可能です。
ローカル上では動かないので、WEBにUPしてお確かめ下さい。
javascriptコードの基本の形
<scirpt> var xhttp = new XMLHttpRequest(); xhttp.onreadystatechange = function() { if (this.readyState == 4 && this.status == 200) { } }; xhttp.open("GET", "ファイル名", true); xhttp.send(); </scirpt>
上記が「ファイル名」の箇所を読み込む基本的なXMLHttpRequestオブジェクトのコードです。
ご自身で任意の位置にtxtファイルなどを置いて、その位置を「ファイル名」の位置に指定します(同階層でなくてOK)。
各コードの流れ
各コードを順にご紹介しましょう。
XMLHttpRequestオブジェクト作成
まず最初の行は、XMLHttpRequestオブジェクトを作成している部分です。
var xhttp = new XMLHttpRequest();
サーバー処理のチェック
次にXMLHttpRequestで行われている処理の状況の変化を、以下の様にonreadystatechangeで監視しています。
サーバー側でリクエストを処理する準備ができたかどうかを確かめています。
xhttp.onreadystatechange = function() { if (this.readyState == 4 && this.status == 200) { } };
事前準備ができているかどうかを確認する
データの送受信をする前に、サーバー側にも色々準備が必要なのですね。
そのため、サーバー側のリクエスト準備がどのような状態で完了したかを知る目安が「readystate値」および「ステータスコード」になります。
readystateの値が「4」であれば、リクエスト処理が完了した事を表します。
さらにHTTPなのでステータスコードが「200」であれば、成功した事を示します。
ここで失敗していた場合、statusTextプロパティを利用してエラーの内容を確認できます。
データの送受信
xhttp.open("GET", "ファイル名", true);
準備が整ったら、xhttp.openを使ってデータの送受信を実行します。
openメソッド内の引数は以下の通りです。
第一引数…情報を取得するならGET、情報を送信する場合はPOSTを利用
第二引数…ローカルサーバー上のファイルURLを指定
第三引数…非同期なら「true」同期なら「false」を指定
非同期通信と同期通信
XMLHttpRequestの基本は非同期通信
XMLHttpRequestでは基本的には「非同期処理」でサーバーとの通信を行ないます。
非同期通信は、サーバーで実行されるプログラムのレスポンスを待たずに次の処理を続けます。
「同期処理」の場合は処理の完了を待ってからおこなうため、前の作業が完了するまで次の処理が始まる事はありません。
小さなリクエストであれば同期通信でも問題はありませんが、そうでない場合はトラブルの原因になります。
サーバーがビジー状態や低速の場合、アプリケーションが停止する可能性があるのです。
サーバーの処理準備が整ったかは確認が必要
非同期通信では、前の処理が終わる・終わらないに関わらず別の事を始めます。
同時に処理ができるメリットがありますが、サーバー準備が整わないまま次の事をしてしまう問題も起きます。
ですのでonreadystatechangeイベントを使って処理が完了したかどうかチェックするのです。
注:同期通信を使用する場合は、sendメソッドの後にonreadystatechange関数をに配置する様にしましょう。
リクエスト処理プロパティ
サーバーからの返答はresponseTextまたはresponseXMLなどで返ってきますし、エラーがあればstatusTextプロパティを通して返ってきます。
プロパティ | 概要 | |
---|---|---|
onreadystatechange | 状態が変更された際のイベントハンドラを指定 | |
readyState | 0 => uninitialized | オブジェクトが作成されたが初期化されていない (openメソッドが呼び出されていない) |
1 =>loading | オブジェクトが作成されたが sendメソッドが呼び出されていない |
|
2 =>loaded | メソッドが呼び出され、状態とヘッダーが使用可能になったが使用可能になっていない | |
3 =>interactive | 一部のデータを受信。restdonseBodyとrestdonseTextを呼び出して、現時点の部分的な結果を取得可能 | |
4 =>完全に完了 | 全てのデータを受信し、restdonseBodyとrestdonseTextで完全なデータを取得可能 | |
status | サーバーからの数値によるリターンコード 404は"Not Found"、200は"OK" |
|
responseText | サーバーから文字列形式のデータが返る 文字エンコーディングはブラウザによって異なる |
|
responseXML | サーバーからDOM形式のデータが返る | |
statusText | サーバーからの文字列によるリターンメッセージ |
GETとPOSTの違い
URLを利用してデータを取得する場合は基本「GET」を利用します。
「GET」はサーバーにデータを簡単に送る事ができますが、URIエンコードをしておく必要がある事と、サイズを全体で512バイト以内に抑える必要があります。
それに対して、ファイルを送信したりもっと大きな大きなファイルデータを扱う場合には「POST」を利用します。
POSTによるファイル送信コード例
<script> var xhttp = new XMLHttpRequest(); xhttp.open('POST','ファイル名',true); xhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'); xhttp.send(); </script>
上記の様にPOSTを使ってファイルを送信する事ができます。
POSTによるフォームデータ送信コード例
htmlフォーム
<form name="user"> Id:<input type="text" name="id"><br> ユーザ名:<input type="text" name="username"><br> <input type="submit" onclick="sendPost();return false;">送信</button> </form>
javascriptコード
<script> function sendPost(){ var xhttp = new XMLHttpRequest(); var formData = new FormData(document.forms.user); xhttp.open('POST','ファイル名',true); xhttp.send(formData); } </script>
上記の場合は、POSTで取得した「ファイル名」に対し、Formで送信されたusernameのデータを送っています。
responseTextプロパティ
ではここからXMLhttpRequestで送受信できる様々なデータ操作についてご紹介します。
responseTextプロパティは、レスポンスを文字列として返します。
応答をテキスト文字列として使用する場合は、このresponseTextプロパティを使用します。
javascriptコード
<button type="button" onclick="loadXMLDoc()">テキストファイル表示</button> <p id="demo"></p> <script> function loadXMLDoc() { var xhttp = new XMLHttpRequest(); xhttp.onreadystatechange = function() { if (this.readyState == 4 && this.status == 200) { document.getElementById("demo").innerHTML = this.responseText; } }; xhttp.open("GET", "xmlhttprequest/xml.txt", true); xhttp.send(); } </script>
buttonがクリックされた時にloadXMLDoc()イベントを発動します。
document.getElementById("demo").innerHTML = this.responseText;
上記により、取得したテキストファイル内のデータをそのままdemo属性が付いたエリアに表示させています。
読込txtファイル(xmlhttprequest/xml.txt)
xhttp.open("GET", "xmlhttprequest/xml.txt", true);
読み込んでいるxmlhttprequestディレクトリのxml.txtには下記内容が記載されています。
<p>XMLhttpRequestにより生成した文章です。</p>
<p>XMLhttpRequestにより生成した文章です。</p>
これをそのままテキスト文字列で受け取ります。ページを再読み込みせずに取得できる訳ですね。
responseText実行例
responseXMLプロパティ
responseXMLは、レスポンスをXML DOMオブジェクト(XML文書)として返すプロパティです。
応答をXML DOMオブジェクトに変換する場合は、responseXMLプロパティを使用します。
javascriptコード
<button type="button" onclick="loadXMLDoc()">XMLファイル抽出表示</button> <p id="demo"></p> <script> function loadXMLDoc() { var xmlhttp = new XMLHttpRequest(); xmlhttp.onreadystatechange = function() { if (this.readyState == 4 && this.status == 200) { myFunction(this); } }; xmlhttp.open("GET", "xmlhttprequest/xmldom.xml", true); xmlhttp.send(); } function myFunction(xml) { var x, i, xmlDoc, txt; xmlDoc = xml.responseXML; txt = ""; x = xmlDoc.getElementsByTagName("TITLE"); for (i = 0; i< x.length; i++) { txt += x[i].childNodes[0].nodeValue + "<br>"; } document.getElementById("demo").innerHTML = txt; } </script>
上記はxmlファイルを読み込むところまでは前回とほぼ同様ですね。
xmlDoc = xml.responseXML;
さらにresponseXMLを使って、取得したデータをXML DOMオブジェクトに変換しています。
今回はさらにfunction myFunction(xml)のところで、XML DOMデータの中からTITLEタグの付いた項目のみを抽出しています。
読込XMLデータ(xmlhttprequest/xmldom.xml)
今回xmlhttprequest/xmldom.xmlの中に記載されているデータは以下の通りです。
<CATALOG>
<DATA>
<TITLE>商品A</TITLE>
<ARTIST>メーカー名:A社</ARTIST>
<COUNTRY>日本</COUNTRY>
<PRICE>¥1,500</PRICE>
<YEAR>2018</YEAR>
</DATA>
<DATA>
<TITLE>商品B</TITLE>
<ARTIST>メーカー名:B社</ARTIST>
<COUNTRY>日本</COUNTRY>
<PRICE>¥1,800</PRICE>
<YEAR>2019</YEAR>
</DATA>
<DATA>
<TITLE>商品C</TITLE>
<ARTIST>メーカー名:C社</ARTIST>
<COUNTRY>日本</COUNTRY>
<PRICE>¥1,700</PRICE>
<YEAR>2020</YEAR>
</DATA>
<DATA>
<TITLE>商品D</TITLE>
<ARTIST>メーカー名:D社</ARTIST>
<COUNTRY>日本</COUNTRY>
<PRICE>¥1,600</PRICE>
<YEAR>2018</YEAR>
</DATA>
<DATA>
<TITLE>商品E</TITLE>
<ARTIST>メーカー名:E社</ARTIST>
<COUNTRY>日本</COUNTRY>
<PRICE>¥1,400</PRICE>
<YEAR>2020</YEAR>
</DATA>
</CATALOG>
responseXML実行例
上記の様にtitleタグ内の「商品名」リストのみが並びます。
もちろん抽出対象をARTISTやPRICEにすれば、違うデータを表示する事ができますね。
XMLparse
XML DOMオブジェクトには、XMLにアクセス・編集するための多くのメソッドが含まれています。
ただし先程の様に、XMLデータをXML DOMオブジェクトに変換する必要があります。
ここでXMLparseを使えば、XMLではないプレーンテキストでもXML DOMオブジェクトに変換できます。
最新のブラウザには全て、XMLparseが組み込まれています。
javascriptコード
<p id="demo"></p> <script> var text, parser, xmlDoc; text = "<game>" + "<title>Nintendo</title>" + "<author>Japan</author>" + "<year>2020</year>" + "</game>"; parser = new DOMParser(); xmlDoc = parser.parseFromString(text,"text/xml"); document.getElementById("demo").innerHTML = xmlDoc.getElementsByTagName("title")[0].childNodes[0].nodeValue; </script>
XMLparse実行例
既に「Nintendo」と表示されていますが、これが抽出されたデータです。
上記の様にtextファイルをXML DOMオブジェクトとして変換し、データの取得・操作ができます。
ドメイン間のアクセス
最近のブラウザはセキュリティ上の理由から、基本的にはドメイン間のデータのやり取りを許可していません。
ですので基本的にWEBページと読込対象のファイルは、両方とも同じサーバー上に存在する必要があります。
しかしWEB技術の拡張に伴い、ドメイン間のデータ通信の必要性がどんどん高まってきました。
そこでAccess-Control-Allow-Origin等の設定を利用した、クロスドメインによるデータ送受信が行われるようになります。
ドメイン間のデータ通信に使われる「JSON」
現在外部ドメイン間で通信を行う際は、JSONでデータを送受信する事がほとんどです。
jsonとは、XMLと比べて簡潔に構造化されたデータを記述する事ができるファイルです。
記述が容易で人間が理解しやすいデータフォーマットと言えます。
ドメイン間でやり取りをする場合、送受信するデータをJSONファイルにしてサーバーに設置しておく必要があります。
Response Typeによる変換
XMLHttpRequestのレスポンスとしてJSONを受け取った場合、それはresponseTextのデータとして読み取る事になります。
しかし受け取った段階では、まだXMLHttpRequestオブジェクトではありません。
そこでこのjsonファイルをXMLHttpRequestオブジェクトに変換できる「Response Type」を使います。
Response Typeは、blob, textなどjson以外の値も設定することができます。
現在はこのResponse Typeを通してデータの取得を行うのが主流です。
javascriptコード
Response Typeの場合
<script> var xhttp = new XMLHttpRequest(); xhttp.responseType = 'json'; xhttp.onreadystatechange = function(){ if(this.readyState == 4 && this.status == 200){ user = this.response; console.log(user.user_name); } } </script>
json.parseの場合
json.parseを使ってテキストファイルをjsonとして扱う事もできます。
<script> var xmlhttp = new XMLHttpRequest(); var url = "xmlhttprequest/list.txt"; xmlhttp.onreadystatechange = function() { if (this.readyState == 4 && this.status == 200) { var myArr = JSON.parse(this.responseText); myFunction(myArr); } }; xmlhttp.open("GET", url, true); xmlhttp.send(); function myFunction(arr) { var out = ""; var i; out += '<p>'; for(i = 0; i < arr.length; i++) { out += '<a href="' + arr[i].url + '">' + arr[i].display + '</a><br>'; } out += '</p>'; document.getElementById("id01").innerHTML = out; } </script>
読込jsonデータ(xmlhttprequest/list.txt)
今回のxmlhttprequest/list.txt内には、以下の様にjsonファイル形式でデータが格納されています。
[
{
"display": "HTML",
"url": "https://lpeg.info/html/"
},
{
"display": "SEO",
"url": "https://lpeg.info/seo/"
},
{
"display": "Webworks",
"url": "https://lpeg.info/webworks/"
},
{
"display": "Security",
"url": "https://lpeg.info/security/"
},
{
"display": "Client",
"url": "https://lpeg.info/client/"
},
{
"display": "Freelance",
"url": "https://lpeg.info/freelance/"
}
]
jsonファイル実行例
HTML
SEO
Webworks
Security
Client
Freelance
上記の様にリンク付きの一覧リストを生成する事ができました。
古いブラウザ(IE5およびIE6)
古いバージョンのInternetExplorer(IE5およびIE6)では、XMLHttpRequestオブジェクトをサポートしていません。
IE5およびIE6を処理するにはActiveXObjectを作成します。
IE5およびIE6は、DOMParserオブジェクトもサポートしていません。
いまIE5や6を使っている人はほとんどいないと思いますので、ActiveXObjectに関するサポート例は割愛します。
まとめ
以上XMLhttpRequestオブジェクトの利用の仕方についてご紹介しました。
一応補足しておきますが、このXMLhttpRequestを使って表示させたデータはHTMLソース内には映りません。
これがページの再読み込みなしに表示させた事を裏付けています。
実装自体が簡単手軽ですし、ページのリロードの必要が無いのでパフォーマンス的にも高い効果があります。
一つずつ確かめながらやればいろいろな事が出来るようになるので、ぜひマスターして欲しいと思います。