[WebAPIs] 檔案上傳 Input File, File Upload, and FileList
keywords: file upload
, FileList
, FileAPI
- FileList @ MDN WebAPIs
- File @ MDN
- Input File @ MDN
- File 物件, FileList 物件,FileReader 物件 @ 阮一峰
關聯文章:
- TypedArray, ArrayBuffer, DataView
- Blob 和 FileReader
🔖 File 物件 (透過 <input type="file" />
)是一種特殊形式的 Blob
,並且在任何 Blob 可以使用的脈絡下都可以使用,它繼承了 Blob Class 的所有屬性和方法;和 Blob
不同之處在於,File Object
有實際參照到檔案系統中的檔案。
HTML Input File
使用 <input type="file" />
取得使用者想要上傳的檔案:
multiple
屬性可以一次上傳多個檔案accept
屬性可以限制上傳檔案的類型
<input
type="file"
id="file-uploader"
data-target="file-uploader"
accept="image/*"
multiple="multiple"
/>
⚠️ 基於安全性的理由,瀏覽器並不允許使用程式的方式指定
<input type="file">
的value
,必須要是使用者自行透過瀏覽器對話框選擇的檔案。
限制可上傳的檔案類型 Accept Attribute
accept="image/png" accept=".png" accept="image/png, image/jpeg" accept=".png, .jpg, .jpeg"
accept="image/*"
accept=".doc,.docx,.xml,application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document"
取得上傳檔案的基本資訊(FileList)
FileList @ MDN WebAPIs
File 物件 (透過 <input type="file" />
)是一種特殊形式的 Blob
,並且在任何 Blob 可以使用的脈絡下都可以使用,它繼承了 Blob class 的所有屬性和方法;和 Blob
不同之處在於,File Object
有實際參照到檔案系統中的檔案。具體來說,FileReader
、URL.createObjectURL()
、createImageBitmap()
、和XMLHttpRequest.send()
可以同時接受 File 和 Blob 。
在 Web 中仍無法直接建立 File 物件,但可以透過使用者從 <input>
元素中選擇的檔 案於 FileList 物件中取得,或使用者透過拖曳的方式得到的 DataTransfer 物件。
當使用者透過 <input type="file" />
的對話框選擇檔案後,透過監聽 change
事件中的 e.target.files
可以取得 FileList 物件,FileList 物件是一種 TypedArray ,裡面含有 File 物件,而 File 物件是一個特殊的 Blob 物件:
const fileUploader = document.querySelector('#file-uploader');
fileUploader.addEventListener('change', (e) => {
e.target.files; // FileList object
e.target.files[0]; // File Object (Special Blob)
});
❗
e.target.files
會是一個 Typed Array,裡面可以取得使用者所有想要上傳的檔案,陣列裡都是該檔案的 File 物件,是一種特殊的 Blob 物件,而不是一般的物件。
因為這裡只有上傳一個檔案,所以使用 e.target.files[0]
即可取得使用者想要上傳的檔案。這的 File Object 是一個 Blob 物件而不是一般的物件,但從中可以透過 name
, size
, type
, lastModifiedDate
取得該檔案的資訊。
File Object
File @ MDN
// <input id="fileItem" type="file">
const file = document.getElementById('fileItem').files[0];
file instanceof File; // true
// new File(bits, name [, options])
// - bits 是二進位元串(ArrayBuffer, ArrayBufferView, Blob, DOMString object),以 UTF-8
// - name 檔案名稱或檔案路徑
// - options { type: 'MIME_TYPE', lastModified: Date.now }
var file = new File(['foo'], 'foo.txt', {
type: 'text/plain',
});
// 可以用的屬性包含
file.name; // 檔案名稱
file.type; // 檔案 MIME Type
file.size; // 檔案大小(單位是位元組 byte)
file.lastModified; // 最後修改時間
瀏覽器也有提供原生的 File API,File 物件用來表示一個檔案,可以用它來讀取檔案訊息,它繼承自 Blob 物件,算是一種特殊的 Blob,所以和 Blob 有關的方法均可以使用在 File 物件上。
FileList Object
// <input id="fileItem" type="file" multiple>
const files = document.getElementById('fileItem').files;
files instanceof FileList; // true
files.length; // 檔案數目
透過 AJAX 上傳檔案
FormData
keywords: FormData()
透過下面的方式,可以將欲上傳的檔案 append 到 FormData()
上:
let form = new FormData();
form.append("product[photos][]", e.target.files[i], optional<'filename'>)