摘自《JavaScript高級程序設計》
并非所有瀏覽器都完整地實現了XMLHttpRequest2級規范,但所有瀏覽器都實現了它規定的部分內容 。
現代Web應用中頻繁使用的一項功能就是表單數據的序列化,XMLHttpRequest2級為此定義了FormData類型。FormData為序列化表單以及創建與表單格式相同的數據(用于通過XHR傳輸)提供了便利。下面的代碼創建了一個FormData對象,并向其中添加了一些數據。
var data = new FormData();
data.append("name", "Nicholas");
這個append()方法接收兩個參數:鍵和值,分別對應表單字段的名字和字段中包含的值。可以像這樣添加任意多個鍵值對兒。而通過向FormData構造函數中傳入表單元素,也可以用表單元素的數據預先向其中填入鍵值對兒:
var data = new FormData(document.forms[0]);
創建了FormData的實例后,可以將它直接傳給XHR的send()方法,如下所示:
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
? ? ?if(xhr.readyState == 4) {
? ? ? ? ? ? if((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){
? ? ? ? ? ? ? ? ? ? alert(xhr.responseText);
? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? ? ?alert("Request was unsuccessful:" + xhr.status);
? ? ? ? ? ?}
? ? }
};
xhr.open("post", "postexample.php", true);
var form = document.getElementById("user-info");
xhr.send(new FormData(form));
使用FormData的方便之處體現在不必明確地在XHR對象上設置請求頭部。XHR對象能夠識別傳入的數據類型是FormData的實例,并配置適當的頭部信息。
支持FormData的瀏覽器有Firefox4+、Safari5+、Chrome和Android3+版WebKit。
接下來是利用XMLHttpRequest上傳文件實現進度條的例子:
(摘自http://www.cnblogs.com/tianyuchen/p/5594641.html和自己項目代碼的結合)
<script ? type="text/javascript">
//上傳文件方法
function uploadFile() {
? ? ? var ? fileObj = document.getElementById("file").files[0]; //js獲取文件對象
? ? ? var url = "uploadFile"; //接收上傳文件的后臺地址
? ? ? var form?= new FormData(); ? //創建一個FormData對象
? ? ? form.append("mf", fileObj); //向FormData對象里添加數據
? ? ? var xhr = new XMLHttpRequest();? //創建XMLHttpRequest對象
? ? ? xhr.onload = ?uploadComplete; //請求完成
? ? ? xhr.onerror = uploadFailed; //請求失敗
? ? ? xhr.onabort = uploadCanceled; //取消上傳
? ? ? xhr.upload.onprogress =? uploadProgress; //上傳進度調用方法實現
? ? ? xhr.open("post", url, true); ?//post方式提交,url為服務器請求地址,true該參數規定請求是否異步處理
? ? ? xhr.send(form); //開始上傳,發送form數據
}
//上傳進度實現方法,上傳過程中會頻繁調用該方法
function uploadProgress(evt){
? ? var progressBar = document.getElementById("progressBar");
? ? var percentage = document.getElementById("percentage");
? ? var done = evt.position || evt.loaded;
? ? var total = evt.totalSize || evt.total;
? ? if(evt.lengthComputable){
? ? ? ?progressBar.max = total;
? ? ? progressBar.value = done;
? ? ? percentage.innerHTML = Math.round(done / total * 100) + "%" ;?
? ? } else {
? ? ? ?percentage.innerHTML = "unable to compute";
? ? ? }
}
//上傳成功響應
function uploadComplete(evt) {
? ?var responseText = evt.target.responseText; //服務器接收完文件返回的響應文本
? ?alert("上傳成功!");
}
//上傳失敗
function uploadFailed(evt) {
? ?alert("上傳失敗!");
}
//取消上傳
function uploadCanceled(evt) {
? ?alert("The upload has been canceled by the user or the browser dropped the connection.");
}
</script>
<body>
? ? ?注:Internet Explorer 9 以及更早的版本不支持 progress標簽
? ? ?<progress id="progressBar" value="0" max="100" ?style="width:300px;"></progress>
? ? ?<span id="percentage"></span>
? ? ?<input type="file" id="file" name="myfile">
? ? ?<input type="button" onclick="uploadFile()" value="上傳">
? ? <input type="button" onclick="uploadCanceled()" value="取消">
</body>
progress事件
onprogress事件處理程序會接收到一個event事件,其target屬性是XHR對象,但包含著三個額外的屬性:lengthComputable、position和totalSize。其中,lengthComputable是一個表示進度信息是否可用的布爾值,position標識已經接收的字節數,totalSize表示根據Content-Length響應頭部確定的預期字節數。
注:為確保正常執行,必須在調用open()方法之前添加onprogress事件處理程序。
下篇文章將講述跨域問題