Остановите выполнение функции Javascript (на стороне клиента) или настройте ее - PullRequest
24 голосов
/ 19 октября 2010

Я хочу остановить выполнение одной единственной строки с сайта, чтобы браузер прочитал всю страницу, кроме этой единственной строки. Или браузер может просто пропустить выполнение этой функции JavaScript.

OR

Есть ли способ, которым я могу каким-то образом настроить javascript, чтобы функция генерирования случайных чисел в javascript не генерировала случайные числа, а только те числа, которые я хочу ...

У меня нет доступа к сайту, на котором размещен скрипт, поэтому все это нужно делать на стороне клиента.

Ответы [ 4 ]

36 голосов
/ 06 мая 2012

Firefox в настоящее время поддерживает beforescriptexecute событие (начиная с версии 4, выпущенной 22 марта 2011 года ) .

С этим событием и директивой // @run-at document-start Firefox и Greasemonkey теперь, похоже, отлично справляются с перехватом определенных тегов <script>.

Это все еще невозможно для Chrome + Tampermonkey . Для всего, кроме Firefox + Greasemonkey, вам нужно будет использовать методы, описанные в других ответах ниже, о написании полного расширения браузера.

Функция checkForBadJavascripts инкапсулирует это. Например, предположим, что на странице был тег <script>, например:

<script>
    alert ("Sorry, Sucka!  You've got no money left.");
</script>

Вы можете использовать checkForBadJavascripts примерно так:

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

чтобы получить более приятное сообщение. (^ _ ^)
См. Встроенную документацию в checkForBadJavascripts , для получения дополнительной информации.


Чтобы увидеть демонстрацию в полном сценарии, сначала посетите эту страницу на jsBin . Вы увидите 3 строки текста, две из которых добавлены JS.

Теперь, установите этот скрипт ( Просмотреть исходный код ; он также ниже.) И вернитесь на страницу. Вы увидите, что GM-скрипт удалил один плохой тег и заменил другой нашим «хорошим» JS.


Обратите внимание, что только Firefox поддерживает событие beforescriptexecute. И он был удален из спецификации HTML5 без указания эквивалентной возможности.



Полный пример сценария GM (такой же, как у GitHub и jsBin):

С учетом этого HTML:

<body onload="init()">
<script type="text/javascript" src="http://jsbin.com/evilExternalJS/js"></script>
<script type="text/javascript" language="javascript">
    function init () {
        var newParagraph            = document.createElement ('p');
        newParagraph.textContent    = "I was added by the old, evil init() function!";
        document.body.appendChild (newParagraph);
    }
</script>
<p>I'm some initial text.</p>
</body>


Используйте этот скрипт Greasemonkey:

// ==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);
}
7 голосов
/ 20 октября 2010

Ответ зависит от деталей, которые не были предоставлены (точная страница и строка кода были бы наилучшими), но вот как вы это делаете в целом:

  1. Если нарушитель Код JS не срабатывает сразу (срабатывает после DOMContentLoaded), тогда вы можете использовать Greasemonkey для замены кода, вызывающего сбой.EG:

    var scriptNode          = document.createElement ("script");
    scriptNode.textContent  = "Your JS code here";
    document.head.appendChild (scriptNode);
    

    Готово.

  2. Если код JS срабатывает сразу , то он усложняется.
    Сначала захваткопию скрипта и внесите в него желаемое изменение.Сохраните это локально.

  3. Является ли нарушающий сценарий файлом или находится на главной странице HTML (<script src="Some File> против <script>Mess O' Code</script>)?

  4. Если скрипт находится в файле, установите Adblock Plus и используйте его для блокировки загрузки этого скрипта.Затем используйте Greasemonkey, чтобы добавить ваш измененный код на страницу.Например:

    var scriptNode          = document.createElement ("script");
    scriptNode.setAttribute ("src", "Point to your modified JS file here.");
    document.head.appendChild (scriptNode);
    
  5. Если скрипт находится на главной странице HTML, установите либо NoScript (лучше всего), либо YesScript и используйтечтобы заблокировать JavaScript с этого сайта.
    Это означает, что вам потребуется использовать Greasemonkey для замены всех скриптов с этого сайта, которые вы хотите запустить.

0 голосов
/ 07 февраля 2017

Используете TamperMonkey? Все, что вам нужно добавить ниже вашего // @grant в заголовке TamperMonkey, это // @require http://urlofyoursite.com/myfile.js. Например, вот самая верхняя часть моей вещицы TamperMonkey:

// ==UserScript==
// @name         Project
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  try to take over the world!
// @author       You
// @match        https://docs.google.com/presentation/*
// @grant        none
// @require http://cdnjs.cloudflare.com/ajax/libs/annyang/2.1.0/annyang.min.js
// ==/UserScript==
0 голосов
/ 20 октября 2010

Вы можете использовать так называемый букмарклет.

Создайте файл js, который вы хотите запустить на другом сайте: your.js

Создайте HTML-страницу со следующим кодом:

<html>
<body>
  <a href="javascript:(function(){var s=document.createElement('SCRIPT');s.src='/url/to/your.js?'+(Math.random());document.getElementsByTagName('head')[0].appendChild(s);})()">
    Drag'n Drop this to your bookmarks
  </a>
</body>
</html>

Замените /url/to/your.js на путь вашего js-файла.

Загрузите эту небольшую страницу в браузер и перетащите ссылку на панель закладок.

Перейдите на веб-сайт, который вы хотите взломать, и нажмите на закладку, которую вы только что создали.Это загрузит your.js на странице и запустит код.

Примечание : часть ?'+(Math.random()) предназначена для предотвращения кэширования ваших js, это не обязательно, но полезно, когдавы развиваете your.js

...