画像をドラッグしてアップロード
12949 ワード
長い間ブログを書いたことがなくて、暇な時に書くものがなくて、忙しい時に書く時間がありません.
先日、バックグラウンドの同僚は、画像をアップロードするのはあまり使いにくいとアドバイスしました.バックグラウンドのオンラインエディタはfckeditorを使っています.その時、ずっと前にユーザーエクスペリエンスの向上:HTML 5ドラッグ&ドロップファイルのアップロードを見たことがあると思って、写真をドラッグしてアップロードする機能を作ろうとしました.
バックグラウンド用なのでieの互換性は考慮しなくてもいいです.
1.画像をブラウザにドラッグすると、ブラウザのデフォルトの動作がブロックされます(直接画像を開くなど)
dropboxは私たちのコンテナにいくつかのイベントバインドdragenter,dragover,dropの3つのイベントを追加しました.
dropbox.addEventListener("dragenter", function(e){ e.stopPropagation(); e.preventDefault(); }, false);
dropbox.addEventListener("dragover" , function(e){ e.stopPropagation(); e.preventDefault(); }, false);
dropbox.addEventListener("drop", function(e){
e.stopPropagation(); // , dropbox drop , ( )
e.preventDefault(); //
e.dataTransfer.files// file ,
}, false);
2.ファイルfileを取得したら、それを表示します.
画像をプレビューするにはFileReaderを使用します.
1 var rd=new FileReader();
2 rd.onloadend=function(e){
3 var img=document.createElement('img');//
4 img.src=this.result;//result
5 img.width=100;
6 img.title=file.name;//
7
8 }
9 rd.readAsDataURL({file}); // dataurl
Filereaderには次の方法があります.画像をプレビューするにはreadAsData URLを使用します.
メソッド名
パラメータ
説明
abort
none
わりこみよみとり
readAsBinaryString
file
ファイルをバイナリコードとして読み込む
readAsDataURL
file
データURLとしてファイルを読み込む
readAsText
file, [encoding]
ファイルをテキストとして読み込む
3.画像をサービス側に送信し、処理する
サーバにコミットするには、画像をバイナリ形式に読み込む必要があります.ここでは、FilereaderのreadAsBinaryStringを使用します.
1 var reader = new FileReader();
2 reader.readAsBinaryString({file});
3
4 reader.onloadend = function(){
5 //bug(this.readyState); // 2
6 //bug(this.result); // , result
7 var fileData=this.result;
8 var CRLF="\r
";
9 var xhr = new XMLHttpRequest();
10 xhr.open('post', self.server, true);
11 //xhr.onreadystatechange=function(){};
12 var boundary='------OTkwNzI0OTEx----';// , ,
13 //
14 xhr.setRequestHeader("Content-Type", "multipart/form-data, boundary="+boundary);
15 //xhr.setRequestHeader("Content-Length", file.size); chrome , ,
16 var body = '';
17 body += '--' + boundary + CRLF;
18 body += 'Content-Disposition: form-data; name="'+{fileFieldName}+'"; filename="' + file.name + '"'+CRLF;
19 body += "Content-Type: "+file.type+CRLF+CRLF;
20 body += fileData + CRLF;
21 body += "--" + boundary + "--"+CRLF;
22 xhr.onreadystatechange = function (aEvt) {
23 if (xhr.readyState == 4) {
24 if (xhr.status == 200)
25 alert(xhr.responseText);
26 else
27 console.log('Error', xhr.statusText);
28 }
29 };
30
31 xhr.sendAsBinary(body);
32
33
34
35 }
上のコードの18行目のfilenameが直接使う元のファイルの名前、名前を変えていないで、これは元の名前が漢字の情況の下で誤りをヒントにすることができて、処理するべきで、しかしどのようにいじることを知りません
値
説明
application/x-www-form-urlencoded
送信前にすべての文字をエンコード(デフォルト)
multipart/form-data
文字コードがありません.ファイルアップロードコントロールを含むフォームを使用する場合は、この値を使用する必要があります.
text/plain
スペースは「+」プラス記号に変換されますが、特殊文字は符号化されません.
上はw 3 cschoolで検索しましたが、multipart/form-dataが文字符号化されていない以上、なぜエラーが発生したのか、シミュレーションしたデータをバイナリで送信するように伝えてほしいです.火狐XMLHttpRequestオブジェクトにはsendAsBinary()メソッドがあります.これは火狐プライベートです.chromeにはありませんが、アナログsendAsBinary
1 XMLHttpRequest.prototype.sendAsBinary = function(datastr) {
2 function byteValue(x) {
3 return x.charCodeAt(0) & 0xff;
4 }
5 var ords = Array.prototype.map.call(datastr, byteValue);
6 var ui8a = new Uint8Array(ords);
7 this.send(ui8a.buffer);
8 }
サービス側がファイルを受信するときは、通常のアップロード時と同様にphpコードなどです.
if(!empty($_FILES)){
$file=$_FILES['new_image']; //new_image fileFieldName
echo $file['name'];
move_uploaded_file($file['tmp_name'],"./zf/".$file['name']);
die();
}
4.アップロードの進捗を表示
1 var xhr = new XMLHttpRequest();
2 upload =xhr.upload;
3 upload.addEventListener("progress", updateProgress, false);//updateProgress
4 xhr.open('post', “ url”, true);
5
6 function updateProgress(evt) {
7 if (evt.lengthComputable) {
8 var percentComplete = Math.round((evt.loaded * 100) / evt.total)
9 bug(percentComplete);
10
11 }
12 else {
13 // Unable to compute progress information since the total size is unknown
14 }
15 }
これも簡単です.コードは上記の通りですが、注意しなければならないのは:
1.イベントは、アップロードの進行状況をリスニングするためにXMLHttpRequestのuploadにバインドされます.XMLHttpRequestにはprogressイベントもありますが、ダウンロードを傍受しています.2.火狐とchromeがupdateProgressを呼び出す頻度は同じようですが、具体的には毎秒1回呼び出すかどうかはよく分かりません.ファイルが小さく、ネットワークが速く(ローカルでテストされた場合、もちろん速く)FFはprogressイベントをトリガーしません.火狐の下では、アップロードが完了してもイベントがトリガーされないので、いつも100%にならず、80,90パーセントになると動かなくなります.
はい、機能は基本的に実現しました.また、上のコードは私が文章を書いてコピーしたものです(1週間近く書いて、暇があれば書いて、プログラムの基本機能が完成したのは2週間前です.).最後に、私が資料を検索して見つけたjqueryプラグインjquery-filedropを添付します.
ソースのダウンロード