Синхронное предупреждение XMLHttpRequest и <script>

Я получаю предупреждающее сообщение:

Синхронный XMLHttpRequest в основном потоке устарел из-за его пагубных последствий для конечного пользователя. Для получения дополнительной справки отметьте http://xhr.spec.whatwg.org/.

при выполнении асинхронного запроса AJAX, содержащего script (имеющего локальный src), который вводится в HTML, используя метод $.html(). Я изменил данный script, содержащий async="async", но предупреждение все еще остается.

Я начал отлаживать проблему, обнаружив, что мой добавленный <script> обрабатывается с помощью вызова jQuery AJAX из jQuery.ajaxTransport (http://code.jquery.com/jquery-1.10.0.js, # 8663), где async установлен на false (вероятно, там, где проблема возникает).

Теперь - что я могу сделать по этому поводу?

Сообщение появляется в новейшей версии Chrome, а также в Firefox.


Пока я не могу предоставить тестовый пример jsfiddle, вот тестовый пример, который отображает проблему:

test.html

<html>
<body>
<script type="text/javascript" src="https://code.jquery.com/jquery-2.1.3.js"></script>
<script>
$(document).ready(function(){
    $.ajax({
        url: '/response.html',
        success: function(response){
            $(document.body).html(response);
        }
    })
});
</script>
</body>
</html>

response.html

<script type="text/javascript" src="/json.js" async="async"></script>

json.js

console.log('hi');

Запрос AJAX не требуется для запуска предупреждения - все, что необходимо, вставляет <script>

test2.html

<html>
<body>
<script type="text/javascript" src="https://code.jquery.com/jquery-2.1.3.js"></script>
<script>
$(document).ready(function(){
    $(document.body).html('<script type="text/javascript" src="/json.js" async="async"><\/script>');
});
</script>
</body>
</html>

Стоит отметить, что это было исправлено, за https://github.com/jquery/jquery/issues/2060

Ответ 1

ОБНОВЛЕНИЕ: Это исправлено в jQuery 3.x. Если у вас нет возможности обновиться до версии выше 3.0, вы можете использовать следующий сниппет, НО имейте в виду, что теперь вы потеряете синхронизирующее поведение script загрузка в целевом контенте.

Вы можете исправить это, установив явно опцию async запроса xhr на true:

$.ajaxPrefilter(function( options, original_Options, jqXHR ) {
    options.async = true;
});

Ответ 2

Теперь браузеры предупреждают об использовании синхронного XHR. MDN говорит, что это было реализовано недавно:

Начиная с Gecko 30.0 (Firefox 30.0/Thunderbird 30.0/SeaMonkey 2.27)

https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Synchronous_and_Asynchronous_Requests#Synchronous_request

Здесь как изменения были реализованы в Firefox и Chromium:

Как сообщают пользователи Chrome, это начало происходить где-то около версии 39. Я не уверен, как связать ревизию/набор изменений с конкретной версией Chrome.

Да, это происходит, когда jQuery добавляет разметку на страницу, включая теги script, которые загружают внешние js файлы. Вы можете воспроизвести его примерно так:

$('body').append('<script src="foo.js"></script>');

Я думаю, что jQuery исправит это в некоторой будущей версии. До тех пор мы можем либо игнорировать его, либо использовать предложение А. Вольфа выше.

Ответ 3

Даже последний jQuery имеет эту строку, поэтому у вас есть следующие параметры:

  • Измените источник jQuery самостоятельно - но, возможно, есть веская причина для его использования.
  • Живой с предупреждением, обратите внимание, что этот параметр устарел и не устарел.
  • Измените свой код, чтобы он не использовал эту функцию.

Я думаю, что номер 2 является наиболее разумным курсом в этом случае.

Кстати, если вы еще не пробовали, попробуйте это: $.ajaxSetup({async:true});, но я не думаю, что это сработает.

Ответ 4

Я был обеспокоен этим сообщением об ошибке, несмотря на использование async: true. Оказывается, фактическая проблема заключалась в использовании метода success. Я изменил это на done, и предупреждение исчезло.

success: function(response) { ... }

заменено на:

done: function(response) { ... }

Ответ 5

В моем случае это было вызвано flexie script, которое было частью приложения "CDNJS Selections", предлагаемого Cloudflare.

Согласно Cloudflare "Это приложение устарело в марте 2015 года". Я отключил его, и сообщение исчезло мгновенно.

Вы можете получить доступ к приложениям, посетив https://www.cloudflare.com/a/cloudflare-apps/yourdomain.com

Ответ 6

если вам просто нужно загрузить script, не делайте этого ниже

$(document.body).html('<script type="text/javascript" src="/json.js" async="async"><\/script>');

Попробуйте

var scriptEl = document.createElement('SCRIPT');
    scriptEl.src = "/module/script/form?_t="+(new Date()).getTime();
    //$('#holder').append(scriptEl) // <--- create warning
    document.body.appendChild(scriptEl);