AJAXでファイルダウンロード

バイナリでもテキストでも、AJAX でリクエストしたら JavaScript で受けることになるので、ブラウザにファイルをダウンロードさせるように処理を作る必要がある。

Blob オブジェクトはファイルに似たオブジェクトで、immutable な生データです。データを表す blob は必ずしも JavaScript ネイティブなフォーマットではありません。File インターフェースは Blob を基礎にしており、その機能を継承する一方で、ユーザのシステム上のファイルをサポートするための機能を拡張しています。

https://developer.mozilla.org/ja/docs/Web/API/Blob

とのことです。レスポンスから Blob オブジェクトを作って、createObjectURL すれば、ダウンロード可能なURLを生成する事ができます。

よくありがちな、CSVデータを管理画面からダウンロードさせたい、みたいなパターンを jQuery + ES6 で書いた場合の例。

IEの場合、IE10以上であれば msSaveBlob という、Blob をダウンロードするという機能を使うことが出来る。それ以外のブラウザは、createObjectURL を使って URL を生成したら、a タグの href にセットしてそれにクリックイベントを発火させるという方法で実現できます。

$.ajax({
  url: 'https://example.com/api/admin/users.csv',
  type: 'GET',
}).done((data, status, jqXHR) => {
  let downloadData = new Blob([data], {type: 'text/csv'});
  let filename = 'users.csv'

  if (window.navigator.msSaveBlob) {
    window.navigator.msSaveBlob(downloadData, filename); // IE用
  } else {
    let downloadUrl  = (window.URL || window.webkitURL).createObjectURL(downloadData);
    let link = document.createElement('a');
    link.href = downloadUrl;
    link.download = filename;
    link.click();
    (window.URL || window.webkitURL).revokeObjectURL(downloadUrl);
  }
}).fail((data, status, jqXHR) => {
  alert('OMG!');
});      
AJAXでファイルダウンロード

WebSocket でリアルタイムお絵かきチャット作った

 WebSocketを使って、@projecthl2先生といっしょにリアルタイム連動お絵かきチャットを作ってみました。

おえかきちゃっと♥

 WebSocket 速いです!リアルタイムで同期しているので、数人でやると、毎秒サーバと50回とかやりとりしてるのだけど (1回の通信はおそらく100bytesくらい)、サーバ側はほとんどCPU食ってないみたいですね。すごぃ。もし AJAX とか使うとすると、毎秒50回とかサーバにリクエスト飛ばそうとか絶対考えないよ。2窓開いてみると、遅延はほぼ0で通信できてることが分かります。

 WebSocket は、やってみたところでは文字列しか送れなさそうなので、今までAJAXでJSON扱ってたようなものは文字列にして送る必要がありました。

JSON.stringfy({x:100, y:100})

みたいにしてサーバに送って、サーバからJSONを文字列にしたものを送って

JSON.parse(event.data)

的な感じにJSONを得てみました。

 お絵かき部分と、チャット部分でWebSocketを使っています。サーバ側のWebSocket部分は em-websocket を使いました。EventMachine を使った WebSocket 実装みたいです。WebSocket はシンプルでした。EventMachine の使い方を調べるのに時間がかかった。。

 お絵かき部分は、canvas を使っています。ファイルをロードの部分は XMLHttpRequest Level2 を使っています。最初は、FileAPI を使って実装すればサーバ経由せずにファイルロードできてウマー!! と思ったけど、まだ Firefox でしか使えないみたいなので、あきらめました。Twitterに投稿っていう部分は、canvas から toDataURL() で canvas に描かれたデータが Base64エンコードされたものを取って、そいつをサーバ側に送って保存しています。今までの XMLHttpRequest ってファイルをサーバに送信出来なかったので、無理矢理 iframe 使ったりとか頑張っていたけど、ファイルが送れるようになってすごい便利そうです。使い方は今までのものと大して変わらないみたいですし。

 
 HTMLを生成する部分は sinatra ちゃんです。sinatra ちゃん可愛いよ。センスいいと思う。

 2日で作られたものなので、例外処理とかあんまりしてなぃ。。でも2日でこのくらいのもの出来るとは、高機能なHTMLですねー

 ソースコードを github で公開しています。 -> ecpplus / websocket_chat

WebSocket でリアルタイムお絵かきチャット作った