通過(guò)Ajax方式上傳文件——FormData 對(duì)象的使用

傳統(tǒng)的方式通過(guò)form表單上傳文件

前端向服務(wù)器上傳文件的方法有很多種闻镶,傳統(tǒng)的方式是通過(guò)form表單甚脉,在form表單中配置:enctype ="multipart/form-data"屬性。

<form id= "uploadForm" action= "http://localhost:8080/cfJAX_RS/rest/file/upload" method= "post" enctype ="multipart/form-data">  
     <h1 >測(cè)試通過(guò)Rest接口上傳文件 </h1>  
     <p >指定文件名: <input type ="text" name="filename" /></p>  
     <p >上傳文件: <input type ="file" name="file" /></p>  
     <p >關(guān)鍵字1: <input type ="text" name="keyword" /></p>  
     <p >關(guān)鍵字2: <input type ="text" name="keyword" /></p>  
     <p >關(guān)鍵字3: <input type ="text" name="keyword" /></p>  
     <input type ="submit" value="上傳"/>  
</form>  

不過(guò)傳統(tǒng)的form表單提交會(huì)導(dǎo)致頁(yè)面刷新铆农,但是在有些情況下牺氨,我們不希望頁(yè)面被刷新,這種時(shí)候我們都是使用Ajax的方式進(jìn)行請(qǐng)求的:

$.ajax({  
     url : "http://localhost:8080/STS/rest/user",  
     type : "POST",  
     data : $( '#postForm').serialize(),  
     success : function(data) {  
          $( '#serverResponse').html(data);  
     },  
     error : function(data) {  
          $( '#serverResponse').html(data.status + " : " + data.statusText + " : " + data.responseText);  
     }  
});  

如上墩剖,通過(guò)$('#postForm').serialize()可以對(duì)form表單進(jìn)行序列化猴凹,從而將form表單中的所有參數(shù)傳遞到服務(wù)端。
但是上述方式岭皂,只能傳遞一般的參數(shù)郊霎,上傳文件的文件流是無(wú)法被序列化并傳遞的。

不過(guò)如今主流瀏覽器都開始支持一個(gè)叫做FormData的對(duì)象蒲障,有了這個(gè)FormData歹篓,我們就可以輕松地使用Ajax方式進(jìn)行文件上傳了

關(guān)于FormData及其用法:

以下是官方的介紹:

XMLHttpRequest Level 2添加了一個(gè)新的接口FormData瘫证。利用FormData對(duì)象,我們可以通過(guò)JavaScript用一些鍵值對(duì)來(lái)模擬一系列表單控件庄撮,我們還可以使用XMLHttpRequest的send()
方法來(lái)異步的提交這個(gè)"表單"背捌。比起普通的ajax,使用FormData的最大優(yōu)點(diǎn)就是我們可以異步上傳一個(gè)二進(jìn)制文件洞斯。
通過(guò)FormData對(duì)象可以組裝一組用 XMLHttpRequest發(fā)送請(qǐng)求的鍵/值對(duì)毡庆。它可以更靈活方便的發(fā)送表單數(shù)據(jù),因?yàn)榭梢元?dú)立于表單使用烙如。如果你把表單的編碼類型設(shè)置為multipart/form-data 么抗,則通過(guò)FormData傳輸?shù)臄?shù)據(jù)格式和表單通過(guò)submit()方法傳輸?shù)臄?shù)據(jù)格式相同。

FormData用法:

你可以自己創(chuàng)建一個(gè)FormData對(duì)象亚铁,然后通過(guò)調(diào)用它的append()方法添加字段蝇刀,就像這樣:

var formData = new FormData();

formData.append("username", "Groucho");
formData.append("accountnum", 123456); // 數(shù)字 123456 會(huì)被立即轉(zhuǎn)換成字符串 "123456"

// HTML 文件類型input,由用戶選擇
formData.append("userfile", fileInputElement.files[0]);

// JavaScript file-like 對(duì)象
var content = '<a id="a"><b id="b">hey!</b></a>'; // 新文件的正文...
var blob = new Blob([content], { type: "text/xml"});

formData.append("webmasterfile", blob);

var request = new XMLHttpRequest();
request.open("POST", "http://foo.com/submitform.php");
request.send(formData);

上面的示例創(chuàng)建了一個(gè)FormData實(shí)例徘溢,包含"username", "accountnum", "userfile" 和 "webmasterfile"四個(gè)字段吞琐,然后使用XMLHttpRequest的send()方法發(fā)送表單數(shù)據(jù)。字段 "webmasterfile" 是 Blob類型然爆。一個(gè) Blob對(duì)象表示一個(gè)不可變的, 原始數(shù)據(jù)的類似文件對(duì)象站粟。Blob表示的數(shù)據(jù)不一定是一個(gè)JavaScript原生格式。 File接口基于Blob曾雕,繼承 blob功能并將其擴(kuò)展為支持用戶系統(tǒng)上的文件奴烙。你可以通過(guò) Blob()構(gòu)造函數(shù)創(chuàng)建一個(gè)Blob對(duì)象。

使用FormData對(duì)象上傳文件:

使用的時(shí)候需要在表單中添加一個(gè)文件類型的input:

<form enctype="multipart/form-data" method="post" name="fileinfo">
  <label>Your email address:</label>
  <input type="email" autocomplete="on" autofocus name="userid" placeholder="email" required size="32" maxlength="64" /><br />
  <label>Custom file label:</label>
  <input type="text" name="filelabel" size="12" maxlength="32" /><br />
  <label>File to stash:</label>
  <input type="file" name="file" required />
  <input type="submit" value="Stash the file!" />
</form>

然后使用下面的代碼發(fā)送請(qǐng)求:

var form = document.forms.namedItem("fileinfo");
form.addEventListener('submit', function(ev) {
  var oOutput = document.querySelector("div"),
      oData = new FormData(form);
  oData.append("CustomField", "This is some extra data");
  var oReq = new XMLHttpRequest();
  oReq.open("POST", "stash.php", true);
  oReq.onload = function(oEvent) {
    if (oReq.status == 200) {
      oOutput.innerHTML = "Uploaded!";
    } else {
      oOutput.innerHTML = "Error " + oReq.status + " occurred when trying to upload your file.<br \/>";
    }
  };
  oReq.send(oData);
  ev.preventDefault();
}, false);
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末剖张,一起剝皮案震驚了整個(gè)濱河市切诀,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌修械,老刑警劉巖趾牧,帶你破解...
    沈念sama閱讀 210,978評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異肯污,居然都是意外死亡翘单,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門蹦渣,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)哄芜,“玉大人,你說(shuō)我怎么就攤上這事柬唯∪想” “怎么了?”我有些...
    開封第一講書人閱讀 156,623評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵锄奢,是天一觀的道長(zhǎng)失晴。 經(jīng)常有香客問(wèn)我剧腻,道長(zhǎng),這世上最難降的妖魔是什么涂屁? 我笑而不...
    開封第一講書人閱讀 56,324評(píng)論 1 282
  • 正文 為了忘掉前任书在,我火速辦了婚禮,結(jié)果婚禮上拆又,老公的妹妹穿的比我還像新娘儒旬。我一直安慰自己,他們只是感情好帖族,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,390評(píng)論 5 384
  • 文/花漫 我一把揭開白布栈源。 她就那樣靜靜地躺著,像睡著了一般竖般。 火紅的嫁衣襯著肌膚如雪甚垦。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,741評(píng)論 1 289
  • 那天涣雕,我揣著相機(jī)與錄音制轰,去河邊找鬼。 笑死胞谭,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的男杈。 我是一名探鬼主播丈屹,決...
    沈念sama閱讀 38,892評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼伶棒!你這毒婦竟也來(lái)了旺垒?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,655評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤肤无,失蹤者是張志新(化名)和其女友劉穎先蒋,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體宛渐,經(jīng)...
    沈念sama閱讀 44,104評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡竞漾,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了窥翩。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片业岁。...
    茶點(diǎn)故事閱讀 38,569評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖寇蚊,靈堂內(nèi)的尸體忽然破棺而出笔时,到底是詐尸還是另有隱情,我是刑警寧澤仗岸,帶...
    沈念sama閱讀 34,254評(píng)論 4 328
  • 正文 年R本政府宣布允耿,位于F島的核電站借笙,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏较锡。R本人自食惡果不足惜业稼,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,834評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望念链。 院中可真熱鬧盼忌,春花似錦、人聲如沸掂墓。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)君编。三九已至跨嘉,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間吃嘿,已是汗流浹背祠乃。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留兑燥,地道東北人亮瓷。 一個(gè)月前我還...
    沈念sama閱讀 46,260評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像降瞳,于是被迫代替她去往敵國(guó)和親嘱支。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,446評(píng)論 2 348

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