Skip to content

Instantly share code, notes, and snippets.

@tomschall
Last active May 14, 2025 15:17
Show Gist options
  • Save tomschall/8eeb1c1361c7bf13e9d39da76ad80926 to your computer and use it in GitHub Desktop.
Save tomschall/8eeb1c1361c7bf13e9d39da76ad80926 to your computer and use it in GitHub Desktop.
Solr Response Interceptor (XHR Patch)

Solr Response Interceptor (XHR Patch)

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.

πŸ’‘ Concept

  • 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

πŸ›  Code Snippet

(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);
  };
})();

πŸ§ͺ How to Use

  1. Open DevTools (F12)
  2. Switch to the "Console" tab
  3. Paste the code and hit ENTER
  4. Perform a search in your app

πŸ” Notes

  • The Network tab shows the original HTTP response, not your patched version
  • Your app (React / Axios / jQuery etc.) receives the modified data

βœ… Use Cases

  • 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

🧠 Understanding this in XHR Interceptors

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! πŸ’₯

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment