Skip to content

Instantly share code, notes, and snippets.

@jsoverson
Last active March 27, 2022 13:15
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save jsoverson/4fe67f835af8c64189a643b5c527d9dc to your computer and use it in GitHub Desktop.
Save jsoverson/4fe67f835af8c64189a643b5c527d9dc to your computer and use it in GitHub Desktop.
Intercept and prettify every script
const puppeteer = require('puppeteer');
const prettier = require('prettier');
const atob = require('atob');
const btoa = require('btoa');
const requestCache = new Map();
const urlPatterns = [
'*'
]
function transform(source) {
return prettier.format(source, {parser:'babel'});
}
async function intercept(page, patterns, transform) {
const client = await page.target().createCDPSession();
await client.send('Network.enable');
await client.send('Network.setRequestInterception', {
patterns: patterns.map(pattern => ({
urlPattern: pattern, resourceType: 'Script', interceptionStage: 'HeadersReceived'
}))
});
client.on('Network.requestIntercepted', async ({ interceptionId, request, responseHeaders, resourceType }) => {
console.log(`Intercepted ${request.url} {interception id: ${interceptionId}}`);
const response = await client.send('Network.getResponseBodyForInterception',{ interceptionId });
const contentTypeHeader = Object.keys(responseHeaders).find(k => k.toLowerCase() === 'content-type');
let newBody, contentType = responseHeaders[contentTypeHeader];
if (requestCache.has(response.body)) {
newBody = requestCache.get(response.body);
} else {
const bodyData = response.base64Encoded ? atob(response.body) : response.body;
try {
if (resourceType === 'Script') newBody = transform(bodyData, { parser: 'babel' });
else newBody === bodyData
} catch(e) {
console.log(`Failed to process ${request.url} {interception id: ${interceptionId}}: ${e}`);
newBody = bodyData
}
requestCache.set(response.body, newBody);
}
const newHeaders = [
'Date: ' + (new Date()).toUTCString(),
'Connection: closed',
'Content-Length: ' + newBody.length,
'Content-Type: ' + contentType
];
console.log(`Continuing interception ${interceptionId}`)
client.send('Network.continueInterceptedRequest', {
interceptionId,
rawResponse: btoa('HTTP/1.1 200 OK' + '\r\n' + newHeaders.join('\r\n') + '\r\n\r\n' + newBody)
});
});
}
(async function main(){
const browser = await puppeteer.launch({
headless:false,
defaultViewport:null,
devtools: true,
args: ['--window-size=1920,1170','--window-position=0,0']
});
const page = (await browser.pages())[0];
intercept(page, urlPatterns, transform);
browser.on('targetcreated', async (target) => {
const page = await target.page();
intercept(page, urlPatterns, transform);
});
})()
@dontcallmedom
Copy link

-        else newBody === bodyData
+       else newBody = bodyData

@nickkaranatsios
Copy link

nickkaranatsios commented Aug 6, 2021

Since the Network.Network.setRequestInterception call has been deprecated how do you go about implementing the above code using the Fetch API?

Never mind I came up with the following implementation.

async function intercept(page, patterns, transform) {
  const client = await page.target().createCDPSession();

  await client.send('Fetch.enable', {
		patterns:  patterns.map(pattern => ({
      urlPattern: pattern, resourceType: 'Script', requestStage: 'Response'
    }))
  });

	client.on('Fetch.requestPaused', async({ requestId, request, frameId, resourceType, responseErrorReason, responseStatusCode, responseHeaders, networkId } ) => {
		console.log(`Intercepted id ${requestId} ${request.url} method ${request.method} headers ${Object.keys(request.headers)} frame id ${frameId} resource type ${resourceType}`);
		if (responseErrorReason) {
			console.log(`Have errored response ${responseErrorReason}`);
		}
		if (responseStatusCode) {
			console.log(`Have response ${responseStatusCode}`);
		}

		const response = await client.send("Fetch.getResponseBody", { requestId });
		console.log(`Response body for ${requestId} is ${response.body.length} bytes`);

		await client.send('Fetch.continueRequest', { requestId });
	});
}

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