fix: ChatGPT interception — synchronous early fetch hook
The fetch interceptor was loaded via <script src="content.js"> which is asynchronous. ChatGPT's Next.js framework stores a reference to the original fetch() during module initialization — before our script finishes downloading. By the time content.js patches window.fetch, ChatGPT is already using its stored copy of the original. Fixed with a two-step injection: 1. Injector injects a tiny INLINE <script> (synchronous, instant) that stores the real fetch/XHR references and installs a thin proxy. This runs before ANY page JavaScript. 2. Content.js loads normally, uses the stored __ssOriginalFetch reference, and registers __ssInterceptFetch so the proxy can route future calls through the full substitution engine. This ensures the fetch hook is in place before frameworks like Next.js, React, or any SPA framework can save a reference to the original fetch(). https://claude.ai/code/session_01SWSwDfMVij53bCTNSCLMwn
This commit is contained in:
+26
-1
@@ -70,7 +70,32 @@
|
||||
// Merge active profiles into a flat identity object for the content script
|
||||
const identity = mergeProfiles(identityData);
|
||||
|
||||
// Inject the main interception script into the page's world
|
||||
// STEP 1: Inject a synchronous inline script that patches fetch/XHR
|
||||
// IMMEDIATELY, before any page JS can store a reference to the originals.
|
||||
// This thin proxy queues calls until the full content.js loads.
|
||||
const earlyHook = document.createElement('script');
|
||||
earlyHook.textContent = `(function(){
|
||||
// Store the real fetch/XHR before any page script can
|
||||
window.__ssOriginalFetch = window.fetch;
|
||||
window.__ssOriginalXHROpen = XMLHttpRequest.prototype.open;
|
||||
window.__ssOriginalXHRSend = XMLHttpRequest.prototype.send;
|
||||
window.__ssReady = false;
|
||||
window.__ssQueue = [];
|
||||
|
||||
// Replace fetch with a proxy that queues until content.js is ready
|
||||
window.fetch = function() {
|
||||
if (window.__ssReady && window.__ssInterceptFetch) {
|
||||
return window.__ssInterceptFetch.apply(this, arguments);
|
||||
}
|
||||
// If not ready yet, call original (no substitution possible)
|
||||
return window.__ssOriginalFetch.apply(this, arguments);
|
||||
};
|
||||
})();`;
|
||||
(document.head || document.documentElement).appendChild(earlyHook);
|
||||
earlyHook.remove();
|
||||
|
||||
// STEP 2: Load the full content.js which will use __ssOriginalFetch
|
||||
// and set __ssReady = true when it's done hooking
|
||||
const script = document.createElement('script');
|
||||
script.setAttribute('data-ss-config', JSON.stringify({ mappings, identity, settings }));
|
||||
script.src = api.runtime.getURL('src/content/content.js');
|
||||
|
||||
Reference in New Issue
Block a user