
XMLHttpRequest風IFAMEによるデータ通信1
1: iframeで動的なテーブル書き換え (JSON)
2: XMLHttpRequestとの機能比較
3: データフォーマット
4: [ソース] jsgt_JSONIframeReqestライブラリ
5: [ソース] テーブル出力処理用ライブラリ
XMLHttpRequestとの機能比較
今回作ったjsgt_JSONIframeReqestの機能は、ソースをみればわかりますが、一応、XMLHttpRequestとの簡単な比較をしてみました。 jsgt_JSONIframeReqestでは、HTTPクライアントの機能はブラウザまかせですので、 setRequestHeader()など、HTTPクライアント関連のメソッドやプロパティは存在しません。
その代わり、jsgt_JSONIframeReqestは、動作ブラウザが多く、XMLHttpRequestのようなブラウザ毎の動作の違いはありません。 さらに、レスポンスデータをオブジェクトで自由なタイミングで渡せるメリットがあります。
| XMLHttpRequest | jsgt_JSONIframeReqest | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 動作ブラウザ |
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| インスタンス生成 | new XMLHttpRequest() new new ActiveXObject("Msxml2.XMLHTTP") new ActiveXObject("Microsoft.XMLHTTP") (* IE以外はnew XMLHttpRequest()) |
new jsgt_JSONIframeReqest() (*対応ブラウザすべてで共通に使えます) |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| レスポンスデータ | responseXML responseText (*文字列として渡します) |
responseJson (*オブジェクトとして渡します) |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| readyState(0,1,2,3,4) | readyState (*IEでは「3」で途中データを受け取れません) |
readyState (*対応ブラウザすべてで「3」で途中データを順次受け取れます。) |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| open | open(method,url[,async[,user[,password]]]) | open(object) (*Objectリテラルで渡します。現在渡せるのはURLと強制ロード(sload)。object ={url:URL[,sload:true|false]}) |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| send | send(postData) | send() (*POSTは現在使えません。送信はGETでURLに付加してください。) |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onload | onload (*IEではonloadを使えません) |
onload (*対応ブラウザすべてで共通に使えます) |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| onreadystatechange | onreadystatechange (*Opera8.0でイベントが2重発生) |
onreadystatechange (*対応ブラウザすべてで共通に使えます) |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| setRequestHeader() | setRequestHeader() | なし | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| getRequestHeader() | getRequestHeader() | なし | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| status | status | なし | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| statusText | statusText | なし |
データフォーマット
iframe要素には、onloadとonreadystatechangeのイベントがありますが、すべてのブラウザに実装されているわけではありません。 そこで、今回は、データ側にコールバックの呼び出しを仕込むことで、すべてのブラウザで共通に動作するonloadとonreadystatechange を用意しました。そのため、このjsgt_JSONIframeReqestを使うには、データ側の書き方を統一する必要があります。
今回は、データを乗せるコンテナとして HTMLファイルを利用し、その中のスクリプト要素内へJSON形式のデータを書いておく方法を採りました (注意:データ形式は、JavaScriptで渡せるなら何でも良いのですが、一応多少のフォーマット指針があった方があとで利用しやすいという理由で選びました)。
そして、iframeでそのHTMLファイルを呼び出すと、その中のJSONがJavaScriptのオブジェクトとして渡されるという仕組みになっています。
今回のサンプルで使ったデータは、たとえば、次のようになっています。
今回のサンプルでは、テーブルのヘッダ行とデータ行を「head」と「data」という二つのプロパティに分けて用意しました。この構造自体はXMLを書く場合と同様に 自由に使いやすい構造を決めて使えばよいと思います。
【eiggo.htm】
<html><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <script type="text/javascript" charset="utf-8"><!-- ///// // jsgt_JSONIframeReqestデータフォーマット // @syntax parent.jsgt_data.response({JSON...}); // @see http://jsgt.guide.withabout.net/guide_jsgt/gp333/lib/jsoniframerequest/readme.htm // // responseする毎に、jsgt_JSONIframeReqestのonreadystatechangeイベントが // 発生しoj.responsJsonでJSONデータを渡します。データはpush追記されます。 // また、ページロード完了後にoj.onloadイベントが発生します。 // // Start data (OK chage here)/////////////////////////////////////////parent.jsgt_JSONIframeReqest.response({url:location}, { "head" : [[ "名前" , "英語" ]], "data" : [ [ "田中" , "24" ] , [ "中山" , "68" ] , [ "山本" , "55" ] , [ "本井" , "18" ] , [ "井上" , "99" ] , [ "上山" , "26" ] ] });// End data ////////////////////////////////////////////////////////
//--></script>
<!-- Start footer (Don't change)///////////////////////////////////-->
<body onload="
parent.jsgt_JSONIframeReqest.onfileloaded({url:location});
">
<!-- End footer ///////////////////////////////////////////////////-->
</body></html>
どうですか?出力されたテーブルと同じ構造のデータですから、わかりやすいでしょう?
このデータページがiframeへ読み込まれるたびに、データページ内の「...response(...)」が実行されます。
ページを読み終わったタイミングでbody要素のonloadに書いた 「...onfileloaded({url:location});」 が実行されて、jsgt_JSONIframeReqest側のoj.onloadイベントが発生します。この時、oj.readyState値は「4」に代わり、データが oj.responseJsonに渡ります。
JavaScriptでデータを取り出すときは、このサンプルなら、たとえば、oj.responseJson.head[0][1]で「英語」という文字列が取り出せます。 oj.responseJson.data[0][0]なら「田中」、oj.responseJson.data[0][1]なら「24」、 oj.responseJson.data[2][0]なら「山本」という具合です。
もし、データページ内のresponse()が複数あって、受信途中でデータを取り出したい場合は、oj.onreadystatechange毎に、oj.responseJson.part[0]、oj.responseJson.part[1]、oj.responseJson.part[2]、、、という具合に、各レスポンスがpart[oj.index]の下にコピーされていきます。
oj.indexは最初は0で、受信したデータ数だけカウントアップされます。
そして、ページを読み終わると、この最後のデータpart[oj.index]はoj.responseJson直下へコピーされます。
このようにして、oj.responseJson以下は受信した順番に、次のような構造を作っていきます。 この結果、「onreadystatechange==3」の時点での着信データによる、極め細かな制御なども可能になると思います。
oj.responseJson
├.part[0]
│ └{ data1-1:...,data1-2:... } //最初の着信
├.part[1]
│ └{ data2-1:...,data2-2:... } //1番目の着信
├.part[3]
│ └{ data3-1:...,data3-2:... } //2番目の着信
├.part[4]
│ └{ data4-1:...,data4-2:... } //4番目の着信
├.part[5]
│ └{ data5-1:...,data5-2:... } //最後の着信
│
│//以下最後の着信(.part[5])のコピー ( oj.onloadで取得 )
├.data5-1
├.data5-2
├.data5-3
├. :
└.data5-n
ちなみに、第一引数の「url:location」は、リクエストとレスポンスを一意に結びつけるおまじないですので省略できません。
関連ジャンル一覧
すぐにでも真似したくなる簡単テク
KALDI(カルディ)のオススメ商品をピックアップしました
新着・人気記事
Javascript新着記事
PDF作成・編集・変換新着記事
PDF作成・編集・変換デイリーランキング





















