
在HTML表單中,可以上傳文件的唯一控件就是
<input type="file">
<body>
<input type="file">
</body>

出于安全考慮,瀏覽器只允許用戶點(diǎn)擊<input type="file">來選擇本地文件,用 JavaScript 對 <input type="file">的value賦值是沒有任何效果的
當(dāng)用戶選擇了上傳某個(gè)文件后,JavaScript也無法獲得該文件的真實(shí)路徑
不過JavaScript可以在提交表單時(shí)對文件擴(kuò)展名做檢查,以便防止用戶上傳無效格式的文件
var f = document.getElementById('file-upload');
var filename = f.value; // '/Users/mazy/Desktop/xxx.png'
if (!filename || !(filename.endsWith('.jpg') || filename.endsWith('.png') || filename.endsWith('.gif'))) {
alert('不是有效的圖片文件!');
return false;
}
File API
隨著HTML5的普及,新增的File API允許 JavaScript 讀取文件內(nèi)容,獲得更多的文件信息
HTML5的File API提供了File和FileReader兩個(gè)主要對象,可以獲得文件信息并讀取文件
設(shè)置內(nèi)容
<body>
<div id="file-info"></div>
<div id="image-preview"></div>
<form action=""><input id="image-file" type="file"></form>
</body>
設(shè)置樣式
<style>
#test-image-preview {
width:200px;
height:200px;
border:1px solid #ff0000;
}
</style>
設(shè)置 JavaScript 代碼
<head>
<script>
window.onload=function(){
var fileInput = document.getElementById('image-file');
var info = document.getElementById('file-info');
var preview = document.getElementById('image-preview');
fileInput.addEventListener('change',function(){
preview.style.backgroundImage='';
if (!fileInput.value){
info.innerHTML = '沒有選擇文件';
return ;
}
var file = fileInput.files[0];
info.innerHTML = '文件:' + file.name + '<br>'+'大小:'+file.size+'<br>'+'修改:'+file.lastModifiedDate;
if(file.type !== 'image/jpeg' && file.type !== 'image/png' && file.type !== 'image/gif'){
alert('不是有效的圖片文件!');
return;
}
var reader = new FileReader();
// 完成回調(diào)
reader.onload=function(e){
var data = e.target.result;
preview.style.backgroundImage='url('+ data +')';
};
// 異步調(diào)用
reader.readAsDataURL(file);
});
};
</script>
</head>
上面的代碼演示了如何通過HTML5的File API讀取文件內(nèi)容


回調(diào)
上面的代碼還演示了JavaScript的一個(gè)重要的特性就是單線程執(zhí)行模式。
在JavaScript中,瀏覽器的JavaScript執(zhí)行引擎在執(zhí)行JavaScript代碼時(shí),總是以單線程模式執(zhí)行,也就是說,任何時(shí)候,JavaScript代碼都不可能同時(shí)有多于1個(gè)線程在執(zhí)行。
但是,單線程模式執(zhí)行的JavaScript,如何處理多任務(wù)?
在JavaScript中,執(zhí)行多任務(wù)實(shí)際上都是異步調(diào)用,比如上面的代碼:
reader.readAsDataURL(file);
因?yàn)槭钱惒讲僮?,所以我們在JavaScript代碼中就不知道什么時(shí)候操作結(jié)束,因此需要先設(shè)置一個(gè)回調(diào)函數(shù):
reader.onload = function(e) {
// 當(dāng)文件讀取完成后,自動(dòng)調(diào)用此函數(shù):
};