js文件上傳中遇到的知識點

前言

在前端開發(fā)中冠桃,我們經(jīng)常遇到上傳文件的需求煞肾,以前都是用到時再找資料咧织,但總是感覺對這塊不熟,最近翻資料學習了一下籍救,記錄一下习绢。

本文中涉及的知識點有:FileList對象,Blob對象蝙昙,F(xiàn)ile對象闪萄,URL對象、FormData對象等奇颠。

本文參考網(wǎng)道败去,總結而來。另外烈拒,強烈推薦網(wǎng)道圆裕,可以去網(wǎng)道的官方看看,是阮一峰大神發(fā)起的項目荆几,提供互聯(lián)網(wǎng)開發(fā)文檔吓妆,文檔非常全面易懂。

FileList 對象

FileList對象吨铸,是一個像數(shù)組的對象行拢,擁有l(wèi)ength屬性和item()方法,同時诞吱,它的每一項都是File對象舟奠。

input 標簽,將type設為file狐胎,之后得到的files屬性就是一個FileList對象鸭栖。

    // html
    <input type="file" accept="image/*" id="fileDiv" />
    
    // js
    var fileInput = document.getElementById('fileDiv');
    var fileListObj = fileInput.files;
    console.log(fileListObj instanceof FileList); // true
    console.log(fileListObj.length); // 0
    

Blob 對象

blob 對象表示1個二進制文件的數(shù)據(jù)內(nèi)容。blob對象和arraybuffer區(qū)別是握巢,blob對象用于操作二進制文件,arraybuffer用于操作內(nèi)存松却。

blob 對象擁有2個屬性和1個方法暴浦,分別是size(單位是字節(jié))、type屬性和slice()方法晓锻。

File 對象

File 對象是一種特殊的Blob 對象歌焦。它在繼承了size、type屬性外砚哆,還同時有name独撇、lastModified、lastModifiedDate等幾個屬性。

FileList 對象中的每一項都是File 對象纷铣。

拿到File 對象之后就要進行操作卵史,下面是操作。

URL 對象

URL.createObjectURL(file) 允許為File 對象創(chuàng)建一個臨時鏈接搜立,

 // 例如我們可以在選中了圖片之后以躯,展示到頁面上
 // html
 <input type="file" accept="image/*" id="fileDiv" onchange="getFile(this.files[0])" />
 <img id="myimg" />
 
 // js
 function getFile(file){
    var urlObj = URL.createObjectURL(file);
    var myimg = document.getElementById('myimg');
    myimg.src = urlObj;
    console.log(urlObj);
 }

 /**
 * 輸出如下:
 * blob:http://127.0.0.1:8848/1410c491-27e2-47fa-8198-1d1ea4eece46
 */

FileReader 對象

FileReader 對象的屬性和方法比較多,屬性中比較重要的是result啄踊,方法中比較重要的是

  • readAsText(file[,code]) 將文件讀取成為文本數(shù)據(jù)忧设,第二個參數(shù)默認采用utf-8編碼,返回到FileReader的result屬性中
  • readAsArrayBuffer(file) 將文件讀取成為內(nèi)存數(shù)據(jù)颠通,返回到FileReader的result屬性中
  • readAsBinaryString(file) 將文件讀取成為原始二進制數(shù)據(jù)址晕,返回到FileReader的result屬性中
  • readAsDataURL(file) 將文件讀取成為base64字符串,返回到FileReader的result屬性中
    // 例如顿锰,將文件讀取為base64數(shù)據(jù)谨垃,賦值給Img.src屬性
    // html
    <input type="file" accept="image/*" id="fileDiv" onchange="getFile(this.files[0])" />
    <img id="myimg" />
    
    // js
    function getFile(file){
        var myimg = document.getElementById('myimg');
        var reader = new FileReader();
        reader.onload = function(){
            myimg.src = reader.result;
        }
        reader.readAsDataURL(file);
    }

FileReader 對象的所有屬性和方法可以參考這里,這里就不再列出來了。

FormData 對象

在早期的互聯(lián)網(wǎng)時候撵儿,提交數(shù)據(jù)都是用表單乘客。表單提交數(shù)據(jù)有些缺陷,例如無法校驗表單數(shù)據(jù)淀歇,會刷新整個頁面等易核。隨著Ajax的興起,頁面表單提交數(shù)據(jù)慢慢退出歷史舞臺浪默,但有時上傳文件時我們偶爾會用到表單提交數(shù)據(jù)牡直。

在調(diào)用構造函數(shù)new FormData(form)構造formdata對象時需要傳入form節(jié)點,如果不傳入纳决,則默認構建空表單碰逸。如果傳入,則按照key=value的時候構建表單阔加。

    // html
    <form id="myform">
        <input name="username" type="text" placeholder="請輸入用戶名" />
        <br />
        <br />
        <input name="password" type="password" placeholder="請輸入密碼" />
        <br />
        <br />
        <input name="age" type="number" placeholder="請輸入年齡" />
    </form>
    <br />
    <input type="button" value="創(chuàng)建表單" id="mybtn" />
 
    // js
    var btn = document.getElementById('mybtn');
    btn.onclick = function(){
        var formNode = document.getElementById('myform');
        var formdata = new FormData(formNode);
        for(var pair of formdata.entries()){
            console.log(pair[0] + ': ' + pair[1]);
        }
    }

可以看看效果圖


formdata.png

FormData 對象主要的方法有:

  • get(key) 返回指定key的鍵值
  • getAll(key) 返回指定key的所有鍵值饵史,如果有多個的話。(注意: set()方法會覆蓋同名鍵值對胜榔,append()方法則不會覆蓋)胳喷,返回值是1個數(shù)組
  • set(key, value) 設置鍵值對
  • delete(key) 刪除鍵值對
  • append(key, value) 在formdata對象后邊添加鍵值對,如果第二個參數(shù)是文件夭织,還可以使用第三個參數(shù)吭露,表示文件名。
  • has(key) 返回布爾值尊惰,表示是否具有該鍵名的鍵值對讲竿。
  • keys() 返回一個遍歷器對象泥兰,用于for...of循環(huán)遍歷所有的鍵名。
  • values() 返回一個遍歷器對象题禀,用于for...of循環(huán)遍歷所有的鍵值鞋诗。
  • entries() 返回一個遍歷器對象,用于for...of循環(huán)遍歷所有的鍵值

cavas壓縮圖片

cavas壓縮圖片其實很簡單投剥,無非就是幾個步驟:
1师脂、選擇圖片,判斷圖片是否大于2M(用File對象的size進行判斷江锨,size的單位是字節(jié))吃警;
2、用FileReader對象讀取文件成base64,
3啄育、然后創(chuàng)建Image對象酌心,賦值src屬性,在Image對象加載完成的回調(diào)里創(chuàng)建cavas并繪制圖片(根據(jù)圖片是否大于2M動態(tài)調(diào)整畫布大小)挑豌;
4安券、將cavas轉成blob,拼在formdata中用ajax上傳氓英。


// 選擇圖片
$("#idcard_reverse_input").change(function (e) {

        var loading = weui.loading('上傳中...');
        // 判斷是否大于2M侯勉,大于2M需要壓縮圖片后再上傳
        var result = e.target.files[0].size > 2*1024*1024;
        var fileObj = e.target.files[0]; //上傳文件的對象

        var reader = new FileReader();
        reader.readAsDataURL(fileObj);
        reader.onload = function(er) {
            var image = new Image()
            image.src = er.target.result;
            image.onload = function() {
                var canvas = document.createElement('canvas'), 
                context = canvas.getContext('2d'),
                imageWidth = result?image.width * 0.1:image.width,    //動態(tài)計算畫布大小
                imageHeight = result?image.height * 0.1:image.height;
                               
                // 將畫布縮小為圖片的1/10,然后將圖片縮小畫入畫布中铝阐,之后到處畫布就能達到壓縮圖片的效果址貌。
                canvas.width = imageWidth;
                canvas.height = imageHeight;
                context.drawImage(image, 0, 0, imageWidth, imageHeight);
                
                canvas.toBlob(function(blob){
                    uploadReverse(blob,loading,true)
                },'image/jpeg',0.8)
            }
        }
    });
    
    function uploadReverse(fileObj,loading,isReverse){
        var time = new Date().getTime();
        var str = 'code=G1&time=' + time;
       // fileSecret是個全局變量,是個秘鑰
        var apisign = md5(fileSecret + str);

        // 構造表單數(shù)據(jù)
        var formData = new FormData();
        var imgName = isReverse ? 'reverse.png' : 'front.png'
        formData.append("file",fileObj,imgName);
        formData.append("apisign", apisign);
        formData.append("time", time);
        formData.append("code", 'G1');
        $.ajax({
            url : 'http://example.baidu.com/upload',
            type:'post',
            data: formData,
            contentType: false,
            processData: false,
            success:function(res){
                if(res.status != '1'){
                    weui.alert(res.info);
                    return ;
                }
                // 上傳成功
            },
            fail : function(){
                weui.alert('上傳失敗,請重新選擇圖片上傳!')
            },
            complete:function(){
                loading.hide()
            }
        })
    }

總結

這篇文章到這里也就結束了徘键,這篇文章包含了一些瀏覽器中提供的對象练对,可以看到都是很簡單的內(nèi)容。

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末吹害,一起剝皮案震驚了整個濱河市螟凭,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌它呀,老刑警劉巖螺男,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異纵穿,居然都是意外死亡烟号,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進店門政恍,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人达传,你說我怎么就攤上這事篙耗∑戎” “怎么了?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵宗弯,是天一觀的道長脯燃。 經(jīng)常有香客問我,道長蒙保,這世上最難降的妖魔是什么辕棚? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮邓厕,結果婚禮上逝嚎,老公的妹妹穿的比我還像新娘。我一直安慰自己详恼,他們只是感情好补君,可當我...
    茶點故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著昧互,像睡著了一般挽铁。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上敞掘,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天叽掘,我揣著相機與錄音,去河邊找鬼玖雁。 笑死更扁,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的茄菊。 我是一名探鬼主播疯潭,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼面殖!你這毒婦竟也來了竖哩?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤脊僚,失蹤者是張志新(化名)和其女友劉穎相叁,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體辽幌,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡仗颈,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了壳影。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片戒祠。...
    茶點故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖加酵,靈堂內(nèi)的尸體忽然破棺而出拳喻,到底是詐尸還是另有隱情哭当,我是刑警寧澤,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布冗澈,位于F島的核電站钦勘,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏亚亲。R本人自食惡果不足惜彻采,卻給世界環(huán)境...
    茶點故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望捌归。 院中可真熱鬧肛响,春花似錦、人聲如沸陨溅。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽门扇。三九已至雹有,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間臼寄,已是汗流浹背霸奕。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留吉拳,地道東北人质帅。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像留攒,于是被迫代替她去往敵國和親煤惩。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,786評論 2 345

推薦閱讀更多精彩內(nèi)容