第壹種:經典的form和input上傳。
設置form的aciton為後端頁面,enctype="multipart/form-data",type=‘post’
<form?action='/'?enctype="multipart/form-data"?type='post'> <input?type='file'> <input?type='hidden'?name='userid'> <input?type='hidden'?name='signature'> <button>提交</button></form>使用input選擇文件,設置好其他input的值,點擊提交,將文件數據及簽名等認證信息發送到form設置的action對應的頁面,瀏覽器也會跳轉到該頁面。觸發form表單提交數據的方式有2種,壹種是在頁面上點擊button按鈕或<input
type='submit'>按鈕觸發,第二種是在js中執行form.submit()方法。
優點:使用簡單方便,兼容性好,基本所有瀏覽器都支持。
缺點:1. 提交數據後頁面會跳轉(下面會講如何禁止頁面跳轉)。
2.因為是瀏覽器發起的請求,不是壹個ajax,所以前端無法知道什麽時候上傳結束。
3. form表單裏發送除文件外的數據,壹般是新建壹個type=hidden的input,value=‘需要傳的數據’,每發送壹個數據就需要壹個input,壹旦多了就會使得dom看起來比較冗余。
小技巧:
form表單提交數據後會自動跳轉到action指定的頁面,為了禁止頁面跳轉,可以在頁面中新建壹個空的ifame,比如name='upload',然後設置form的target="Uploader",form有壹個target的屬性,規定在何處打開action,這樣form提交數據後就會仍停留在當前頁。代碼如下:
<form?action='/'?enctype="multipart/form-data"?type='post'?target="uploader1"><input?type='file'><button>提交</button></form><ifrmae?name='upload'?id='uploader1'></iframe>這樣寫的另壹個好處是,可以知道什麽時候上傳完成並接收到後端的回調結果。比如上面這個例子,文件數據發送到了
'uploadFile.php',假設該頁面處理完數據後返回了壹個地址,該地址會被寫入到之前的iframe中。所以在ifame的onload函數觸發時,也就是上傳完成後,可以在iframe中讀取到後端返回的數據。
var?iframe?=?document.getElementById('upload1');iframe.onload?=?function?()?{?
var?doc?=?window.frames['uploader1'].document;var?pre?=?doc.getElementsByTagName('pre');var?obj?=?JSON.parse(pre[0].innerHTML);
}
使用這種方法時需要註意,iframe有跨域限制,創建出來的iframe的地址如果和當前頁面地址不同源,會報錯。這種情況下,建議大家在iframe的onload函數中,再次向後端請求壹個接口獲取文件地址,而不是直接去iframe裏讀取。或者返回這樣的數據。
<script?type="text/javascript">window.top.window[callback](data)</script>callback是和前端約定好的名字,上傳完成後觸發該函數並返回後端數據。
第二種:使用formData上傳。
用js構造form表單的數據,簡單高效,但最低只兼容IE10,所以需要兼容IE9的童鞋們就略過這個方法吧。
html:
<input?type='file'>js:
var?formData?=?new?FormData();formData.append("userid",?userid);
formData.append("signature",?signature);
formData.append("file",?file);?//file是blob數據//再用ajax發送formData到服務器即可,
註意壹定要是post方式上傳
說明:第壹種方法提到了創建多個type=‘hidden’的input來發送簽名數據,這兒可以用formData.append方法來代替該操作,避免了dom中有多個input的情況出現。最後將file數據也append到formData發送到服務器即可完成上傳。
優點:由於這種方式是ajax上傳,可以準確知道什麽時候上傳完成,也可以方便地接收到回調數據。
缺點:兼容性差
第三種:使用fileReader讀取文件數據進行上傳。
HTML5的新api,兼容性也不是特別好,只兼容到了IE10。
var?fr?=?new?FileReader();fr.readAsDataURL(file);
fr.onload?=?function?(event)?{var?data=?event.target.result;?//此處獲得的data是base64格式的數據 img.src?=?data;
ajax(url,{data}?,function(){})
}
上面獲得的data可以用來實現圖片上傳前的本地預覽,也可以用來發送base64數據給後端然後返回該數據塊對應的地址。
優點:?同第二種
缺點:壹次性發送大量的base64數據會導致瀏覽器卡頓,服務器端接收這樣的數據可能也會出現問題。