Stop execution of Javascript function (client side) or tweak it

前端 未结 5 1993
别跟我提以往
别跟我提以往 2020-11-22 08:48

I want to stop the execution of one single line from a site, so that the whole page is read by the browser except that single line. Or the browser may simply skip the execut

5条回答
  •  名媛妹妹
    2020-11-22 09:32

    Firefox currently supports the beforescriptexecute event (as of Version 4, released on March 22, 2011).

    With that event and the // @run-at document-start directive, Firefox and Greasemonkey now seem to do a good job intercepting specific

    You could use checkForBadJavascripts like so:

    checkForBadJavascripts ( [
        [   false, 
            /Sorry, Sucka/, 
            function () {
                addJS_Node ('alert ("Hooray, you\'re a millionaire.");');
            } 
        ]
    ] );
    

    to get a much nicer message. (^_^)
    See the inline documentation, in checkForBadJavascripts, for more.


    To see a demonstration in a complete script, first visit this page at jsBin. You will see 3 lines of text, two of them added by JS.

    Now, install this script (View source; it's also below.) and revisit the page. You will see that the GM-script deleted one bad tag and replaced another with our "good" JS.


    Note that only Firefox supports the beforescriptexecute event. And it was removed from the HTML5 spec with no equivalent capability specified.



    Complete GM script example (The same as the one at GitHub and jsBin):

    Given this HTML:

    
    
    
    

    I'm some initial text.


    Use this Greasemonkey script:

    // ==UserScript==
    // @name        _Replace evil Javascript
    // @include     http://jsbin.com/ogudon*
    // @run-at      document-start
    // ==/UserScript==
    
    /****** New "init" function that we will use
        instead of the old, bad "init" function.
    */
    function init () {
        var newParagraph            = document.createElement ('p');
        newParagraph.textContent    = "I was added by the new, good init() function!";
        document.body.appendChild (newParagraph);
    }
    
    /*--- Check for bad scripts to intercept and specify any actions to take.
    */
    checkForBadJavascripts ( [
        [false, /old, evil init()/, function () {addJS_Node (init);} ],
        [true,  /evilExternalJS/i,  null ]
    ] );
    
    function checkForBadJavascripts (controlArray) {
        /*--- Note that this is a self-initializing function.  The controlArray
            parameter is only active for the FIRST call.  After that, it is an
            event listener.
    
            The control array row is  defines like so:
            [bSearchSrcAttr, identifyingRegex, callbackFunction]
            Where:
                bSearchSrcAttr      True to search the SRC attribute of a script tag
                                    false to search the TEXT content of a script tag.
                identifyingRegex    A valid regular expression that should be unique
                                    to that particular script tag.
                callbackFunction    An optional function to execute when the script is
                                    found.  Use null if not needed.
        */
        if ( ! controlArray.length) return null;
    
        checkForBadJavascripts      = function (zEvent) {
    
            for (var J = controlArray.length - 1;  J >= 0;  --J) {
                var bSearchSrcAttr      = controlArray[J][0];
                var identifyingRegex    = controlArray[J][1];
    
                if (bSearchSrcAttr) {
                    if (identifyingRegex.test (zEvent.target.src) ) {
                        stopBadJavascript (J);
                        return false;
                    }
                }
                else {
                    if (identifyingRegex.test (zEvent.target.textContent) ) {
                        stopBadJavascript (J);
                        return false;
                    }
                }
            }
    
            function stopBadJavascript (controlIndex) {
                zEvent.stopPropagation ();
                zEvent.preventDefault ();
    
                var callbackFunction    = controlArray[J][2];
                if (typeof callbackFunction == "function")
                    callbackFunction ();
    
                //--- Remove the node just to clear clutter from Firebug inspection.
                zEvent.target.parentNode.removeChild (zEvent.target);
    
                //--- Script is intercepted, remove it from the list.
                controlArray.splice (J, 1);
                if ( ! controlArray.length) {
                    //--- All done, remove the listener.
                    window.removeEventListener (
                        'beforescriptexecute', checkForBadJavascripts, true
                    );
                }
            }
        }
    
        /*--- Use the "beforescriptexecute" event to monitor scipts as they are loaded.
            See https://developer.mozilla.org/en/DOM/element.onbeforescriptexecute
            Note that it does not work on acripts that are dynamically created.
        */
        window.addEventListener ('beforescriptexecute', checkForBadJavascripts, true);
    
        return checkForBadJavascripts;
    }
    
    function addJS_Node (text, s_URL, funcToRun) {
        var D                                   = document;
        var scriptNode                          = D.createElement ('script');
        scriptNode.type                         = "text/javascript";
        if (text)       scriptNode.textContent  = text;
        if (s_URL)      scriptNode.src          = s_URL;
        if (funcToRun)  scriptNode.textContent  = '(' + funcToRun.toString() + ')()';
    
        var targ = D.getElementsByTagName ('head')[0] || D.body || D.documentElement;
        //--- Don't error check here. if DOM not available, should throw error.
        targ.appendChild (scriptNode);
    }
    

提交回复
热议问题