HTML form enctype: check the submit button before changing the upload handler

For a native HTML form submission using POST, enctype selects the request encoding. Use multipart/form-data when sending file contents. Check the activated submit button too: its formenctype can override the form's setting. If JavaScript intercepts submission and calls fetch, the body passed to fetch determines that request's encoding instead. Form reference · Submit button overrides

A maintenance claim lets a technician save a text draft or submit a claim with a photograph. Both buttons belong to one form, but their native submissions use different encodings. A later JavaScript rewrite can accidentally make them identical by treating new FormData(form) as a complete replacement for the native submit process.

Read the form and the activated button together

This illustrative form uses separate server routes. The draft route accepts ordinary encoded fields; the final route expects multipart data:

<form id="claim" action="/claims/draft" method="post"
      enctype="application/x-www-form-urlencoded">
  <label for="asset">Asset reference</label>
  <input id="asset" name="asset" required>

  <label for="evidence">Photograph for the final claim</label>
  <input id="evidence" name="evidence" type="file"
         accept="image/*">

  <button type="submit" name="operation" value="draft">
    Save text draft
  </button>
  <button type="submit" name="operation" value="submit"
          formaction="/claims/submit"
          formenctype="multipart/form-data">
    Submit with photograph
  </button>
</form>

With native submission, the first button uses the form's action and encoding. The second overrides both. Saving a text draft through URL encoding does not transfer the photograph's file bytes; the user would need to select a photograph again for a later submission after navigation. If drafts must retain attachments, design a file-storage path for drafts too.

The two endpoints here are examples to implement in your application. Adding these attributes does not create either server route or guarantee that a submitted claim was accepted.

Keep the three encoding choices tied to the receiver

application/x-www-form-urlencoded is the default. It represents names and values as encoded pairs. multipart/form-data carries separate parts and can include file bytes. text/plain is a debugging format; use a defined request format for production form parsing instead.

Changing enctype does not change the HTTP method. A GET form sends its data in the URL and is not a route for transferring file bytes. Confirm method, action, encoding, and server parser as one request contract. The HTML form submission guide explains the underlying submission event and control collection.

For the claim form, compare the request created by each button in the browser's Network panel. Inspect the destination and Content-Type, then check whether the final request contains an actual file part. Seeing a filename among text fields is not proof that the image bytes reached the server.

An intercepted fetch does not inherit the button's encoding

Consider this handler added to the same form:

const form = document.querySelector('#claim');
form.addEventListener('submit', async (event) => {
  event.preventDefault();
  const body = new FormData(form, event.submitter);
  const response = await fetch(form.action, {
    method: 'POST',
    body
  });
  console.log(response.status);
});

It always reads form.action and always sends a FormData body. It does not honor the final button's formaction, and the browser generates multipart encoding for that body regardless of the form's URL-encoded setting. Including the submitter in FormData includes its named value; it does not apply all of that button's submission overrides to fetch.

Choose a deliberate implementation. You can preserve native submission and its overrides, or have the handler explicitly select the destination and body format for each operation. In the second case, document how attachments are handled for drafts and final claims. Do not convert a file-bearing FormData into URLSearchParams and expect the file bytes to survive.

When sending FormData through fetch, let the browser supply the Content-Type and multipart boundary. The FormData guide covers this object and its repeated-field behavior. That boundary advice concerns constructing the multipart request; it does not resolve which operation or endpoint the handler selected.

Before calling the rewrite finished, save a draft and submit a final claim through the actual application. Check the recorded operation, receiving route, parsed fields, and stored photograph separately. Report success only after the server accepts the intended result, rather than when the browser starts a request.

Keep reading