Skip to content

Streaming file uploads #14773

@Rich-Harris

Description

@Rich-Harris

Describe the problem

When you submit a form, and JS is available, we POST a lightly-seasoned FormData object to the endpoint. Whenever you post form data with fetch, it defaults to multipart encoding, which allows it to include files.

The problem is with what happens next: on the server, calling request.formData() causes the entire payload to be downloaded before we can do anything with it. If you're uploading large files, that's a problem.

it's especially bad if you call myform.validate(), since the file data will get uploaded even though it's not necessary for validation.

Describe the proposed solution

The solution proposed in #14477 (comment):

We create a custom binary encoding that puts the file manifest upfront, followed by the file data (unless we're just validating). data.myfile is still a File object, and so everything continues to work the same from the user's perspective, but data.myfile.stream() and await data.myfile.arrayBuffer() don't have the data immediately — it streams in as it's available.

Additionally, we could use XHR instead of fetch, and report file upload progress — something like this, perhaps:

{#each myform.uploads as upload}
  <p>uploading {upload.name}... {format(upload.sent)}/{format(upload.total)}</p>
  <progress value={upload.sent / upload.total}></progress>
{/each}

In the no-JS case, things would continue to work as they do today.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions