HTML5中使用type=file的input上傳文件權威指南

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章