XMLHttpRequest Level2ではバイナリデータもアップロードできるようになった!ヽ(=´▽`=)ノ
■ソース
基本的には前回と同じコードを利用している。
<p ondragstart="dragstart(event)" ondragenter="dragenter(event);" ondragover="dragover(event);" ondrop="drop(event);">You drop some images, here!</p> <div id="preview"></div>
次にJavaScriptコード。
function dragStart(e){ //e.preventDefault(); } function dragEnter(e){ //e.preventDefault(); } function dragOver(e){ e.preventDefault(); } function drop(e){ var files = e.dataTransfer.files; for(var i = 0; i < files.length; i++){ var request = new XMLHttpRequest(); request.upload.onprogress = function(e){ document.getElementById('progress').style.width = ((e.loaded / e.total) * 100 + "%"); } request.upload.onload = function(e){ document.getElementById('progress').style.width = '0px'; alert('finished'); } request.open('post', "./index.html"); request.send(files[i]); } e.preventDefault(); }
ファイルアップロード部分
onprogressで進捗を把握できる。e.loadedはアップロードを行った容量で、e.totalは全体のアップロード容量である。
var request = new XMLHttpRequest(); request.upload.onprogress = function(e){ document.getElementById('progress').style.width = ((e.loaded / e.total) * 100 + "%"); }
onload でアップロードの完了を取得できる。
request.upload.onload = function(e){ document.getElementById('progress').style.width = '0px'; alert('finished'); } request.open('post', "./index.html"); request.send(files[i]);
Chromeについて
You can work around this by uploading the file via xmlhttprequest, maybe. I don’t
think Chrome has yet implemented the necessary HTML5 APIs for doing this yet,
unfortunately (they’re called FileStreams I think).
まだサポートしていないんじゃないか?と言ってるみたいだ。
WorkersからのDatabaseへのアクセスや,File API,XMLHttpRequestのFormData送信サポートなどはChrome 5での対応からChrome 6への対応に先送りされています
やっぱりFile APIへの対応はChrome6以降になったらしい。残念。
マイルストーン6で対応ですな=3
■サンプル
Firefox3.6以降でないと動かないですが、10MB以下のファイルを点線の中にドロップしてください。
You drop some files, here!
おまけ
jQuery1.4.2のbindを使うと、eventオブジェクトのプロパティdataTransferは、コールバック関数の引数のeventオブジェクトでは受け取れないようだ。従って、以下のコードは使えない。
$(elm).bind( 'drop', function(e){ e.preventDefault(); var files = e.dataTransfer.files; for(var i = 0; i < files.length; i++){ var request = new XMLHttpRequest(); request.upload.onprogress = function(e){ document.getElementById('progress').style.width = ((e.loaded / e.total) * 100 + "%"); } request.upload.onload = function(e){ document.getElementById('progress').style.width = '0px'; alert('finished'); } request.open('post', "./index.html"); request.send(files[i]); } e.preventDefault(); } );
以下のようにaddEventListenerを使用すれば良い。
elm.addEventListener( 'drop', function(e){ e.preventDefault(); var files = e.dataTransfer.files; for(var i = 0; i < files.length; i++){ var request = new XMLHttpRequest(); request.upload.onprogress = function(e){ document.getElementById('progress').style.width = ((e.loaded / e.total) * 100 + "%"); } request.upload.onload = function(e){ document.getElementById('progress').style.width = '0px'; alert('finished'); } request.open('post', "./index.html"); request.send(files[i]); } e.preventDefault(); }, false );
さらにdropだけでなく、input type=”file”のchangeにもハンドリング可能だ。
elm.addEventListener( 'change', function(e){ e.preventDefault(); var files = e.dataTransfer.files; for(var i = 0; i < files.length; i++){ var request = new XMLHttpRequest(); request.upload.onprogress = function(e){ document.getElementById('progress').style.width = ((e.loaded / e.total) * 100 + "%"); } request.upload.onload = function(e){ document.getElementById('progress').style.width = '0px'; alert('finished'); } request.open('post', "./index.html"); request.send(files[i]); } e.preventDefault(); }, false );
プログレスバーを参考にさせていただきました。
質問なのですがバイナリデータはsendでは送れないのでは?
自分も同じようなことをしているのですがFireFox限定のsendAsBinaryでないと無理でした。
どのようにして転送してるのでしょうか?
ご質問ありがとうございます。
長くなるので検証を含め、以下の記事で回答させていただきました!
/2010/06/14/%E3%82%82%E3%81%A3%E3%81%A8%E3%82%82%E3%81%A3%E3%81%A8file-api%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6%E3%82%B5%E3%83%BC%E3%83%90%E5%81%B4%E3%81%A7%E5%8F%97%E3%81%91%E5%8F%96%E3%81%A3%E3%81%A6%E3%81%BF/
凄く勉強になりました。
ピンバック: Tweets that mention もっとFile APIを使ってXMLHttpRequestと組み合わせてみる - @blog.justoneplanet.info -- Topsy.com