トップJavaScript > XMLHttpRequestによる非同期通信

XMLHttpRequestによる非同期通信

はじめに

サーバーにある画像ファイルを読み込んで Canvas に貼り付けて、画像を描画するだけならば簡単であるが、 開発を予定している地図システムでは少し複雑な仕組みを使う。

少なくとも一度はサーバーから画像ファイルをクライアント端末(パソコンやスマホ)に読み込むが、 それはローカルファイルに保存される。

したがって、通常は、ローカルファイルの読み込みが多くなる。 ローカルにないとき、もしくは、ローカルファイルが古いとき、サーバーから読み込み、 ローカルファイルを更新しておく。

ローカルファイルをダイレクトに Canvas に貼り付けるのではなく、 メモリ上のキャッシュ(画像データ配列)に載せる。

描画はこのキャッシュにある画像データを使う。 地図のスクロールやズームイン/ズームアウトで頻繁に画像描画が必要になるが、 これを高速に行うためにキャッシュを使う。

ローカルにあれば、それが古い場合も、一旦はそれがキャッシュに読み込み、地図を描画する。 新しい画像ファイルをサーバーから入手して、キャッシュを書き換えたら、再描画により地図を新しくする。

XMLHttpRequestによる非同期通信

XMLHttpRequestオブジェクトを作成する

let request = XMLHttpRequest();

HTTPリクエストを初期化する(open)

open(メソッド, URL[, 非同期[, ユーザー名[, パスワード]]])
let request = new XMLHttpRequest();
request.open('GET', 'http://cyberjapandata.gsi.go.jp/xyz/std/14/14552/6451.png', true);
※ 3 番目の引数の true は省略しても同じ(非同期)である。

サーバからのレスポンスの受信が完了した時にコールバック関数を呼びだす

XMLHttpRequest.readyState プロパティは以下の値をとる。

0 未初期化(openメソッドが呼ばれていない)
1 ロード中(openメソッドは済み、sendメソッドが未)
2 ロード済(sendメソッドは済みでレスポンス待ち)
3 受信中(レスポンス受信中)
4 完了(レスポンスの受信完了)

XMLHttpRequest.readyState == 4 になったとき、受信完了である。

let request = new XMLHttpRequest();

request.onreadystatechange = function(){
  if (request.readyState == 4){
    // 受信したデータの処理を記述する
  }
}

request.open('GET', 'http://cyberjapandata.gsi.go.jp/xyz/std/14/14552/6451.png', true);

テキストファイル

テキストファイルの場合、 let data = request.responseText; で受け取る。

request.onreadystatechange = function(){
  if (request.readyState == 4){
    if (request.status == 200){
      let data = request.responseText;
      console.log(data);
    }
  }
}

画像ファイル[3]

画像ファイルについては blob を使う。

var oReq = new XMLHttpRequest();
oReq.open("GET", 'http://cyberjapandata.gsi.go.jp/xyz/std/14/14552/6451.png', true);
oReq.responseType = "blob";

oReq.onload = function(oEvent) {
    var blob = oReq.response;
    const url = URL.createObjectURL(blob);
    const a = document.createElement("a");
    document.body.appendChild(a);
    a.download = 'tile.png';
    a.href = url;
    a.click();
    a.remove();
};

oReq.send();

FileSaver.jsを使う

<script src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/1.3.3/FileSaver.min.js"></script>
<script>
var oReq = new XMLHttpRequest();
oReq.open("GET", "http://cyberjapandata.gsi.go.jp/xyz/std/14/14552/6451.png", true);
oReq.responseType = "blob";

oReq.onload = function(oEvent) {
    var blob = oReq.response;
    //console.log(oReq.readyState);
    saveAs(blob, 'test.png');
};

oReq.send();
</script>

A.リファレンス

[1] XMLHttpRequestオブジェクトを使った非同期通信を行う
[2] XMLHttpRequest.readyState
[3] バイナリデータの送信と受信 JavaScript 型付き配列を使ったバイナリデータの受信
[4] XMLHttpRequest2 に関する新しいヒント
[5] ブラウザからファイル出力(FileSaver.js)