Skip to content

Latest commit

 

History

History
1125 lines (750 loc) · 30.7 KB

File metadata and controls

1125 lines (750 loc) · 30.7 KB

> Back to homepage

Options

Source code: source/core/options.ts

Like fetch stores the options in a Request instance, Got does so in Options.
It is made of getters and setters that provide fast option normalization and validation.

By default, Got will retry on failure. To disable this option, set options.retry to {limit: 0}.

Merge behavior explained

When an option is already set, setting it again replaces it with a deep clone by default.
Otherwise the merge behavior is documented in the corresponding section for the option.

How to store options

The Options class is useful for storing and validating configuration for Got instances.

The constructor - new Options(url, options, defaults) - takes the same arguments as the got function.

To use an Options instance, create an extended Got instance:

import got, {Options} from 'got';

const options = new Options({
	prefixUrl: 'https://httpbin.org',
	headers: {
		foo: 'foo'
	}
});

options.headers.foo = 'bar';

// Use got.extend() to create an instance with the Options
const instance = got.extend(options);

const {headers} = await instance('anything').json();
console.log(headers.foo);
//=> 'bar'

For most use cases, plain objects are simpler and more convenient:

import got from 'got';

const options = {
	prefixUrl: 'https://httpbin.org',
	headers: {
		foo: 'foo'
	}
};

options.headers.foo = 'bar';

// Plain objects can be passed directly as the second argument
const {headers} = await got('anything', options).json();
console.log(headers.foo);
//=> 'bar'

Note that the Options constructor throws immediately when an invalid option is provided, such as a non-existing option or a typo. With plain objects, validation only happens when the request is made.

For TypeScript users, got exports a dedicated type called OptionsInit.
It is a plain object that can store the same properties as Options.

The Options class is useful for storing the base configuration of a custom Got client, especially when you want early validation of options.

Resetting options

Unlike Got 11, explicitly specifying undefined no longer keeps the parent value.
In order to keep the parent value, you must not set an option to undefined.
Doing so will reset those values:

instance(, {searchParams: undefined}});
instance(, {cookieJar: undefined}});
instance(, {responseType: undefined}});
instance(, {prefixUrl: ''});
instance(, {agent: {http: undefined, https: undefined, http2: undefined}});
instance(, {context: {token: undefined,}});
instance(, {https: {rejectUnauthorized: undefined,}});
instance(, {cacheOptions: {immutableMinTimeToLive: undefined,}});
instance(, {headers: {'user-agent': undefined,}});
instance(, {timeout: {request: undefined,}});

In order to reset hooks, retry and pagination, another Got instance must be created:

const defaults = new Options();

const secondInstance = instance.extend({mutableDefaults: true});
secondInstance.defaults.options.hooks = defaults.hooks;
secondInstance.defaults.options.retry = defaults.retry;
secondInstance.defaults.options.pagination = defaults.pagination;

url

Type: string | URL

The URL to request. Usually the url represents a WHATWG URL.

import got from 'got';

// This:
await got('https://httpbin.org/anything');

// is semantically the same as this:
await got(new URL('https://httpbin.org/anything'));

// as well as this:
await got({
	url: 'https://httpbin.org/anything'
});

Note:

  • Throws if no protocol specified.

Note:

  • If url is a string, then the query string will not be parsed as search params.
    This is in accordance to the specification.
    If you want to pass search params instead, use the searchParams option below.
import got from 'got';

await got('https://httpbin.org/anything?query=a b'); //=> ?query=a%20b
await got('https://httpbin.org/anything', {searchParams: {query: 'a b'}}); //=> ?query=a+b

// The query string is overridden by `searchParams`
await got('https://httpbin.org/anything?query=a b', {searchParams: {query: 'a b'}}); //=> ?query=a+b

Note:

  • Leading slashes are disallowed to enforce consistency and avoid confusion.
    For example, when the prefix URL is https://example.com/foo and the input is /bar, there's ambiguity whether the resulting URL would become https://example.com/foo/bar or https://example.com/bar. The latter is used by browsers.

searchParams

Type: string | URLSearchParams | object<string, Primitive>

WHATWG URL Search Params to be added to the request URL.

import got from 'got';

const response = await got('https://httpbin.org/anything', {
	searchParams: {
		hello: 'world',
		foo: 123
	}
}).json();

console.log(response.args);
//=> {hello: 'world', foo: 123}

If you need to pass an array, you can do it using a URLSearchParams instance:

import got from 'got';

const searchParams = new URLSearchParams([['key', 'a'], ['key', 'b']]);

await got('https://httpbin.org/anything', {searchParams});

console.log(searchParams.toString());
//=> 'key=a&key=b'

Note:

  • This will override the query string in url.

Note:

  • null values are not stringified, an empty string is used instead.
  • undefined values will clear the original keys.

Merge behavior:

  • Overrides existing properties.

prefixUrl

Type: string
Default: ''

The string to be prepended to url.

The prefix can be any valid URL, either relative or absolute. A trailing slash / is optional - one will be added automatically.

import got from 'got';

// This:
const instance = got.extend({prefixUrl: 'https://httpbin.org'});
await instance('anything');

// is semantically the same as this:
await got('https://httpbin.org/anything');

Note:

  • Changing prefixUrl also updates the url option if set.

Note:

  • If you're passing an absolute URL as url, you need to set prefixUrl to an empty string.

signal

Type: AbortSignal

You can abort the request using AbortController.

import got from 'got';

const abortController = new AbortController();

const request = got('https://httpbin.org/anything', {
	signal: abortController.signal
});

setTimeout(() => {
	abortController.abort();
}, 100);

method

Type: string
Default: GET

The HTTP method used to make the request.
The most common methods are: GET, HEAD, POST, PUT, DELETE.

import got from 'got';

const {method} = await got('https://httpbin.org/anything', {
	method: 'POST'
}).json();

console.log(method);
// => 'POST'

headers

Type: object<string, string>
Default: {}

The HTTP headers to be sent. Headers set to undefined will be omitted.

import got from 'got';

const {headers} = await got.post('https://httpbin.org/anything', {
	headers: {
		hello: 'world'
	}
}).json();

console.log(headers);
// => {hello: 'world'}

Merge behavior:

  • Overrides existing properties.

isStream

Type: boolean
Default: false

Whether the got function should return a Request duplex stream or a Promise<Response>.

import got from 'got';

// This:
const stream = got('https://httpbin.org/anything', {isStream: true});

// is semantically the same as this:
const stream = got.stream('https://httpbin.org/anything');

stream.setEncoding('utf8');
stream.on('data', console.log);

body

Type: string | Buffer | TypedArray | stream.Readable | Generator | AsyncGenerator | Iterable | AsyncIterable | FormData or form-data instance

The payload to send.

For string, Buffer, and TypedArray types (Uint8Array, Uint16Array, etc.), the content-length header is automatically set if the content-length and transfer-encoding headers are missing.

The content-length header is not automatically set when body is an instance of fs.createReadStream().

To set content-length for file streams, you need to manually provide it using fs.promises.stat():

import fs from 'node:fs';
import fsPromises from 'node:fs/promises';
import got from 'got';

const filePath = 'path/to/file';
const fileStats = await fsPromises.stat(filePath);
const fileStream = fs.createReadStream(filePath);

await got.post('https://httpbin.org/anything', {
	body: fileStream,
	headers: {
		'content-length': fileStats.size.toString()
	}
});
import got from 'got';

const {data} = await got.post('https://httpbin.org/anything', {
	body: 'Hello, world!'
}).json();

console.log(data);
//=> 'Hello, world!'

You can also use typed arrays (Uint8Array, Uint16Array, etc.) as request body:

import got from 'got';

const uint8Body = new Uint8Array([104, 101, 108, 108, 111]); // 'hello' in ASCII

const {data} = await got.post('https://httpbin.org/anything', {
	body: uint8Body
}).json();

console.log(data);
//=> 'hello'

You can use Iterable and AsyncIterable objects as request body, including Web ReadableStream:

import got from 'got';

// Using an async generator
async function* generateData() {
	yield 'Hello, ';
	yield 'world!';
}

await got.post('https://httpbin.org/anything', {
	body: generateData()
});

Since Got 12, you can use spec-compliant FormData objects as request body, such as formdata-node or formdata-polyfill:

import got from 'got';
import {FormData} from 'formdata-node'; // or:
// import {FormData} from 'formdata-polyfill/esm.min.js';

const form = new FormData();
form.set('greeting', 'Hello, world!');

const data = await got.post('https://httpbin.org/post', {
	body: form
}).json();

console.log(data.form.greeting);
//=> 'Hello, world!'

Note:

  • If body is specified, then the json or form option cannot be used.

Note:

  • If you use this option, got.stream() will be read-only.

Note:

Note:

  • This option is not enumerable and will not be merged with the instance defaults.

json

Type: JSON-serializable values

JSON request body. If set, the content-type header defaults to application/json.

Important

This option only affects the request body you send to the server. To parse the response as JSON, you must either call .json() on the promise or set responseType: 'json' in the options.

import got from 'got';

const {data} = await got.post('https://httpbin.org/anything', {
	json: {
		hello: 'world'
	}
}).json();

console.log(data);
//=> `{hello: 'world'}`

form

Type: object<string, Primitive>

The form body is converted to a query string using (new URLSearchParams(form)).toString().

If set, the content-type header defaults to application/x-www-form-urlencoded.

import got from 'got';

const {data} = await got.post('https://httpbin.org/anything', {
	form: {
		hello: 'world'
	}
}).json();

console.log(data);
//=> 'hello=world'

parseJson

Type: (text: string) => unknown
Default: (text: string) => JSON.parse(text)

The function used to parse JSON responses.

import got from 'got';
import Bourne from '@hapi/bourne';

// Preventing prototype pollution by using Bourne
const parsed = await got('https://example.com', {
	parseJson: text => Bourne.parse(text)
}).json();

console.log(parsed);

stringifyJson

Type: (object: unknown) => string
Default: (object: unknown) => JSON.stringify(object)

The function used to stringify the body of JSON requests.

Example: ignore all properties starting with an underscore

import got from 'got';

await got.post('https://example.com', {
	stringifyJson: object => JSON.stringify(object, (key, value) => {
		if (key.startsWith('_')) {
			return;
		}

		return value;
	}),
	json: {
		some: 'payload',
		_ignoreMe: 1234
	}
});

Example: all numbers as strings

import got from 'got';

await got.post('https://example.com', {
	stringifyJson: object => JSON.stringify(object, (key, value) => {
		if (typeof value === 'number') {
			return value.toString();
		}

		return value;
	}),
	json: {
		some: 'payload',
		number: 1
	}
});

allowGetBody

Type: boolean
Default: false

Set this to true to allow sending body for the GET method.

However, the HTTP/2 specification says:

An HTTP GET request includes request header fields and no payload body

Therefore this option has no effect when using HTTP/2.

Note:

  • This option is only meant to interact with non-compliant servers when you have no other choice.

Note:

  • The RFC 7231 doesn't specify any particular behavior for the GET method having a payload, therefore it's considered an anti-pattern.

copyPipedHeaders

Type: boolean
Default: true

Automatically copy headers from piped streams.

When piping a request into a Got stream (e.g., request.pipe(got.stream(url))), this controls whether headers from the source stream are automatically merged into the Got request headers.

Note: Piped headers overwrite any explicitly set headers with the same name. To override this, either set copyPipedHeaders to false and manually copy safe headers, or use a beforeRequest hook to force specific header values after piping.

Useful for proxy scenarios, but you may want to disable this to filter out headers like Host, Connection, Authorization, etc.

Example: Disable automatic header copying and manually copy only safe headers

import got from 'got';
import {pipeline} from 'node:stream/promises';

server.get('/proxy', async (request, response) => {
	const gotStream = got.stream('https://example.com', {
		copyPipedHeaders: false,
		headers: {
			'user-agent': request.headers['user-agent'],
			'accept': request.headers['accept'],
			// Explicitly NOT copying host, connection, authorization, etc.
		}
	});

	await pipeline(request, gotStream, response);
});

Example: Override piped headers using beforeRequest hook

import got from 'got';

const gotStream = got.stream('https://example.com', {
	hooks: {
		beforeRequest: [
			options => {
				// Force specific header values after piping
				options.headers.host = 'example.com';
				delete options.headers.authorization;
			}
		]
	}
});

timeout

Type: object

See the Timeout API.

Merge behavior:

  • Overrides existing properties.

retry

Type: object

See the Retry API.

Merge behavior:

  • Overrides existing properties.

hooks

Type: object

See the Hooks API.

Merge behavior:

  • Merges arrays via [...hooksArray, ...next]

encoding

Type: string
Default: 'utf8'

Encoding to be used on setEncoding of the response data.

To get a Buffer, you need to set responseType to 'buffer' instead. Don't set this option to null.

import got from 'got';

const response = await got('https://httpbin.org/anything', {
	encoding: 'base64'
}).text();

console.log(response);
//=> base64 string

Note:

  • This option does not affect streams! Instead, do:
import got from 'got';

const stream = got.stream('https://httpbin.org/anything');

stream.setEncoding('base64');
stream.on('data', console.log);

responseType

Type: 'text' | 'json' | 'buffer'
Default: 'text'

The parsing method.

The promise also has .text(), .json() and .buffer() methods which return another Got promise for the parsed body.
It's like setting the options to {responseType: 'json', resolveBodyOnly: true} but without affecting the main Got promise.

import got from 'got';

const responsePromise = got('https://httpbin.org/anything');
const bufferPromise = responsePromise.buffer();
const jsonPromise = responsePromise.json();

const [response, buffer, json] = await Promise.all([responsePromise, bufferPromise, jsonPromise]);
// `response` is an instance of Got Response
// `buffer` is an instance of Buffer
// `json` is an object

Note:

  • When using streams, this option is ignored.

Note:

  • 'buffer' will return the raw body buffer. Any modifications will also alter the result of .text() and .json(). Before overwriting the buffer, please copy it first via Buffer.from(buffer).
    See nodejs/node#27080

resolveBodyOnly

Type: boolean
Default: false

If true, the promise will return the Response body instead of the Response object.

import got from 'got';

const url = 'https://httpbin.org/anything';

// This:
const body = await got(url).json();

// is semantically the same as this:
const body = await got(url, {responseType: 'json', resolveBodyOnly: true});

context

Type: object<string, unknown>
Default: {}

Note:

  • Non-enumerable properties inside are not merged.

Contains user data. It's very useful for storing auth tokens:

import got from 'got';

const instance = got.extend({
	hooks: {
		beforeRequest: [
			options => {
				if (typeof options.context.token !== 'string') {
					throw new Error('Token required');
				}

				options.headers.token = options.context.token;
			}
		]
	}
});

const context = {
	token: 'secret'
};

const {headers} = await instance('https://httpbin.org/headers', {context}).json();

console.log(headers);
//=> {token: 'secret', …}

This option is enumerable. In order to define non-enumerable properties inside, do the following:

import got from 'got';

const context = {};

Object.defineProperties(context, {
	token: {
		value: 'secret',
		enumerable: false,
		configurable: true,
		writable: true
	}
});

const instance = got.extend({context});

console.log(instance.defaults.options.context);
//=> {}

Merge behavior:

  • Overrides existing properties.

cookieJar

Type: object | tough.cookieJar

Note:

  • Setting this option will result in the cookie header being overwritten.

Cookie support. Handles parsing and storing automatically.

import got from 'got';
import {CookieJar} from 'tough-cookie';

const cookieJar = new CookieJar();

await cookieJar.setCookie('foo=bar', 'https://example.com');
await got('https://example.com', {cookieJar});

cookieJar.setCookie

Type: (rawCookie: string, url: string) => void | Promise<void>

See ToughCookie API for more information.

cookieJar.getCookieString

Type: (currentUrl: string) => string | Promise<string>

See ToughCookie API for more information.

ignoreInvalidCookies

Type: boolean
Default: false

Ignore invalid cookies instead of throwing an error.
Only useful when the cookieJar option has been set.

Note:

  • This is not recommended! Use at your own risk.

followRedirect

Type: boolean | (response: PlainResponse) => boolean
Default: true

Whether redirect responses should be followed automatically.

Optionally, pass a function to dynamically decide based on the response object.

Note:

  • If a 303 is sent by the server in response to any request type (POST, DELETE, etc.), Got will request the resource pointed to in the location header via GET.
    This is in accordance with the specification. You can optionally turn on this behavior also for other redirect codes - see methodRewriting.
import got from 'got';

const instance = got.extend({followRedirect: false});

const response = await instance('http://google.com');

console.log(response.headers.location);
//=> 'https://google.com'

maxRedirects

Type: number
Default: 10

If exceeded, the request will be aborted and a MaxRedirectsError will be thrown.

import got from 'got';

const instance = got.extend({maxRedirects: 3});

try {
	await instance('https://nghttp2.org/httpbin/absolute-redirect/5');
} catch (error) {
	//=> 'Redirected 3 times. Aborting.'
	console.log(error.message);
}

decompress

Type: boolean
Default: true

Decompress the response automatically. This will set the accept-encoding header to gzip, deflate, br (and zstd on Node.js >= 22.15.0).

If disabled, a compressed response is returned as a Buffer. This may be useful if you want to handle decompression yourself.

Note

Zstandard (zstd) compression support is available on Node.js >= 22.15.0 and will be automatically enabled when available.

import got from 'got';

const response = await got('https://google.com');

console.log(response.headers['content-encoding']);
//=> 'gzip'

strictContentLength

Type: boolean
Default: false

Throw an error if the server response's content-length header value doesn't match the number of bytes received.

This is useful for detecting truncated responses and follows RFC 9112 requirements for message completeness.

Note

  • Responses without a content-length header are not validated.
  • When enabled and validation fails, a ReadError with code ERR_HTTP_CONTENT_LENGTH_MISMATCH will be thrown.

dnsLookup

Type: Function
Default: dns.lookup

Custom DNS resolution logic.

The function signature is the same as dns.lookup.

dnsCache

Type: CacheableLookup | false

An instance of CacheableLookup used for making DNS lookups.
Useful when making lots of requests to different public hostnames.

Note:

  • This should stay disabled when making requests to internal hostnames such as localhost, database.local etc.
  • CacheableLookup uses dns.resolver4(…) and dns.resolver6(…) under the hood and falls back to dns.lookup(…) when the first two fail, which may lead to additional delay.

dnsLookupIpVersion

Type: 4 | 6
Default: undefined

The IP version to use. Specifying undefined will use the default configuration.

request

Type: Function<ClientRequest | IncomingMessage> | AsyncFunction<ClientRequest | IncomingMessage>
Default: http.request | https.request (depending on the protocol)

Custom request function.

The main purpose of this is to support HTTP/2 using a wrapper.

cache

Type: object | false
Default: false

Cache adapter instance for storing cached response data.

cacheOptions

Type: object
Default: {}

Cache options used for the specified request.

http2

Type: boolean
Default: false

Note:

  • This option requires Node.js 15.10.0 or newer as HTTP/2 support on older Node.js versions is very buggy.

If true, the request option will default to http2wrapper.auto and the entire agent object will be passed.

Note:

  • ALPN negotiation will have place in order to determine if the server actually supports HTTP/2. If it doesn't, HTTP/1.1 will be used.

Note:

  • Setting the request option to https.request will disable HTTP/2 usage. It is required to use http2wrapper.auto.

Note:

  • There is no direct h2c support. However, you can provide a h2session option in a beforeRequest hook. See an example.
import got from 'got';

const {headers} = await got(
	'https://httpbin.org/anything',
	{
		http2: true
	}
);

console.log(headers[':status']);
//=> 200

Note:

  • The current Got version may use an older version of http2-wrapper.
    If you prefer to use the newest one, set both request to http2wrapper.auto and http2 to true.
import http2wrapper from 'http2-wrapper';
import got from 'got';

const {headers} = await got(
	'https://httpbin.org/anything',
	{
		http2: true,
		request: http2wrapper.auto
	}
);

console.log(headers[':status']);
//=> 200

See the http2-wrapper docs to learn more about Agent and Proxy support.

agent

Type: object
Default: {}

An object with http, https and http2 properties.

Got will automatically resolve the protocol and use the corresponding agent. It defaults to:

{
	http: http.globalAgent,
	https: https.globalAgent,
	http2: http2.globalAgent
}

Note:

The HTTP/2 Agent must be an instance of http2wrapper.Agent

throwHttpErrors

Type: boolean
Default: true

If true, it will throw when the status code is not 2xx / 3xx.

If this is disabled, requests that encounter an error status code will be resolved with the response instead of throwing. This may be useful if you are checking for resource availability and are expecting error responses.

username

Type: string
Default: ''

The username used for Basic authentication.

password

Type: string
Default: ''

The password used for Basic authentication.

localAddress

Type: string | undefined
Default: undefined

The local IP address used to make the request.

createConnection

Type: Function | undefined
Default: undefined

The function used to retrieve a net.Socket instance when the agent option is not used.

https

Type: object

See Advanced HTTPS API.

pagination

Type: object

See Pagination API.

setHost

Type: boolean
Default: true

Specifies whether or not to automatically add the Host header.

maxHeaderSize

Type: number | undefined
Default: undefined

Optionally overrides the value of --max-http-header-size (default 16KB: 16384).

methodRewriting

Type: boolean
Default: false

Specifies if the HTTP request method should be rewritten as GET on redirects.

As the specification prefers to rewrite the HTTP method only on 303 responses, this is Got's default behavior. Setting methodRewriting to true will also rewrite 301 and 302 responses, as allowed by the spec. This is the behavior followed by curl and browsers.

Note:

enableUnixSockets

Type: boolean
Default: false

When enabled, requests can also be sent via UNIX Domain Sockets.

Warning Make sure you do your own URL sanitizing if you accept untrusted user input for the URL.

Use the following URL scheme: PROTOCOL://unix:SOCKET:PATH

  • PROTOCOL - http or https
  • SOCKET - Absolute path to a UNIX domain socket, for example: /var/run/docker.sock
  • PATH - Request path, for example: /v2/keys
import got from 'got';

await got('http://unix:/var/run/docker.sock:/containers/json', {enableUnixSockets: true});

// Or without protocol (HTTP by default)
await got('unix:/var/run/docker.sock:/containers/json', {enableUnixSockets: true});

// Enable Unix sockets for the whole instance.
const gotWithUnixSockets = got.extend({enableUnixSockets: true});

await gotWithUnixSockets('http://unix:/var/run/docker.sock:/containers/json');

Methods

options.merge(other: Options | OptionsInit)

Merges other into the current instance.

If you look at the source code, you will notice that internally there is a this._merging property.
Setters work a bit differently when it's true.

options.toJSON()

Returns a new plain object that can be stored as JSON.

options.createNativeRequestOptions()

Creates a new object for native Node.js HTTP request options.

In other words, this translates Got options into Node.js options.

Note:

  • Some other stuff, such as timeouts, is handled internally by Got.

options.getRequestFunction()

Returns a http.request-like function used to make the request.

options.freeze()

Makes the entire Options instance read-only.