HTML5中使用type=file的input上傳文件權威指南
一 、入門
下面是大家非常熟悉的html5的文件上傳代碼,可不保證每個人都真的理解背後的知識點。
<input type="file" id="input">
當我們點擊file標籤的時候一定會彈出文件選擇的界面,當我們選擇一個圖片或者文件時,瀏覽器dom中會產生一個fileList對象。
通過DOM API我們可以訪問到這個file對象的數組列表。
二 FileList中的file對象
File 對象提供了三個屬性,包含了文件的有用信息。
- name 文件名稱,只讀字符串。只包含文件名,不包含任何路徑信息。
- size 文件大小,按字節數(bytes)計算,只讀的64位整數。
- type 文件的MIME類型,只讀字符串,當類型不能確定時爲""。
通過dom api獲取fileList
const selectedFile = document.getElementById('input').files[0];
選擇1個文件的時候,可以獲取數組的第一個元素。
通過onchange事件訪問fileList
<input type="file" id="input" multiple onchange="handleFiles(this.files)">
注:如果你想讓用戶選擇多個文件,只需在input元素上使用multiple屬性。
動態監聽change事件獲取fileList(推薦,常用)
const inputElement = document.getElementById("input");
inputElement.addEventListener("change", handleFiles, false);
function handleFiles() {
const fileList = this.files; /* now you can work with the file list */
}
三 input的click事件(和change事件區別)
上面提到了change事件,觸發的場景就是fileList對象內容的改變。這種改變是彈出文件選擇框,並選擇了文件改變後才觸發。而觸發彈出文件選擇框的事件是click事件。掌握這一點,可以幫我們優雅的解決業務問題。
使用圖片代替原本醜陋的input按鈕
方式1:使用一個image標籤和input絕對定位,保持兩者大小一致重疊。這樣點擊圖片時,就可以觸發input的彈出選擇文件窗口。這種方式網上很流行,其實是初學者無奈之舉,不好控制。
方式2: 推薦
# H5中隱藏按鈕,無需做其他事情
<input type="file" id="fileElem" multiple accept="image/*" style="display:none" onchange="handleFiles(this.files)">
<button id="fileSelect">Select some files</button>
# 頂一個可見的button,點擊button的時候觸發input的click事件
const fileSelect = document.getElementById("fileSelect"),
fileElem = document.getElementById("fileElem");
fileSelect.addEventListener("click", function (e) {
if (fileElem) {
fileElem.click();
}
}, false);
四,如何展示圖片
只有兩種方式,圖片的url或者base64,具體可以參考我的另外一篇博客。
通過圖片的URL顯示縮略圖(重要)
function handleFiles(files) {
# 獲取每一個圖片對象
for (var i = 0; i < files.length; i++) {
var file = files[i];
var imageType = /^image\//;
if (!imageType.test(file.type)) {
continue;
}
# 在dom上創建一個image標籤,並且掛載到priview的div內部。
var img = document.createElement("img");
img.file = file;
preview.appendChild(img); // 假設"preview"就是用來顯示內容的div
# 重點,讀取圖片的file(blog)對象,並且將返回的url設定到img的src屬性中
var reader = new FileReader();
reader.onload = (function(aImg) { return function(e) { aImg.src = e.target.result; }; })(img);
reader.readAsDataURL(file);
}
}
最後一步再解釋一下,FileReader是一個異步讀取圖片的函數,和讀普通文件沒區別,讀取結束後會觸發onload事件。
reader.readAsDataURL(file);開始執行,onload後面其實是後面才執行。
五 如何上傳圖片
假設已經獲取到了圖片的file對象,這是可以通過多種方式上傳給後端。這裏展示的ajax的方式。還有很多其他方法,我們需要理解一點
注:如果後端想獲取到文件,並轉存上傳的需要是file對象。而不是url,url很可能本地的,上傳給後端是無法讀取的。
<script type="text/javascript">
function FileUpload(blog) {
var formdata = new FormData($("#contact-form")[0]);
formdata.append("brokerId", brokerId);
formdata.append("age", age);
if (blog != "") {
formdata.set("file", blog, blog.name);
}
$.ajax({
type: "POST",
url: prefix + "customers/add",
data: formdata,
processData: false,
contentType: false,
dataType: "json",
success: function(data) {
if (data.code == 0) {
console.log("添加成功" + data.code);
$(window).attr('location', 'mycustomers.html');
} else {
alert("添加客戶遇到錯誤!")
}
},
error: function(data) {
alert("添加客戶遇到網絡錯誤!")
console.log(data);
}
});
}
</script>
待續
還有幾點,今天沒時間,可以順帶提一下。
url是一個字符串,但是可以通過字符串找到圖片的位置,url必須指向一個對象。
base64其實是文件對象的另外一種存儲形式,這種形式可以用來在網絡中傳播。img的src也可以讀取base64格式的數據,直接顯示爲圖像。
如果你src指向的是base64,無論是否聯網你都能顯示圖片,因爲base64就代表了圖片本身。
參考:
文章來源於此,很多內容沒有介紹,個人也做了補充
https://developer.mozilla.org/zh-CN/docs/Web/API/File/Using_files_from_web_applications