I was trying to inject a React script into a website after page has loaded/
I was able to get it working on most of the websites like https://google.com, https://discovercard.com, https://stackoverflow.com, https://capitalone.com.
However, when I execute the same script in https://chase.com or https://bankofamerica.com, I get a reference error where I am transforming JSX using Babel.transform
because Babel
is undefined.
All the required scripts however are downloaded as can be seen in the network tab and the DOM.
Could someone please let me know if there any specific tag or attribute in the HTML that is preventing execution of Javascript on these websites. It seemed like banking websites do this to prevent external Javascript.
Here is the code I tried on the developer console
NOTE: Hello World! appears after 5 seconds because of the setTimeout
const react = document.createElement("script");
react.src = "https://cdnjs.cloudflare.com/ajax/libs/react/16.2.0/umd/react.production.min.js"
document.body.appendChild(react);
const reactDom = document.createElement("script");
reactDom.src = "https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.2.0/umd/react-dom.production.min.js"
document.body.appendChild(reactDom);
const babel = document.createElement("script");
babel.src = "https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.26.0/babel.min.js"
document.body.appendChild(babel);
const rootDiv = document.createElement("div");
rootDiv.id = "app";
rootDiv.style="width: 100px; height: 100px; position: absolute; top: 0px; left: 0px; z-index: 999999";
document.body.appendChild(rootDiv);
setTimeout(() => {
const babelScript = document.createElement("script");
babelScript.type = "text/babel";
const jsxCode = "ReactDOM.render(<h1>Hello, world!</h1>, document.getElementById('app'));"
const babelTransformCode = Babel.transform(jsxCode, { presets: ["react"] } ).code;
eval(babelTransformCode);
}, 5000)
The two sites that aren't working are using requireJs, so that instead of loading the modules on window, they are getting loaded using define
.
The easy thing to do, is just call define = undefined
before the rest of your script and it will work just as it did with the rest of the sites. For safety sake it appears that the UMD loader checks for exports and modules.exports as well, so you might want to set them to undefined as well.
define = undefined;
exports = undefined;
if (window.module) module.exports = undefined;
The libraries your are using are packed together using a Universal Module Definition. That is so they can work with a wide variety of module loaders such as requireJs. The UMD pattern looks for common variables defined by module loaders, so by setting these variables to undefined it causes the modules to be loaded globally and accessible to your scripts as written.