Question

Restrict File Types with HTML File Input accept Attribute

htmlfiletypes

Question

How can I restrict which file formats a user can select in the native operating system file chooser opened by an HTML <input type="file"> element? I would like to use only HTML and JavaScript, without browser plugins such as Flash.

Short Answer

You will learn how the HTML accept attribute filters the file chooser, how to use file extensions and MIME types, and why client-side filtering is only a convenience rather than upload security. You will also see how to validate a selected file with JavaScript and why a server must still perform final validation.

Concept

The main HTML feature for suggesting allowed upload formats is the accept attribute on a file input.

<input type="file" accept=".png,.jpg,.jpeg">

When the user opens the browser's native file chooser, the browser passes this preference to the operating system. The chooser will usually show matching files first or limit its visible file filter to those formats.

However, accept is not a strict security restriction:

  • Browser and operating system behavior varies.
  • Many file choosers let users switch to an option such as All files.
  • A user can rename a file to give it a different extension.
  • A malicious user can bypass browser checks completely by sending a custom HTTP request.

Therefore, use accept to improve the user experience, use JavaScript to give immediate feedback, and validate files again on the server before storing or processing them. HTML and JavaScript alone cannot securely enforce an upload policy because the user controls the browser.

Mental Model

Think of accept as a sign at the entrance to a filing cabinet saying, “Please put image files here.” The sign helps a cooperative person find the right documents, but it is not a lock.

JavaScript is like a receptionist who checks the label when a document is handed over and can ask the person to choose another one. Server-side validation is the locked records room: it must inspect the document before accepting it, because it is the only part the user cannot alter.

Take Quiz

Syntax and Examples

Use accept with one or more comma-separated file type specifiers.

Accept specific extensions

<label for="photo">Choose a photo:</label>
<input id="photo" name="photo" type="file" accept=".png,.jpg,.jpeg">

This asks the chooser to show PNG and JPEG files.

Accept MIME types

<input type="file" accept="image/png,image/jpeg">

MIME types describe the content category and format. Common examples include image/png, application/pdf, and text/csv.

Accept every type in a category

<input type="file" accept="image/*">

image/* requests any image type supported by the browser and operating system. Use explicit types when your application supports only particular formats.

Allow multiple files

<input type="file" accept=".pdf,.docx" multiple>

The multiple attribute changes the number of files a user may select; it does not change how accept works.

Add JavaScript feedback

<input id="resume" type="file" accept="application/pdf,.pdf">
<p id="message" role="alert"></p>

<script>
  const input = document.querySelector("#resume");
  const message = document.querySelector("#message");

  input.addEventListener("change", () => {
    const file = input.files[0];

    if (!file) {
      message.textContent = "";
      return;
    }

    const isPdf = file.type === "application/pdf" ||
      file.name.toLowerCase().endsWith(".pdf");

    if (!isPdf) {
      message.textContent = "Please choose a PDF file.";
      input.value = "";
      return;
    }

    message.textContent = `Selected: ${file.name}`;
  });
</script>

input.files is a FileList containing the selected files. For a single-file input, the first selected file is input.files[0]. The example checks both the MIME type and extension because file.type can be empty or unreliable on some systems.

Step by Step Execution

Consider this example:

<input id="avatar" type="file" accept="image/png,image/jpeg">
<p id="status"></p>

<script>
  const avatar = document.querySelector("#avatar");
  const status = document.querySelector("#status");

  avatar.addEventListener("change", () => {
    const file = avatar.files[0];

    if (!file) {
      status.textContent = "No file selected.";
      return;
    }

    if (file.type !== "image/png" && file.type !== "image/jpeg") {
      status.textContent = "Choose a PNG or JPEG image.";
      avatar.value = "";
      return;
    }

    status.textContent = `${file.name} is ready to upload.`;
  });
</script>

Execution when a user selects cat.png:

  1. The user clicks the input. The accept value tells the chooser to prefer PNG and JPEG files.
  2. The user selects cat.png and closes the chooser.
  3. The input fires its change event.
  4. avatar.files[0] stores a File object representing cat.png.
  5. The first if is skipped because a file exists.
  6. The second if is skipped because its MIME type is image/png.
  7. The success message is displayed.

If the user selects a file reported as application/pdf, the second condition is true. The script displays an error and sets avatar.value to an empty string, which clears the selection.

Real World Use Cases

  • Profile photo upload: Suggest JPEG, PNG, or WebP files with accept="image/jpeg,image/png,image/webp".
  • Resume submission: Ask applicants for a PDF using accept="application/pdf,.pdf".
  • Data import tool: Guide users toward CSV files with accept=".csv,text/csv".
  • Document portal: Allow approved office formats such as PDF and DOCX.
  • Media dashboard: Let content editors select audio or video formats supported by the application.

In each case, the chooser filter reduces accidental selection of unsupported files. The upload endpoint must still reject invalid, oversized, or unsafe files.

Take Quiz

Real Codebase Usage

In real applications, developers usually combine three layers.

  1. Chooser guidance: Add accept to make the normal path easy for users.
  2. Client-side validation: Check selected files before uploading so the UI can show immediate, friendly errors.
  3. Server-side validation: Enforce the actual policy before saving or processing data.

A reusable client-side validation function often checks both type and size:

function validateImage(file) {
  const allowedTypes = new Set(["image/jpeg", "image/png"]);
  const maximumBytes = 5 * 1024 * 1024;

  if (!allowedTypes.has(file.type)) {
    return "Choose a JPEG or PNG image.";
  }

  if (file.size > maximumBytes) {
    return "The image must be 5 MB or smaller.";
  }

  return null;
}

A change handler can use a guard clause to stop as soon as a file is invalid:

const error = validateImage(file);
if (error) {
  showError(error);
  return;
}

uploadFile(file);

On the server, robust validation commonly includes a file-size limit, an allowlist of supported formats, inspection of file signatures or decoded content when appropriate, safe generated filenames, and storage outside publicly executable directories.

Common Mistakes

Treating accept as security

<input type="file" accept=".pdf">

This does not guarantee that only PDFs reach your server. It is a browser hint. Always validate uploads on the server.

Using only a filename extension in JavaScript

// Not enough by itself
if (file.name.endsWith(".png")) {
  uploadFile(file);
}

A filename can be changed easily, such as renaming program.exe to photo.png. An extension check can improve feedback, but it cannot prove file content is safe or valid.

Trusting file.type completely

if (file.type === "image/png") {
  uploadFile(file);
}

file.type is useful for UI validation, but it may be empty or based on operating-system file associations. Do not use it as your only security check.

Forgetting that the user can cancel

const file = input.files[0];
console.log(file.name); // Can fail if no file exists

Check that file exists before accessing its properties.

const file = input.files[0];
if (!file) return;
console.log(file.name);

Assuming every chooser enforces the filter identically

Different browsers and operating systems present file filters differently. Design your form so it remains understandable even if a user selects an unsupported file.

Using a nonstandard attribute

Attributes such as filetype, extensions, or filter are not standard HTML file-input restrictions. Use the standard accept attribute.

Comparisons

TechniqueWhere it runsWhat it doesSecurity value
accept attributeBrowser file chooserSuggests or filters selectable file formatsNone by itself
JavaScript validationBrowser after selectionGives immediate feedback and can prevent normal UI submissionEasily bypassed
Server-side validationServer upload endpointEnforces allowed type, size, and processing rulesRequired
Extension checkBrowser or serverChecks the filename suffix, such as .pdfWeak; names can be changed
MIME type checkBrowser or serverChecks a declared or detected media typeUseful, but should be verified server-side

Explicit formats vs wildcard formats

ValueBest forExample
Explicit extensionsA small known set of file names.jpg,.jpeg,.png
Explicit MIME typesA small known set of media formatsimage/jpeg,image/png
Category wildcardAny format in a broad categoryimage/*

Prefer explicit formats when your application can process only specific formats.

Take Quiz

Cheat Sheet

<!-- One extension -->
<input type="file" accept=".pdf">

<!-- Several extensions -->
<input type="file" accept=".png,.jpg,.jpeg">

<!-- MIME types -->
<input type="file" accept="image/png,image/jpeg">

<!-- Broad category -->
<input type="file" accept="image/*">

<!-- More than one file -->
<input type="file" accept=".csv,text/csv" multiple>
  • Separate accepted values with commas.
  • Use extensions, MIME types, or a category wildcard such as image/*.
  • Read selected files from input.files.
  • For one file, use input.files[0] after checking it exists.
  • Use JavaScript for fast user feedback.
  • accept and JavaScript validation can be bypassed.
  • Enforce type, size, and safety rules on the server.

FAQ

Can HTML completely prevent users from choosing another file type?

No. The accept attribute asks the browser and operating system to filter or suggest files, but users may be able to choose an all-files option or bypass the page entirely.

What is the correct attribute for restricting a file input?

Use accept, for example: <input type="file" accept=".pdf">.

Should I use file extensions or MIME types in accept?

You can use either, and including both is often practical. For example: accept="application/pdf,.pdf".

Does accept="image/*" allow every image format?

It requests image formats recognized by the browser and operating system. It does not guarantee that your application or server can process every possible image format.

Can JavaScript determine the real file type securely?

Not securely enough to protect an upload endpoint. JavaScript checks are helpful for user experience, but the server must validate the uploaded bytes and enforce its policy.

How do I clear an invalid file selection in JavaScript?

Assign an empty string to the input value:

input.value = "";

Why is file.type empty for some files?

The browser may not know a MIME type for the file, or the operating system may not provide one. Handle an empty type as untrusted or unsupported in client-side validation.

Does multiple restrict file formats?

No. multiple only permits selecting more than one file. Combine it with accept when needed.

Take Quiz

Mini Project

Description

Build a small image-upload picker for a profile settings page. It guides users toward PNG or JPEG images, checks the selected file in the browser, and displays either a helpful error or a success message. This mirrors the client-side portion of a real upload form.

Goal

Create a file input that accepts JPEG and PNG images up to 2 MB and reports whether the chosen file is ready for upload.

Requirements

Use an <input type="file"> with an accept attribute for PNG and JPEG files. Add a message area that reports validation results. Reject files that are not PNG or JPEG images. Reject files larger than 2 MB. Clear the file input when validation fails.

Take Quiz

Keep learning

Related questions

View more