diff --git a/src/scriptlets/trusted-replace-fetch-response.js b/src/scriptlets/trusted-replace-fetch-response.js index 78fc41ae..8abe051e 100644 --- a/src/scriptlets/trusted-replace-fetch-response.js +++ b/src/scriptlets/trusted-replace-fetch-response.js @@ -116,7 +116,14 @@ export function trustedReplaceFetchResponse(source, pattern = '', replacement = return Reflect.apply(target, thisArg, args); } - const forgeResponse = (response, text) => { + /** + * Create new Response object using original response' properties + * and given text as body content + * @param {Response} response original response to copy properties from + * @param {string} textContent text to set as body content + * @returns {Response} + */ + const forgeResponse = (response, textContent) => { const { bodyUsed, headers, @@ -128,21 +135,15 @@ export function trustedReplaceFetchResponse(source, pattern = '', replacement = url, } = response; - const patternRegexp = pattern === getWildcardSymbol() - ? toRegExp() - : toRegExp(pattern); - - const modifiedContent = text.replace(patternRegexp, replacement); - // eslint-disable-next-line compat/compat - const fiddledResponse = new Response(modifiedContent, { + const forgedResponse = new Response(textContent, { status, statusText, headers, }); // Manually set properties which can't be set by Response constructor - Object.defineProperties(fiddledResponse, { + Object.defineProperties(forgedResponse, { url: { value: url }, type: { value: type }, ok: { value: ok }, @@ -150,13 +151,23 @@ export function trustedReplaceFetchResponse(source, pattern = '', replacement = redirected: { value: redirected }, }); - hit(source); + return forgedResponse; }; return nativeFetch(...args) .then((response) => { return response.text() - .then((bodyText) => forgeResponse(response, bodyText)) + .then((bodyText) => { + const patternRegexp = pattern === getWildcardSymbol() + ? toRegExp() + : toRegExp(pattern); + + const modifiedTextContent = bodyText.replace(patternRegexp, replacement); + const forgedResponse = forgeResponse(response, modifiedTextContent); + + hit(source); + return forgedResponse; + }) .catch(() => { // log if response body can't be converted to a string const fetchDataStr = objectToString(fetchData); diff --git a/src/scriptlets/trusted-replace-xhr-response.js b/src/scriptlets/trusted-replace-xhr-response.js index 43a68c12..193c855c 100644 --- a/src/scriptlets/trusted-replace-xhr-response.js +++ b/src/scriptlets/trusted-replace-xhr-response.js @@ -131,9 +131,9 @@ export function trustedReplaceXhrResponse(source, pattern = '', replacement = '' * to be able to collect response data without triggering * listeners on original XHR object */ - const replacingRequest = new XMLHttpRequest(); - replacingRequest.addEventListener('readystatechange', () => { - if (replacingRequest.readyState !== 4) { + const forgedRequest = new XMLHttpRequest(); + forgedRequest.addEventListener('readystatechange', () => { + if (forgedRequest.readyState !== 4) { return; } @@ -145,7 +145,7 @@ export function trustedReplaceXhrResponse(source, pattern = '', replacement = '' responseXML, status, statusText, - } = replacingRequest; + } = forgedRequest; // Extract content from response const content = responseText || response; @@ -186,7 +186,7 @@ export function trustedReplaceXhrResponse(source, pattern = '', replacement = '' hit(source); }); - nativeOpen.apply(replacingRequest, [xhrData.method, xhrData.url]); + nativeOpen.apply(forgedRequest, [xhrData.method, xhrData.url]); // Mimic request headers before sending // setRequestHeader can only be called on open request objects @@ -194,12 +194,12 @@ export function trustedReplaceXhrResponse(source, pattern = '', replacement = '' const name = header[0]; const value = header[1]; - replacingRequest.setRequestHeader(name, value); + forgedRequest.setRequestHeader(name, value); }); requestHeaders = []; try { - nativeSend.call(replacingRequest, args); + nativeSend.call(forgedRequest, args); } catch { return Reflect.apply(target, thisArg, args); }