Inject local .js file into a webpage?

Jack M picture Jack M · Apr 28, 2012 · Viewed 12.3k times · Source

I'd like to inject a couple of local .js files into a webpage. I just mean client side, as in within my browser, I don't need anybody else accessing the page to be able to see it. I just need to take a .js file, and then make it so it's as if that file had been included in the page's html via a <script> tag all along.

It's okay if it takes a second after the page has loaded for the stuff in the local files to be available.

It's okay if I have to be at the computer to do this "by hand" with a console or something.

I've been trying to do this for two days, I've tried Greasemonkey, I've tried manually loading files using a JavaScript console. It amazes me that there isn't (apparently) an established way to do this, it seems like such a simple thing to want to do. I guess simple isn't the same thing as common, though.

If it helps, the reason why I want to do this is to run a chatbot on a JS-based chat client. Some of the bot's code is mixed into the pre-existing chat code -- for that, I have Fiddler intercepting requests to .../chat.js and replacing it with a local file. But I have two .js files which are "independant" of anything on the page itself. There aren't any .js files requested by the page that I can substitute them for, so I can't use Fiddler.

Answer

eSniff picture eSniff · Apr 28, 2012

Since your already using a fiddler script, you can do something like this in the OnBeforeResponse(oSession: Session) function

    if ( oSession.oResponse.headers.ExistsAndContains("Content-Type", "html") &&
         oSession.hostname.Contains("MY.TargetSite.com") ) {

        oSession.oResponse.headers.Add("DEBUG1_WE_EDITED_THIS", "HERE");

        // Remove any compression or chunking
        oSession.utilDecodeResponse();

        var oBody = System.Text.Encoding.UTF8.GetString(oSession.responseBodyBytes);

        // Find the end of the HEAD script, so you can inject script block there.
        var oRegEx = oRegEx = /(<\/head>)/gi
        // replace the head-close tag with new-script + head-close 
        oBody = oBody.replace(oRegEx, "<script type='text/javascript'>console.log('We injected it');</script></head>");

        // Set the response body to the changed body string
        oSession.utilSetResponseBody(oBody); 
    }

Working example for www.html5rocks.com :

    if ( oSession.oResponse.headers.ExistsAndContains("Content-Type", "html") &&
         oSession.hostname.Contains("html5rocks") ) { //goto html5rocks.com
        oSession.oResponse.headers.Add("DEBUG1_WE_EDITED_THIS", "HERE");
        oSession.utilDecodeResponse();
        var oBody = System.Text.Encoding.UTF8.GetString(oSession.responseBodyBytes);
        var oRegEx = oRegEx = /(<\/head>)/gi
        oBody = oBody.replace(oRegEx, "<script type='text/javascript'>alert('We injected it')</script></head>");
        oSession.utilSetResponseBody(oBody); 
    }

Note, you have to turn streaming off in fiddler : http://www.fiddler2.com/fiddler/help/streaming.asp and I assume you would need to decode HTTPS : http://www.fiddler2.com/fiddler/help/httpsdecryption.asp

I have been using fiddler script less and less, in favor of fiddler .Net Extensions - http://fiddler2.com/fiddler/dev/IFiddlerExtension.asp