使用Input type=file 原生上傳使用總結

reggie發表於2021-07-26

最新發現之前專案裡用的 js 上傳外掛有點點問題 就是上傳同一張圖片會報錯圖片限制的型別錯誤 不知道是不是自己引數什麼沒設定對 然後想到了使用input標籤中的type=file這種原生的上傳 寫下分享下

傳統的上傳

比如我們在正常的form表單中需要上傳一張圖片 一般不使用外掛之類的常用做法就是先設定form屬性 enctype ="multipart/form-data" 最後提交form表單 然後後天那邊自己寫處理接受儲存啥的 但是這樣做會直接重新整理頁面 很多時候我們不希望提交頁面這種 一般都會想到ajax之類 當然也有別的方法。

Ajax上傳

使用ajax上傳時 需要把要提交的資料組成key=>value的形式 但是檔案流就比較麻煩了 他不能被轉換成字元之類 即使你使用serialize 也不能把檔案流序列化 然後傳送到後端 不過沒關係 有個 FormData的玩意可以幫助我們在 ajax 中提交檔案流

FormData 簡介

The FormData interface provides a way to easily construct a set of key/value pairs representing form fields and their values, which can then be easily sent using the XMLHttpRequest.send() method. It uses the same format a form would use if the encoding type were set to “multipart/form-data”.
大概就是說 FormData 介面提供了一種很方便的方法去構建表單中的 屬性=>值 的這種鍵值對結構 另外他還可以使用 XMLHttpRequest.send() 來傳送非同步請求 如果設定了 multipart/form-data 還可以使用和form表單一樣的格式化

1.建立一個formdata物件
var formData = new FormData();
2.新增屬性值 append方法有2個版本 一個是傳2個引數的 一個是傳遞3個引數的
①formData.append('key_name','value'); //這種可以用來設定普通的字串之類的值
②formData.append('key_name','value','file_name'); //這種用來設定 Blob 和 File 型別的值 如果是blob型別的 第三個引數預設寫 ‘blob’就行 如果是file 型別 預設就寫上傳的檔名就行
eg:formData.append('file',myFileInput.files[0],'test.jpg');
3.設定的Key也可以是陣列形式
formData.append('userpic[]', myFileInput1.files[0], 'chris1.jpg');
formData.append('userpic[]', myFileInput2.files[0], 'chris2.jpg');

其實我用append()2個引數的也可以提交file 第二個引數直接傳遞 file 物件就可以了
具體參考 MDN 這裡有詳細的介紹 包括瀏覽器的相容情況等等

透過Ajax使用FormData實現上傳圖片

html:

<label for="uploadID_face" class="show_info show_info_face" id="show_info_face">+身份證正面</label>
<input class="hide"  type="file" id="uploadID_face" />

我做了一個lable-for的繫結 不用學我
js:

$(function(){
    $('#uploadID_face').change(function(){
            var file=this.files[0]; //這裡是獲取file物件 id對應了上面的input的id屬性 0 表示取的第一個
            reader = new FileReader(); //這個filereader物件也是 MDN mozilla裡的東東 可以看看
            reader.readAsDataURL(file); //這個就是把檔案讀取成base64的格式 輸出成圖片的一個url一樣的東東可以在本地訪問到圖片 傳遞進來的file物件已經被處理過了
            //console.log(file);
            reader.onload = function( evt ){
                var formData = new FormData();
                formData.append('file',file);
                console.log(reader.result);
                new_fileload(formData);
           }
    });

    function new_fileload(formData){
            $.ajax({
                type:"post",
                url:'your upload url',
                processData: false,
                cache: false,
                contentType: false,
                data:formData,
                success:function(data){
                    //上傳結果的判斷以及後續的一些操作 比如上傳顯示縮圖等
                }
            });
        }
}

上面的ajax中需要注意幾個引數
1.processData 設定為false 表示對formdata物件不做處理
2.cache設定為false 表示上傳檔案不需要快取
3.contentType設定為false 表示表示不設定該值

然後後臺接受處理就好了 因為我上面的formData中設定的名字是file所以後臺接受了一個file的變數名

$fileData=$_FILES['file'];
//使用了CurlFile構建了一個後端file檔案物件 自己寫的上傳需要
$file   = new CURLFile($fileData['tmp_name'], $fileData['type'], $fileData['name']);

僅供參考

本作品採用《CC 協議》,轉載必須註明作者和本文連結
微信公眾號:碼咚沒 ( ID: codingdongmei )

相關文章