A small browser-side debug script to intercept and modify Solr responses on /search_endpoint/
β useful for UI testing or facet debugging without touching the backend.
- Intercepts
XMLHttpRequest
- Captures the response once it's ready (
readyState === 4
) - Replaces the response with a modified JSON object
- Logs both the original and the modified versions for comparison
(function() {
const origOpen = XMLHttpRequest.prototype.open;
const origSend = XMLHttpRequest.prototype.send;
XMLHttpRequest.prototype.open = function(method, url, ...rest) {
this._url = url;
return origOpen.call(this, method, url, ...rest);
};
XMLHttpRequest.prototype.send = function(...args) {
const origOnReadyStateChange = this.onreadystatechange;
this.onreadystatechange = function() {
if (this.readyState === 4 && this._url?.includes('/search_endpoint/')) {
try {
const originalJson = JSON.parse(this.responseText);
const modifiedJson = {
...originalJson,
result_count: 0,
results: [],
facets: {
fields: {
tag: [["999", 1, "HACKED"]],
documenttype: [["2", 0, "Debug"]],
documentstyle: [["1", 0, "Demo"]],
categories: [["105", 0, "Intercept"]],
status: [["2", 0, "TEST"]]
},
dates: {},
queries: {}
}
};
const newResponse = JSON.stringify(modifiedJson);
console.log("π Original Solr response:", originalJson);
console.log("π§ͺ Modified response sent to app:", modifiedJson);
Object.defineProperty(this, 'responseText', { value: newResponse });
Object.defineProperty(this, 'response', { value: newResponse });
} catch (e) {
console.warn('Intercept failed:', e);
}
}
if (origOnReadyStateChange) origOnReadyStateChange.apply(this, arguments);
};
return origSend.apply(this, args);
};
})();
- Open DevTools (F12)
- Switch to the "Console" tab
- Paste the code and hit ENTER
- Perform a search in your app
- The Network tab shows the original HTTP response, not your patched version
- Your app (React / Axios / jQuery etc.) receives the modified data
- Fake facets for UI testing
- Simulate empty
results[]
to test behavior - Test how the UI responds to
result_count = 0
- Trigger and debug edge cases
In the context of both .open()
and .send()
, the this
keyword refers to the current instance of XMLHttpRequest
β not window
.
This allows you to store custom properties like this._url
and later access built-in properties like this.readyState
and this.responseText
when intercepting the request lifecycle.
const xhr = new XMLHttpRequest();
xhr.open('GET', '/some-endpoint');
xhr.onreadystatechange = function() {
console.log(this.readyState); // Works fine β refers to xhr
};
xhr.send();
This behavior is crucial for interceptors to properly track and manipulate specific requests.
Tom, ready to level up your debug game! π₯