This reference provides two concrete examples for dynamic request header manipulation via iodesktop.customHeaders.
Prerequisite
Enable header manipulation in the app definition:
{
"allowHeadersManipulation": true
}
Example 1: Different REST Endpoints From the Same App Split by Request Type
Scenario
A single app sends requests to two REST endpoints:
-
endpoint A is called via
fetch(); -
endpoint B is called via
XMLHttpRequest.
Rule Design
Use a single header rule if both requests are network XHR-class requests.
-
The filter supports
types, including"xhr". -
There is no separate
"fetch"request type value. -
Therefore, both
fetchandXMLHttpRequestrequests are matched withtypes: ["xhr"].
Use separate rules only when header values or URL targeting must differ.
Single-Rule Example
const header = {
"X-Channel": "market-data"
};
const filter = {
applications: ["clientlist"],
urls: [
"http://localhost:3000/api/fetch-endpoint", // called via fetch
"http://localhost:3000/api/xhr-endpoint" // called via XMLHttpRequest
],
types: ["xhr"]
};
const ruleId = await iodesktop.customHeaders.set(header, filter);
Request Calls Example (Fetch + XMLHttpRequest)
// Example request made with fetch().
const fetchResponse = await fetch("http://localhost:3000/api/fetch-endpoint", {
method: "GET"
});
const fetchData = await fetchResponse.json();
// Example request made with XMLHttpRequest.
const xhrData = await new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open("GET", "http://localhost:3000/api/xhr-endpoint", true);
xhr.onload = () => {
if (xhr.status >= 200 && xhr.status < 300) {
try {
resolve(JSON.parse(xhr.responseText));
} catch {
resolve(xhr.responseText);
}
return;
}
reject(new Error(`XHR request failed with status ${xhr.status}`));
};
xhr.onerror = () => reject(new Error("Network error during XHR request"));
xhr.send();
});
Both calls are matched by types: ["xhr"] and will receive the custom headers from the same rule.
When Separate Rules Are Needed
Create separate rules if:
-
each endpoint needs different header values;
-
each endpoint needs a different target scope (for example, URL pattern differences).
Example 2: Multiple Header Rules Matching the Same Request
Scenario
Two custom header rules match the same outgoing request.
Behavior
When multiple rules match:
-
all matching rules are applied;
-
header keys are merged;
-
if multiple rules set the same header key, the later-added rule overwrites the earlier value.
Overlapping-Rules Example
// Rule 1
const id1 = await iodesktop.customHeaders.set(
{
"X-Tenant": "alpha",
"X-Trace": "rule-1"
},
{
applications: ["clientlist"],
urls: ["https://api.example.com/*"],
types: ["xhr"]
}
);
// Rule 2 (also matches some of the same requests)
const id2 = await iodesktop.customHeaders.set(
{
"X-Trace": "rule-2", // same key as Rule 1
"X-Region": "eu-west-1"
},
{
applications: ["clientlist"],
urls: ["https://api.example.com/orders/*"],
types: ["xhr"]
}
);
For a request to https://api.example.com/orders/123, the effective headers are:
-
X-Tenant: alpha -
X-Trace: rule-2(overwritten by the later-added rule) -
X-Region: eu-west-1
Optional Cleanup
await iodesktop.customHeaders.remove(id1);
await iodesktop.customHeaders.remove(id2);
Notes
-
applicationsfiltering works for app type"window". -
For non-window app types, use
urlsfiltering. -
Passing an empty array for a filter property prevents matches for that property.