FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

Zahgon/unfetch: 🐕 Bare minimum 500b fetch polyfill. · GitHub

Repository navigation

Public
forked from developit/unfetch

About

🐕 Bare minimum 500b fetch polyfill.

Resources

Stars

0 stars

Watchers

1 watching

Forks

 
 

Latest commit

 

History

230 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

unfetch-go

A Go port of unfetch — Jason Miller's tiny fetch polyfill.

The original is 500 bytes of JavaScript that implements just enough of the Fetch API to cover the common cases, on top of XMLHttpRequest. This port keeps that scope exactly: it does not grow the API, and it reproduces the original's behavior including the parts that are arguably bugs.

Install

go get github.com/developit/unfetch-go

Usage

res, err := unfetch.Fetch("/foo", nil)
if err != nil {
    return err // transport failure only, never an HTTP error status
}

var data map[string]any
if err := res.JSON(&data); err != nil {
    return err
}

POST with headers and a body:

res, err := unfetch.Fetch("/foo", &unfetch.RequestInit{
    Method:  "post",
    Headers: []unfetch.Header{{Name: "Content-Type", Value: "application/json"}},
    Body:    []byte(`{"a": "b"}`),
})

Send cookies, the equivalent of credentials: 'include':

res, err := unfetch.Fetch("/foo", &unfetch.RequestInit{
    Credentials: "include",
})

API

func Fetch(url string, opts *RequestInit) (*Response, error)

Performs the request and blocks until it completes. A nil opts is equivalent to {} in JavaScript.

FetchAsync returns a *Promise instead, for code that wants the original's .then() / .catch() shape or needs to start several requests at once.

type RequestInit

Field JS equivalent Notes
Method string options.method Defaults to "get"
Headers []Header options.headers A slice, because request-header order is observable
Credentials string options.credentials Only the exact string "include" enables cookies
Body []byte options.body Empty or nil sends no request entity

HeadersFromMap converts a map[string]string using JavaScript's own for...in property order (integer-like keys ascending, then insertion order — which for a Go map is unrecoverable, so lexicographic is used as the stable stand-in). Prefer building the slice directly when order matters.

type Response

Member JS equivalent
OK bool res.ok
Status int res.status
StatusText string res.statusText
URL string res.url — the URL after redirects
Headers *Headers res.headers
Text() (string, error) res.text()
JSON(v any) error res.json()
JSONRaw() (any, error) res.json() into an untyped value
Blob() (*Blob, error) res.blob()
Clone() *Response res.clone()

type Headers

Only the four members the original implements: Keys(), Entries(), Get(name), Has(name). Header names are always lowercase. There is no Append, Set, Delete, or iteration — the original types those as never, and so does this port.

Caveats

These are inherited from upstream by design.

Cookies are not sent by default. Set Credentials: "include". Note that only that exact string works; "same-origin" behaves like "omit", matching the original's options.credentials == "include" check.

An HTTP error status is not an error. A 404 or 500 returns a *Response with OK == false and a nil error. Only a transport failure returns an error, and it is always a *NetworkError. Check res.OK.

OK uses truncating division. ok is status/100 == 2, so any status from 200 to 299 is ok — and so is a nonsensical status like 2 or 29, exactly as in the original.

Subpackages

polyfill

The equivalent of polyfill/polyfill.mjs (if (!self.fetch) self.fetch = unfetch). Install() registers Fetch only when no implementation is present, and reports whether it did. On js/wasm it installs a real, JS-callable globalThis.fetch.

isomorphic

The equivalent of the isomorphic-unfetch package: Resolve picks node-fetch-style behavior when a process-like environment is detected and plain unfetch otherwise, while ResolveBrowser always picks unfetch. The node branch rewrites protocol-relative //host URLs to https://host, as upstream does.

Transports

Fetch talks to an XHR interface rather than to net/http directly, mirroring the original's dependency on XMLHttpRequest. This is also the seam the tests use, in place of upstream's jest.fn() mock.

  • Native builds use internal/httpxhr (net/http), which also registers a data: URI handler, because browsers serve data: URIs through XHR and the upstream TypeScript test depends on it.
  • js/wasm builds use internal/jsxhr, a real XMLHttpRequest via syscall/js.

Swap in your own with SetXHRFactory, or pass one per call to FetchWithXHR.

Differences from the original

Documented in full in MIGRATION.md. The short version: the API surface and observable behavior match; what changes is the shape imposed by Go's type system (JSON needs a destination, Get returns a second ok value, headers are an ordered slice) plus the addition of a blocking Fetch alongside the promise-based FetchAsync.

License

MIT © Jason Miller, as the original.

About

🐕 Bare minimum 500b fetch polyfill.

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages


Back | FazBrowse Home | New Git URL