javascriptfiddlermockttp

Trying to Inject a JavaScript into webpage using mockttp


So far i have tried the below code but its throwing me an error Failed to handle request: Cannot read properties of undefined (reading 'replace')

var INJECT = "<script src='https://examlple.com/googletranslate.js'></script>"

await server.forAnyRequest().thenPassThrough({
    beforeResponse: (res) => {
        var newBody = res.body.text.replace("<head>", "<head>"+INJECT)
        return {
            status: 200,
            body: newBody
        };
    }
});

How can i solve this error and inject a JavaScript into the page successfully


Solution

  • Mockttp aside, from this error by itself you can tell that somewhere you're trying to read X.replace for an X that's undefined.

    In this case, there's a clear probable cause: res.body.text.replace(...). This tells you that res.body.text is undefined, so something is wrong there.

    In fact, if you look at Mockttp's reference docs for the CompletedBody type, you'll see that there is no .text property - it's .getText() instead, and this returns a promise, not a fixed value (this is one of the breaking changes from Mockttp v3). These are asynchronous because reading the text of a request may require non-trivial decoding steps, e.g. to decode Brotli data.

    That means you need to make your callback async, use await, and call getText(). I haven't tested, but I think this version of your example should work correctly:

    var INJECT = "<script src='https://examlple.com/googletranslate.js'></script>"
    
    await server.forAnyRequest().thenPassThrough({
        beforeResponse: async (res) => { // <-- Make the callback async
            var oldBody = await res.body.getText() // <-- await the result of getText()
            var newBody = oldBody.replace("<head>", "<head>"+INJECT)
            return {
                status: 200,
                body: newBody
            };
        }
    });