Сценарии отладки, добавленные с помощью функции getScript jQuery - PullRequest
49 голосов
/ 27 марта 2009

У меня есть страница, которая динамически добавляет ссылки на скрипты с помощью функции $.getScript в jQuery. Скрипты загружаются и выполняются нормально, поэтому я знаю, что ссылки верны. Однако, когда я добавляю оператор «отладчик» в любой из сценариев, чтобы позволить мне шагать по коду в отладчике (например, VS.Net, Firebug и т. Д.), Он не работает. Похоже, что способ загрузки сценариев в jQuery не позволяет отладчикам находить файлы.

У кого-нибудь есть обходной путь для этого?

Ответы [ 9 ]

74 голосов
/ 28 марта 2009

Хорошо, получается, что реализация функции $.getScript() по умолчанию работает по-разному в зависимости от того, находится ли указанный файл сценария в одном домене или нет. Внешние ссылки, такие как:

$.getScript("http://www.someothersite.com/script.js")

приведет к тому, что jQuery создаст внешнюю ссылку на скрипт, которую можно без проблем отладить.

<script type="text/javascript" src="http://www.someothersite.com/script.js"></script>

Однако, если вы ссылаетесь на локальный файл сценария, такой как любой из следующих:

$.getScript("http://www.mysite.com/script.js")
$.getScript("script.js")
$.getScript("/Scripts/script.js");

, затем jQuery будет асинхронно загружать содержимое сценария и затем добавлять его как встроенное содержимое:

<script type="text/javascript">{your script here}</script>

Этот последний подход не работает с любым отладчиком, который я тестировал (Visual Studio.net, Firebug, IE8 Debugger).

Обходной путь - переопределить функцию $.getScript(), чтобы она всегда создавала внешнюю ссылку, а не встроенный контент. Вот скрипт для этого. Я проверил это в Firefox, Opera, Safari и IE 8.

<script type="text/javascript">
// Replace the normal jQuery getScript function with one that supports
// debugging and which references the script files as external resources
// rather than inline.
jQuery.extend({
   getScript: function(url, callback) {
      var head = document.getElementsByTagName("head")[0];
      var script = document.createElement("script");
      script.src = url;

      // Handle Script loading
      {
         var done = false;

         // Attach handlers for all browsers
         script.onload = script.onreadystatechange = function(){
            if ( !done && (!this.readyState ||
                  this.readyState == "loaded" || this.readyState == "complete") ) {
               done = true;
               if (callback)
                  callback();

               // Handle memory leak in IE
               script.onload = script.onreadystatechange = null;
            }
         };
      }

      head.appendChild(script);

      // We handle everything using the script element injection
      return undefined;
   },
});
</script>
18 голосов
/ 21 сентября 2011

С JQuery 1.6 (возможно, 1.5) вы можете переключиться не на getScript, а на jQuery.ajax (). Затем установите crossDomain: true, и вы получите тот же эффект.

Ошибка обратного вызова не будет работать. Так что вы можете не настроить его, как показано ниже.

Тем не менее, я настроил таймер и очистил его с успехом. Так, скажите, что через 10 секунд, если я ничего не слышу, я предполагаю, что файл был плохим.

        jQuery.ajax({
            crossDomain: true,
            dataType: "script",
            url: url,
            success: function(){
                _success(_slot)
            },
            error: function(){
                _fail(_slot);
            }
        })
14 голосов
/ 08 февраля 2014

Для тех, кто хотел бы отлаживать скрипты и использовать их с $ .when (ответ Джеймса Мессингера плохо работает с $ .when), я предлагаю использовать этот код:

var loadScript = function (path) {
  var result = $.Deferred(),
  script = document.createElement("script");
  script.async = "async";
  script.type = "text/javascript";
  script.src = path;
  script.onload = script.onreadystatechange = function (_, isAbort) {
      if (!script.readyState || /loaded|complete/.test(script.readyState)) {
         if (isAbort)
             result.reject();
         else
            result.resolve();
    }
  };
  script.onerror = function () { result.reject(); };
  $("head")[0].appendChild(script);
  return result.promise();
};

Все заслуги и славы достаются Бенджамину Думке-фон-дер-Эхе и его статье: Вставка скрипта jQuery и ее последствия для отладки

Это хорошо работает с $ .when, и скрипт полностью видим и отлаживаем. Благодаря.

2 голосов
/ 08 мая 2015

Существует простой способ отладки с помощью Chrome.

1- Напишите console.log («что-то») в строке, которую вы хотите отладить.

2- Следите за консолью для этого журнала.

sample log

3- Нажмите на адресную ссылку перед журналом.

4 - Установить точку останова на этой линии.

2 голосов
/ 19 июня 2011

Попробуйте это,

jQuery.extend({
getScript: function(url, callback) {
    var head = document.getElementsByTagName("head")[0];

    var ext = url.replace(/.*\.(\w+)$/, "$1");

    if(ext == 'js'){
        var script = document.createElement("script");
        script.src = url;
        script.type = 'text/javascript';
    } else if(ext == 'css'){
        var script = document.createElement("link");
        script.href = url;
        script.type = 'text/css';
        script.rel = 'stylesheet';
    } else {
        console.log("Неизветсное расширение подгружаемого скрипта");
        return false;
    }



    // Handle Script loading
    {
        var done = false;

        // Attach handlers for all browsers
        script.onload = script.onreadystatechange = function(){
            if ( !done && (!this.readyState ||
            this.readyState == "loaded" || this.readyState == "complete") ) {
                done = true;
                if (callback)
                callback();

                // Handle memory leak in IE
                script.onload = script.onreadystatechange = null;
            }
        };
    }

    head.appendChild(script);

    // We handle everything using the script element injection
    return undefined;

} 
   });
0 голосов
/ 12 января 2019

Все ответы где-то на этой странице, но я хотел бы подвести итог для будущих читателей.

Проверка (динамически добавленных) загрузок файлов

Используя Chrome, вы можете видеть файлы Javascript, добавленные с использованием $ .getScript (http://api.jquery.com/jQuery.getScript/) на панели Network на вкладке XHR ; обратите внимание, что они не отображаются на вкладке JS.

Отладка файла

1) Установка точки останова в коде. Как уже упоминалось в других ответах \ комментариях, вы можете вставить

debugger;

оператор в коде Javascript. Это вызовет отладчик браузера. См. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/debugger для получения дополнительной информации.

2) Использование карты источников , чтобы отобразить ее на панели источников браузера (тестирование в Chrome). Добавить

//# sourceURL=whatevername.js

до конца вашего файла. [Файл отображается под (без домена) на исходной панели Chrome].

См: Как отлаживать динамически загружаемый JavaScript (с помощью jQuery) в самом отладчике браузера? и https://developer.mozilla.org/en-US/docs/Tools/Debugger/How_to/Use_a_source_map для получения дополнительной информации.

3) Переопределите $ .getScript, чтобы всегда использовать внешнюю ссылку согласно принятому ответу (я не проверял).

0 голосов
/ 07 апреля 2016

Это объединяет решение ОП с решением Эрика. Переопределите необходимый jquery для обработки get, как всегда, кросс-домен, и они будут отображаться идеально, не нарушая ничего в реализации обещания jquery.

jQuery.extend({
get: function (url, data, callback, type) {
 // shift arguments if data argument was omitted
 if (jQuery.isFunction(data)) {
    type = type || callback;
    callback = data;
    data = undefined;
 }

 return jQuery.ajax({
    url: url,
    type: "GET":,
    dataType: type,
    data: data,
    success: callback,
    crossDomain: true
 });
}


});
0 голосов
/ 25 февраля 2016

В Firefox 38.6.0 с Firebug 2.0.14, когда я перехожу на вкладку «Сценарий», в раскрывающемся меню я вижу запись типа jquery-1.11.1.js line 338 > eval, которая содержит загруженный скрипт. Кроме того, при взгляде на код в этой версии jQuery, похоже, что внутренне $.getScript() использует $.get() и, в конечном счете, $.ajax(), единственное отличие заключается в части eval() для скрипта, которая обрабатывается jQuery globalEval() функция:

// Evaluates a script in a global context
// Workarounds based on findings by Jim Driscoll
// http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context
globalEval: function( data ) {
    if ( data && jQuery.trim( data ) ) {
        // We use execScript on Internet Explorer
        // We use an anonymous function so that context is window
        // rather than jQuery in Firefox
        ( window.execScript || function( data ) {
            window[ "eval" ].call( window, data );
        } )( data );
    }
},
0 голосов
/ 13 февраля 2016

Чтобы избежать лишнего кодирования, вы можете попробовать это. В файл, в котором вы объявили свой $ ('document'). Ready () ( или любой другой файл, к которому ваш отладчик будет обращаться ), добавьте что-то вроде ...

$.debug = function(name) {
   var n = name;
}

Добавьте точку останова в строку назначения в вашем отладчике. Затем в любой другой js-файл, который вы загружаете с помощью $ .getScript (), вы можете добавить ...

$.debug("some string to identify this point of code");

Всякий раз, когда выполняется эта строка, ваш отладчик останавливается и ждет вашей команды. Выйдите из функции $ .debug и все!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...