Scaling up with request
The previous page covered the bread-and-butter request.get / request.post. This page is for everything else: headers, timeouts, debouncing, cancellation, custom response handling, and the request.config global.
Set request headers
Pass headers in the third (config) argument.
request.get("https://reqres.in/api/users", null, {
headers: {
Authorization: "Bearer token",
},
});Common Question
Q: I'm trying to send a Cookie header from JavaScript and it doesn't work.
A: Cookie, Authorization (in some browsers), Set-Cookie, Host and the rest of the forbidden header names are off-limits to scripts. The browser silently strips them. Use the cookie module to write a cookie that the browser will then send automatically.
Set request timeout
config.timeout (in milliseconds) aborts the request via AbortSignal.timeout. 0 disables it.
request.get("https://looooong.example/", null, { timeout: 10_000 });Very short timeouts
In development mode, a fastjs/request warning is logged when timeout is ≤ 1000 ms – it is easy to accidentally abort every request that way.
Set default timeout
request.config is the global config object. Anything you set on it becomes the default for subsequent calls.
request.config.timeout = 10_000;Built-in debounce
config.wait (milliseconds) collapses multiple calls into one – the request is only fired after wait has passed without another call. Calling abort() while waiting cancels the pending timer.
import { dom, request } from "jsfast";
dom.newEl("button", { text: "Click me" }).addEvent("click", () => {
request
.get("https://reqres.in/api/users", null, { wait: 1000 })
.then((data) => console.log(data));
});Cancelling a request
Every FastjsRequest exposes abort(reason?). It clears any pending debounce timer and aborts the underlying fetch via its AbortController.
const req = request.get("https://reqres.in/api/long");
req.then((data) => console.log(data));
// Later, e.g. when the user navigates away:
req.abort("navigated away");abort() before the request has been dispatched (e.g. during wait) is a safe no-op for downstream observers.
Customise the response handling
request.config.handler controls how Fastjs decides "success vs failure" and how the body is decoded.
By default Fastjs decodes the body as JSON when Content-Type includes application/json, otherwise as text, and treats any 2xx code as success.
Example: accept any 4xx as "success" so you can read the body in .then:
request.config.handler.responseCode = (code) => code >= 200 && code < 500;Example: always decode as ArrayBuffer:
request.config.handler.handleResponse = async (response) =>
await response.arrayBuffer();GlobalConfig Type Declaration
interface GlobalConfig {
timeout: number;
hooks: RequestHookParam;
handler: {
handleResponse: (
response: Response,
request: FastjsRequest,
) => Promise<any>;
responseCode: (code: number, request: FastjsRequest) => boolean;
};
check: {
ignoreFormatWarning: boolean;
stringBodyWarning: boolean;
unrecommendedMethodWarning: boolean;
};
}The default implementation:
handler: {
// application/json → json(); everything else → text()
handleResponse: async (response) => {
if (response.headers.get("Content-Type")?.includes("application/json")) {
return await response.json();
}
return await response.text();
},
// 2xx is "success"
responseCode: (code) => code >= 200 && code < 300,
}Per-call config reference
Anything you don't pass to config is filled in from request.config (the global). See Add Hooks for the hook fields.
RequestConfig Type Declaration
interface RequestConfig {
timeout: number;
headers: { [key: string]: string };
wait: number;
failed: (error: FailedParams<Error | number>) => void;
callback: (data: RequestReturnData, response: RequestReturn) => void;
query: { [key: string]: any } | string | null;
body: { [key: string]: any } | string | null;
hooks: RequestHookParam;
}Reusing config
Use request.request(config) to materialise a RequestConfig (with global defaults merged in) and pass it around explicitly:
const baseCfg = request.request({
timeout: 8000,
headers: { "X-App": "demo" },
});
request.get("/api/posts", null, baseCfg);
request.post("/api/posts", { title: "Hi" }, baseCfg);If you want a fully-fledged reusable instance with its own URL / data / hooks, use request.create instead.