Movatterモバイル変換


[0]ホーム

URL:


Skip to content
DEV Community
Log in Create account

DEV Community

Cover image for Uploading Multiple Files with Fetch
Raymond Camden
Raymond Camden

Posted on • Originally published atraymondcamden.com on

     

Uploading Multiple Files with Fetch

This afternoon I was going through my "blog ideas" list and cleaning up entries I've changed my mind on. I came across something I added many months ago - using theFetch API to upload multiple files at once. The reason it's stuck in my "todo" pile for so long is that I wasn't aware of a good service I could use to post my files against. I've done it before in Node.js and I know it's something I could do locally in an hour, but honestly I just didn't want to. That probably sounds a bit lazy but it's honest. Today though I came acrosshttpbin.org, an online service that lets you hit it with various types of HTTP methods and even supports file uploads. (Obviously it doesn't make those files available, it just reports back on the upload.) Even better, it supports CORS which means I could use CodePen. So with no more excuses at my disposal, today I finally built a simple demo.

First off, I created a simple form:

<form><inputid="filesToUpload"type="file"multiple><buttonid="testUpload">Test Upload</button></form><divid="status"></div>
Enter fullscreen modeExit fullscreen mode

I've got a file field, a button, and an empty div. Notice the file field uses themultiple attribute. This lets the end user select one or more files. For my first iteration, I used the following #"http://www.w3.org/2000/svg" width="20px" height="20px" viewbox="0 0 24 24">Enter fullscreen modeExit fullscreen mode

From top to bottom - I begin by usingquerySelector to cache access to my file field and empty div. Then I add a click handler to the button.

The click handler first checks to see if any files were selected. If none were then we print out a message and leave. Otherwise, we then iterate over thefiles array and call an async function,uploadFile. In my demo,uploadFile does aPOST to httpbin and returns the result. Right now I'm ignoring the result but in a real application you would probably need something from there. At the end of each upload I update my div with a status.

Finally I report that everything is complete and reset the file field. Here's a CodePen for you to try it out yourself:

This works well, but uploads the files one after the other. It would be nicer if they were all uploaded at once, right? Here's an updated version that does that:

document.addEventListener('DOMContentLoaded',init,false);letfileField,statusDiv;asyncfunctioninit(){fileField=document.querySelector('#filesToUpload');statusDiv=document.querySelector('#status');document.querySelector('#testUpload').addEventListener('click',doUpload,false);}asyncfunctiondoUpload(e){e.preventDefault();statusDiv.innerHTML='';lettotalFilesToUpload=fileField.files.length;//nothing was selectedif(totalFilesToUpload===0){statusDiv.innerHTML='Please select one or more files.';return;}statusDiv.innerHTML=`Uploading${totalFilesToUpload} files.`;letuploads=[];for(leti=0;i<totalFilesToUpload;i++){uploads.push(uploadFile(fileField.files[i]));}awaitPromise.all(uploads);statusDiv.innerHTML='All complete.';fileField.value='';}asyncfunctionuploadFile(f){console.log(`Starting with${f.name}`);letform=newFormData();form.append('file',f);letresp=awaitfetch('https://httpbin.org/post',{method:'POST',body:form});letdata=awaitresp.json();console.log(`Done with${f.name}`);returndata;}
Enter fullscreen modeExit fullscreen mode

The main difference is tht now I don'tawait the call touploadFile and use the implied Promise returned instead. I can then usePromise.all on the array of uploads to notice when they are all done. One thing I don't have is the nice "X of Y" message, and that's possibly something I could do too, but for now the improved speed should be nice. If you want to test this version, it's below.

Enjoy, let me know what you think!

Top comments(0)

Subscribe
pic
Create template

Templates let you quickly answer FAQs or store snippets for re-use.

Dismiss

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment'spermalink.

For further actions, you may consider blocking this person and/orreporting abuse

Raymond Camden
Raymond Camden is a experienced developer advocate and evangelist. His work focuses on APIs, the web platform, and generative AI. He is the author of multiple books on development and has been activel
  • Location
    Louisiana
  • Work
    API Evangelist at Foxit
  • Joined

More fromRaymond Camden

Using Intl.DurationFormat for Localized Durations
#javascript
Integrating Eleventy with GitHub Flat Data
#eleventy#javascript#staticsites
Graphing Movie Rating Distribution For No Good Reason
#javascript#movies
DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Log in Create account

[8]ページ先頭

©2009-2025 Movatter.jp