傳統(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);