File API
Chapter 4 ended with dragged files landing in dataTransfer.files as a FileList — the exact same type a regular <input type="file"> (Intermediate Chapter 1) produces. This chapter covers what you can actually do with that File object once you have it, entirely in the browser, with no server round-trip required at all.
Getting Files from an Input
accept attribute only filters the OS file picker dialog's default view — most file pickers still let a user manually choose "All Files" and pick anything regardless. Always re-check file.type in JavaScript (and validate the actual file content server-side, never trust the client-reported type alone) rather than relying on accept as genuine validation.
FileReader — Reading the Actual Content
A File object alone only gives metadata — FileReader actually reads the bytes, asynchronously, in one of several formats depending on what's needed.
| Method | Reads the file as |
|---|---|
| readAsDataURL() | A base64 data URL — directly usable as an <img> src, for instant previews |
| readAsText() | Plain text — for .txt, .csv, .json files |
| readAsArrayBuffer() | Raw binary data — for processing binary formats directly |
A Real Example — Instant Image Preview Before Upload
This is exactly the pattern behind every "see a preview before you upload" experience — the user picks a file, sees it rendered instantly, and nothing has been sent to a server at all yet. The actual upload (if any) happens separately, typically via the FormData covered in Intermediate Chapter 10.
Reading Text Files — Client-Side CSV/JSON Preview
Drag-and-Drop + File API — Tying Chapters 4 and 5 Together
Because a dragged file and a file selected via <input type="file"> both produce identical File objects, the exact same FileReader code handles both without any special-casing — a genuinely clean piece of API design that pays off whenever both interaction methods are offered together.
Chapter 5 Quick Reference
- input.files — a FileList, even for a single file; access individual files by index
- accept attribute doesn't enforce anything — just filters the picker's default view; always re-check file.type in JS
- FileReader.readAsDataURL() — base64 data URL, directly usable as an img src for instant previews
- readAsText() / readAsArrayBuffer() — for text content and raw binary data respectively
- reader.onload fires asynchronously once reading completes; result available as reader.result
- Drag-and-drop files and input-selected files produce identical File objects — the same FileReader code handles both
- Client-side reading is UX only — server-side validation of every uploaded file remains essential regardless
- Next chapter: Web Storage & offline — localStorage/IndexedDB, service workers intro