<input type="file"> lets the user choose files from their device. JavaScript can read information about the chosen files, and, with their permission, read their content in the browser. Nothing is uploaded until you send it.
<input id="file" type="file" accept="image/*">
<p id="info"></p>
<img id="preview" alt="Preview of the chosen image" style="max-width:160px;display:none">
<script>
const input = document.querySelector("#file");
input.addEventListener("change", () => {
const file = input.files[0];
if (!file) return;
document.querySelector("#info").textContent =
`${file.name} (${file.type || "unknown type"}, ${(file.size / 1024).toFixed(1)} KB)`;
if (file.type.startsWith("image/")) {
const preview = document.querySelector("#preview");
preview.src = URL.createObjectURL(file);
preview.style.display = "block";
preview.onload = () => URL.revokeObjectURL(preview.src); // free the memory
}
});
</script>
Choose an image to see its details and a preview.
The files list
input.files is a FileList. Each File has:
| Property | Meaning |
|---|---|
name | file name, such as photo.png |
size | size in bytes |
type | MIME type, such as image/png (may be empty) |
lastModified | timestamp |
For several files, add the multiple attribute and loop over input.files.
Limiting what can be chosen
accept=".pdf,image/*"filters the file picker, but it is only a hint. Users can bypass it.- Check size and type in JavaScript before uploading:
const MAX = 2 * 1024 * 1024; // 2 MB
if (file.size > MAX) {
showError("Please choose a file under 2 MB.");
input.value = ""; // clear the selection
}
Reading the content
const text = await file.text(); // text files
const buffer = await file.arrayBuffer(); // raw bytes
For previews of images, URL.createObjectURL(file) (above) is quick and does not read the whole file into memory.
Uploading
const formData = new FormData();
formData.append("avatar", file);
await fetch("/upload", { method: "POST", body: formData });
Do not set the Content-Type header yourself. See FormData.
Drag and drop
A drop zone can read dropped files from event.dataTransfer.files, and must call preventDefault() on dragover and drop.
Client checks are not security
.exe to .png, so file type and size checks in the browser only improve the experience. The server must verify uploaded files again.