Today, we are kicking off the first post in a series all about uploading files to the web. In this post, we’ll start with the basics of using . The full series will look like this: HTML Uploading files with HTML Uploading files with JavaScript Receiving file uploads with Node.js (Nuxt.js) Optimizing storage costs with Object Storage Optimizing delivery with a CDN Securing file uploads with malware scans https://www.youtube.com/watch?v=s2TTck1sj4s&embedable=true Access Files The very first step is accessing a file to upload. Unfortunately, or rather, fortunately, browsers can’t access our file systems. If they did, it would be a major security concern. There is work being done on the , but it’s experimental and will be limited access, so let’s just pretend it doesn’t exist. File System Access API Accessing a file requires user interaction, which means we need something in the UI for the user to interact with. Conveniently, there is the attribute. input element with a file type <input type="file" /> On its own, a file input isn’t very useful. It allows a user to select a file from their device, but that’s about it. To actually send the file to a server, we need to make an , which means we need a . We’ll put the file input inside along with a to submit the form. HTTP request <form> <button> The input will also need a to make it for assistive technology, an attribute to associate it with the label, and a attribute in order to include its data along with the HTTP request. <label> accessible id name <form> <label for="file">File</label> <input id="file" type="file" /> <button>Upload</button> </form> Looks good 👍. Doesn’t work good, though 👎. Include a Request Body If we watch the as we submit the form, we can see that it generates a request, and the payload is sent as a that looks like this: “ “. It’s essentially a key-value pair, with the key being the input and the value being the name of the file. network tab GET query string ?name=filename.txt name This is sent as a string. Not quite what we’re going for here. We can’t actually send a file using a GET request because you can’t put a file in the query string parameters. We need to put the file in the . To do that, we need to send a request, which we can do by changing the form’s attribute to . body of the request POST method "post" <form method="post"> <label for="file">File</label> <input id="file" name="file" type="file" /> <button>Upload</button> </form> Now, if we explore that request, we can see that we are making a post request. We can also see that the request has a payload containing the form’s data. Unfortunately, the data is still just a key-value pair with the input and the filename. name Set the Content-Type We’re still not actually sending the file, and the reason has to do with the request “ “. Content-Type By default, when a form is submitted, the request is sent with a of . Content-Type application/x-www-form-urlencoded And unfortunately, we can’t send the binary file information as . URL-encoded data In order to send the file contents as , we have to change the of the request to . And in order to do that, we can set the form’s attribute. binary data Content-Type multipart/form-data enctype <form method="post" enctype="multipart/form-data"> <label for="file">File</label> <input id="file" name="file" type="file" /> <button>Upload</button> </form> Now, if we submit the form one more time, we can see the request uses the POST method and has the set to . In Chromium browsers, you’ll no longer see the request payload, but you can see it in the Firefox devtools under the request Params tab. Content-Type multipart/form-data We did it!!! Recap With all that in place, we can upload files using HTML. To re-iterate, sending files with HTML requires three things: Create an input with the of file to access the file system. type Use a form with to include a body on the request. method="post" Set the request’s to using the attribute. Content-Type multipart/form-data enctype I hope you learned something new today, and you come back for the rest of the series. In the rest of the series, we’ll cover things like uploading files with JavaScript, receiving files on the backend, optimizing resources and costs with Object Storage, security concerns for uploads, and delivery improvements. Once again, here’s what the series outline will look like: Uploading files with HTML Uploading files with JavaScript Receiving file uploads with Node.js (Nuxt.js) Optimizing storage costs with Object Storage Optimizing delivery with a CDN Securing file uploads with malware scans Thank you so much for reading. If you liked this article, please . It's one of the best ways to support me. You can also or if you want to know when new articles are published. share it , sign up for my newsletter follow me on Twitter Also published . here