バイナリデータの送信と受信

JavaScript typed arrays を使ったバイナリデータの受信

XMLHttpRequest オブジェクトの responseType プロパティをセットすると、サーバに期待する response type を変更する事が出来ます。設定可能な値は空文字列(デフォルト), "arraybuffer", "blob", "document", "json", そして "text" です。response プロパティには responseType に応じてArrayBuffer, Blob, Document, JSON, または string のエンティティボディが入ります。リクエストが不完全であったり成功しなかった場合は null になります。

このサンプルでは画像をバイナリファイルとして読み込み、生のバイト列から 8 ビット符号なし整数値の配列を作成します。

var oReq = new XMLHttpRequest();
oReq.open("GET", "/myfile.png", true);
oReq.responseType = "arraybuffer";

oReq.onload = function (oEvent) {
  var arrayBuffer = oReq.response; // Note: not oReq.responseText
  if (arrayBuffer) {
    var byteArray = new Uint8Array(arrayBuffer);
    for (var i = 0; i < byteArray.byteLength; i++) {
      // do something with each byte in the array
    }
  }
};

oReq.send(null);

上記の方法の代わりに Blob インタフェースを利用して arraybuffer データから直接 Blob を 構築 (construct) します。

var oReq = new XMLHttpRequest();
oReq.open("GET", "/myfile.png", true);
oReq.responseType = "arraybuffer";

oReq.onload = function(oEvent) {
  var blob = new Blob([oReq.response], {type: "image/png"});
  // ...
};

oReq.send();

更に、responseType プロパティに "blob" 文字列をセットする事で、 Blob としてバイナリファイルを読む事も出来ます。

var oReq = new XMLHttpRequest();
oReq.open("GET", "/myfile.png", true);
oReq.responseType = "blob";

oReq.onload = function(oEvent) {
  var blob = oReq.response;
  // ...
};

oReq.send();

古いブラウザでのバイナリデータの受信

下に示す load_binary_resource() 関数は指定した URL からロードしたバイナリデータを関数の呼び元 (caller)に返します。

function load_binary_resource(url) {
  var req = new XMLHttpRequest();
  req.open('GET', url, false);
  //XHR binary charset opt by Marcus Granado 2006 [http://mgran.blogspot.com]
  req.overrideMimeType('text\/plain; charset=x-user-defined');
  req.send(null);
  if (req.status != 200) return '';
  return req.responseText;
}

魔法が 5 行目にかかっていて、 MIME type を上書きする事で user-defined 文字セット のプレインテキストとして扱う事をブラウザに強制します。これによりブラウザはパースせずバイト列を未処理のまま通します。

var filestream = load_binary_resource(url);
var abyte = filestream.charCodeAt(x) & 0xff; // throw away high-order byte (f7)

上記のサンプルでは、ロードしたバイナリデータ内のオフセット x のバイトを取得します。 x の有効範囲は 0 から filestream.length-1 です。

詳細な説明は downloading binary streams with XMLHttpRequest を見て下さい。また downloading files も見て下さい。

バイナリデータの送信

XMLHttpRequest の send メソッドは拡張され、 ArrayBuffer, Blob, または File オブジェクトを受け付ける事でバイナリデータの送信が容易になりました.

続くサンプルはその場 (on-the-fly)で作ったテキストファイルを POST メソッドで "file" をサーバに送信します。このサンプルはプレインテキストを使っていますが、代わりにデータがバイナリファイルだとイメージする事も出来ます。

var oReq = new XMLHttpRequest();
oReq.open("POST", url, true);
oReq.onload = function (oEvent) {
  // Uploaded.
};

var blob = new Blob(['abc123'], {type: 'text/plain'});

oReq.send(blob);

バイナリデータとして typed arrays を送信

同等にバイナリデータとして JavaScript typed arrays を送信する事も出来ます。

var myArray = new ArrayBuffer(512);
var longInt8View = new Uint8Array(myArray);

for (var i=0; i< longInt8View.length; i++) {
  longInt8View[i] = i % 255;
}

var xhr = new XMLHttpRequest;
xhr.open("POST", url, false);
xhr.send(myArray);

これは 8ビット整数の 512 バイトの配列を構築して送信します。勿論、好きな任意のバイナリデータで使えます。

注記: XMLHttpRequest を使った ArrayBuffer オブジェクトの送信サポートは Gecko 9.0 (Firefox 9.0 / Thunderbird 9.0 / SeaMonkey 2.6)で追加されました。他のブラウザのサポート情報をここに追記して下さい。

フォーム送信とファイルアップロード

この節をお読み下さい。

Firefox 独自のサンプル

このサンプルでは非同期にバイナリコンテンツを送信するのに POST メソッドと Firefox にある非標準の sendAsBinary() を使います。

var req = new XMLHttpRequest();
req.open("POST", url, true);
// set headers and mime-type appropriately
req.setRequestHeader("Content-Length", 741);
req.sendAsBinary(aBody);

4行目で Content-Length ヘッダに 741 をセットするのは、データが 741 バイト長である事を示します。送信データの実際のサイズに応じてこの値を変更する必要があります。

5行目では sendAsBinary() メソッドを使ってリクエストをはじめます。

また、nsIFileInputStream のインスタンスの send()を通す事でバイナリコンテンツを送信できます。この場合は、あなた自身が Content-Length ヘッダセットしてはならず、この情報はストリームから自動的に取得されます:

// Make a stream from a file.
var stream = Components.classes["@mozilla.org/network/file-input-stream;1"]
                       .createInstance(Components.interfaces.nsIFileInputStream);
stream.init(file, 0x04 | 0x08, 0644, 0x04); // file is an nsIFile instance   

// Try to determine the MIME type of the file
var mimeType = "text\/plain";
try {
  var mimeService = Components.classes["@mozilla.org/mime;1"]
          .getService(Components.interfaces.nsIMIMEService);
  mimeType = mimeService.getTypeFromFile(file); // file is an nsIFile instance
}
catch (oEvent) { /* eat it; just use text/plain */ }

// Send    
var req = Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"]
                    .createInstance(Components.interfaces.nsIXMLHttpRequest);
req.open('PUT', url, false); /* synchronous! */
req.setRequestHeader('Content-Type', mimeType);
req.send(stream);

Document Tags and Contributors

Contributors to this page: yoya
最終更新者: yoya,