Headers
Session defaults, per-request headers, removing a header, and header order.
A browser profile copies the TLS and HTTP/2 handshake, not the headers. You decide which headers are sent, and anti-bot checks compare them with the fingerprint, so a Chrome handshake should carry Chrome's User-Agent.
Session headers and request headers
Put the headers every request needs on the session. Add or override headers per request:
const session = new Session({
clientIdentifier: ClientIdentifier.chrome_150,
headers: {
"user-agent":
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/150.0.0.0 Safari/537.36",
"accept-language": "en-US,en;q=0.9",
},
});
// Request headers are added on top of the session's.
const withAuth = await session.get("https://httpbin.org/headers", {
headers: { authorization: "Bearer token" },
});
// → User-Agent, Accept-Language and Authorization are all sent
// null removes one session header for this request only.
const withoutLanguage = await session.get("https://httpbin.org/headers", {
headers: { "accept-language": null },
});
// → only User-Agent is sentThe rules:
- Request headers are layered over session headers per key, and names match case-insensitively:
User-Agentin the request replacesuser-agentfrom the session. - On a clash, the request's value and its casing win. The header keeps the session's position in the order.
- A
null(orundefined) value removes that session header for this request. - Numbers are sent as strings; arrays are joined with
", ".
Changed in 2.2.0
Before 2.2.0, a request headers object replaced the session headers
entirely, which silently dropped the session's User-Agent. See the
changelog.
When no headers are given
If neither the session nor the request has a headers object, a small default set is sent:
User-Agent: tls-client/2.2.0
Accept-Encoding: gzip, deflate, br
Accept: */*
Connection: keep-aliveThat User-Agent matches no browser. Always set your own.
The defaults only apply when headers is missing on both sides. An explicit headers: {} sends none of them, and Go's transport then adds User-Agent: Go-http-client/2.0 and Accept-Encoding itself. Whenever you leave out user-agent, you get one of these non-browser values.
Header order
Browsers send headers in a fixed order, and some fingerprinting looks at it. headerOrder lists header names, lower-case, in the order to send them:
const ordered = new Session({
clientIdentifier: ClientIdentifier.chrome_150,
headers: {
accept: "text/html",
"user-agent": "Mozilla/5.0 …",
"accept-language": "en-US",
},
// Header names in the order the browser sends them.
headerOrder: ["user-agent", "accept", "accept-language"],
});headerOrder can be set on the session or per request; a request's order replaces the session's. Headers not in the list are sent after the listed ones.
HTTP/2 pseudo-headers (:method, :authority, :scheme, :path) have their own order, pseudoHeaderOrder. It only applies to custom fingerprints; browser profiles already use the browser's order.
Proxy CONNECT headers
connectHeaders are sent to an HTTP proxy on the CONNECT request that opens the tunnel, not to the target site. See Proxies.