フロントエンドファイルアップロード-javascript-ajax


書くのはもっと良い記憶のためです.
シナリオ1:formフォームアップロード
このシナリオの利点は、サポートがよく、ページのリフレッシュが悪いことです.

原理:enctypeはformアップロードファイルのポイントです.

説明application/x-www-form-urlencoded
デフォルト.送信前にすべての文字をエンコード(スペースを「+」記号、特殊文字をASCII HEX値に変換)multipart/form-data
文字コードがありません.この値は、ファイルアップロードコントロールのあるフォームを使用する場合に必要です.text/plain
スペースを「+」記号に変換しますが、特殊文字は符号化されません.
シナリオ2:formフォームアップロード-シナリオの最適化の欠点
このスキームの利点もサポートされているが,欠点はドメイン間ではサポートされていないことである.

原理:targetで応答を1つのiframeページに指向し、その後、戻りデータを取得する.

説明_blank
新しいウィンドウ/タブで開く_self
既定では、同じフレームで開く_parent
親フレームで開きます._top
ウィンドウ全体で開くframename
指定したiframeで開く
シナリオ3:ajaxアップロード-シナリオの最適化の2つの欠点
このスキームの欠点は互換性の問題である-caniuseであり、互換性には2つの方向がある.1つは低バージョンieがサポートされていないCORSドメイン間であり、1つはinputが新たに追加されたFilesである.利点は非同期、進捗バー、判断サイズ、処理、ドメイン間である.
var file = input.files[0];
var xhr = new XMLHttpRequest();
if (xhr.upload) {
    xhr.upload.addEventListener("progress", function(e) {
        console.log(file, e.loaded, e.total);
    }, false);
    //           
    xhr.onreadystatechange = function(e) {
        if (xhr.readyState == 4) {
            if (xhr.status == 200) {
                console.log('  ', xhr.responseText)
            } else {
                console.log('  ')    
            }
        }
    }
    //     
    xhr.open("POST", 'url', true);
    xhr.send(file);
}

シナリオ4:ajax-formDataアップロード-マルチフィールドマルチファイル;
この案は基本的に同じで、ただFormDataを使っただけで、欠点はformDataの互換性です
var formData = new FormData();
formData.append('file', input.files[0]);
xhr.send(formData);

その他のシナリオ:
1. SWFupload Flash  
2. jquery.form.js       

需要一:ドラッグアップロードdropイベントを使用して、e.dataTransferを取得
document.querySelector('body').addEventListener("drop", (e)=>{
    e.preventDefault();//    ,    
    console.log(e.dataTransfer.files[0])
});

需要2:スクリーンショット-貼り付け-アップロードpasteイベントを使用して、e.clipboardDataを取得
document.querySelector('body').addEventListener("paste", (e)=>{
    e.preventDefault();//    ,    
    console.log(e.clipboardData.files[0])
});

需要3:base 64変換アップロード
シーンは、クライアントとインタラクティブな場合に発生し、クライアントが選択した画像はbase 64に返され、これをアップロードさせ、インタフェースの向こうはまだ変更されず、ファイルが必要になります.コードの书き込みがくどくどしていて、実はこんなに多くのものを使うことができなくて、その时も初めてatobBlobArrayBufferこれらのものに接触して、このように书きました.
  function(data){
    var _str = atob(data.base64Str)
    var _filePath = ((data.filePath.match(/.(jpg|jpeg|png|bmp)$/) || [])[1] || 'png').toLowerCase();
    var _filePathHash = {
        jpg:'image/jpeg',jpeg:'image/jpeg',png: 'image/png',bmp:'application/x-bmp',
    }
    var pre = '--------------------------1\r
Content-Disposition: form-data; name="file"; filename="1.png"\r
Content-Type: '+_filePathHash[_filePath]+'\r
\r
'; var end = '\r
--------------------------1--'; var buffer = new ArrayBuffer(_str.length); var uint8 = new Uint8Array(buffer); for(var i in _str){ uint8[i] = _str.charCodeAt(i); } var blob = new Blob([pre, uint8, end], {type: _filePathHash[_filePath]}); var oReq = new XMLHttpRequest(); oReq.open("POST", "url", true); oReq.setRequestHeader("Content-Type", "multipart/form-data; boundary=------------------------1") oReq.onreadystatechange=function(){if (oReq.readyState==4 && oReq.status==200){console.log(oReq.responseText); } oReq.send(blob);

需要四
アップロードは一般的にスタイルを書くので、デフォルトのinputスタイルだけでOKとは言えませんが、スタイルはそんなに書きにくいわけではありません.どうすればいいですか.
シナリオ1labelラベルのforinputのクリックをトリガーして、これでいいのではないでしょうか.inputのスタイルは書きにくいので、私たちは彼を隠して、labelにスタイルを書きます.
シナリオ2input[type=file]左はinput右はボタンで、実はボタンのスタイルが変更しにくいので、私达の外は1阶overlfow:hiddenを包んで、それからinputに1つの极めて大きいことを设置して、彼にすべての异なるものを譲って、すべて超えて、このように変えることができる区域で変更しました