npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

formdata-polyfill

v4.0.10

Published

HTML5 `FormData` for Browsers and Node.

Downloads

16,896,296

Readme

A FormData polyfill for the browser ...and a module for NodeJS (New!)

npm install formdata-polyfill

The browser polyfill will likely have done its part already, and i hope you stop supporting old browsers c",) But NodeJS still laks a proper FormDataThe good old form-data package is a very old and isn't spec compatible and dose some abnormal stuff to construct and read FormData instances that other http libraries are not happy about when it comes to follow the spec.

The NodeJS / ESM version

  • The modular (~2.3 KiB minified uncompressed) version of this package is independent of any browser stuff and don't patch anything
  • It's as pure/spec compatible as it possible gets the test are run by WPT.
  • It's compatible with node-fetch.
  • It have higher platform dependencies as it uses classes, symbols, ESM & private fields
  • Only dependency it has is fetch-blob
// Node example
import fetch from 'node-fetch'
import File from 'fetch-blob/file.js'
import { fileFromSync } from 'fetch-blob/from.js'
import { FormData } from 'formdata-polyfill/esm.min.js'

const file = fileFromSync('./README.md')
const fd = new FormData()

fd.append('file-upload', new File(['abc'], 'hello-world.txt'))
fd.append('file-upload', file)

// it's also possible to append file/blob look-a-like items
// if you have streams coming from other destinations
fd.append('file-upload', {
  size: 123,
  type: '',
  name: 'cat-video.mp4',
  stream() { return stream },
  [Symbol.toStringTag]: 'File'
})

fetch('https://httpbin.org/post', { method: 'POST', body: fd })

It also comes with way to convert FormData into Blobs - it's not something that every developer should have to deal with. It's mainly for node-fetch and other http library to ease the process of serializing a FormData into a blob and just wish to deal with Blobs instead (Both Deno and Undici adapted a version of this formDataToBlob to the core and passes all WPT tests run by the browser itself)

import { Readable } from 'node:stream'
import { FormData, formDataToBlob } from 'formdata-polyfill/esm.min.js'

const blob = formDataToBlob(new FormData())
fetch('https://httpbin.org/post', { method: 'POST', body: blob })

// node built in http and other similar http library have to do:
const stream = Readable.from(blob.stream())
const req = http.request('http://httpbin.org/post', {
  method: 'post',
  headers: {
    'Content-Length': blob.size,
    'Content-Type': blob.type
  }
})
stream.pipe(req)

PS: blob & file that are appended to the FormData will not be read until any of the serialized blob read-methods gets called ...so uploading very large files is no biggie

Browser polyfill

usage:

import 'formdata-polyfill' // that's it

The browser polyfill conditionally replaces the native implementation rather than fixing the missing functions, since otherwise there is no way to get or delete existing values in the FormData object. Therefore this also patches XMLHttpRequest.prototype.send and fetch to send the FormData as a blob, and navigator.sendBeacon to send native FormData.

I was unable to patch the Response/Request constructor so if you are constructing them with FormData then you need to call fd._blob() manually.

new Request(url, {
  method: 'post',
  body: fd._blob ? fd._blob() : fd
})

Dependencies

If you need to support IE <= 9 then I recommend you to include eligrey's blob.js (which i hope you don't - since IE is now dead)

Previously you had to import the polyfill and use that, since it didn't replace the global (existing) FormData implementation. But now it transparently calls _blob() for you when you are sending something with fetch or XHR, by way of monkey-patching the XMLHttpRequest.prototype.send and fetch functions.

So you maybe had something like this:

var FormData = require('formdata-polyfill')
var fd = new FormData(form)
xhr.send(fd._blob())

There is no longer anything exported from the module (though you of course still need to import it to install the polyfill), so you can now use the FormData object as normal:

require('formdata-polyfill')
var fd = new FormData(form)
xhr.send(fd)

Native Browser compatibility (as of 2021-05-08)

Based on this you can decide for yourself if you need this polyfill.

screenshot

This normalizes support for the FormData API:

  • append with filename
  • delete(), get(), getAll(), has(), set()
  • entries(), keys(), values(), and support for for...of
  • Available in web workers (just include the polyfill)