JavaScript console.log вызывает ошибку: «Синхронный XMLHttpRequest в основном потоке устарел…»

386

Я добавляю логи в консоль для проверки состояния различных переменных без использования отладчика Firefox.

Однако во многих местах, где я добавляю a console.logв свой main.jsфайл, я получаю следующую ошибку вместо моих милых маленьких рукописных сообщений:

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

Какие альтернативы или обертки для console.logя могу добавить к своему использованию кода, которые не вызовут эту ошибку?

Я "делаю это неправильно"?

Натан Басанезе
источник
8
Я не понимаю, как вызов console.log () может вызвать вызов ajax, если только не включен какой-либо подключаемый модуль удаленной регистрации или что-то подобное.
Марк Б,
Я не уверен, что он делает вызов ajax. Это помогло бы, если бы я включил скриншот?
Натан Басанезе
6
xmlhttprequest - это, в основном, ajax-запрос.
Марк Б
14
<script>$.ajaxPrefilter(function( options, originalOptions, jqXHR ) { options.async = true; });</script> это удалит предупреждение. Вы можете увидеть здесь для того же вопроса.
Akilsree1
1
Я просто использовал get вместо post, это помогло. JQuery.
Стас Казанин

Ответы:

278

Это случилось со мной, когда я был ленивым и включил тег script как часть возвращаемого содержимого. В качестве таких:

Частичное содержимое HTML:

<div> 
 SOME CONTENT HERE
</div>
<script src="/scripts/script.js"></script> 

По крайней мере, в моем случае кажется, что если вы вернете HTML-контент, подобный этому, через xhr, вы заставите jQuery выполнить вызов для получения этого скрипта. Этот вызов происходит с ложным асинхронным флагом, поскольку он предполагает, что для продолжения загрузки необходим скрипт.

В подобных ситуациях вам будет лучше, если вы посмотрите на какую-то обязательную среду и просто вернете объект JSON, или, в зависимости от вашего бэкенда и шаблонов, вы можете изменить способ загрузки своих скриптов.

Вы также можете использовать jQuerygetScript() для получения соответствующих скриптов. Вот скрипка, это просто прямая копия примера jQuery, но я не вижу никаких предупреждений, когда скрипты загружаются таким образом.

пример

<script>
var url = "/scripts/script.js";
$.getScript(url);
</script>

http://jsfiddle.net/49tkL0qd/

kroolk
источник
8
ошибка в том, что OP использует где-то синхронный XMLHttpRequests, я не думаю, что должным образом JQuery, так как не кажется, что он использует его ... однако это происходит со мной, когда я пытаюсь загрузить, <script>как вы сказали в обратном вызове Аякс асинхронного вызова. Мой ajax-вызов асинхронный, однако в обратном вызове, который я выполняю, $('#object').html(data)где данные представляют собой часть htmlс <script>и когда эта строка выполняется, появляется ошибка в js console. +1 !!! спасибо :).
albciff
2
Для этого проекта я использовал JQuery.
Натан Басанезе
1
@ 37 монет, если бы это был ответ; пометьте его как таковой и замените тег javascript на jQuery.
Бретт Касвелл
3
Это была моя проблема, и, скорее всего, проблема ОП тоже - ОП, пожалуйста, пометьте это как ответ. Ответ с более высоким рейтингом здесь в настоящее время никак не помогает людям с этой проблемой, поэтому принятие этого ответа очень поможет другим.
Ник Коад
1
Просто FYI jQuery getScript нарушает кэширование. Я думаю, что .ajax сделает то же самое и разрешит кеширование
Ronnie Royston
75

Предупреждающее сообщение МОЖЕТ БЫТЬ вызвано запросом XMLHttpRequest в главном потоке с установленным ложным флагом async.

https://xhr.spec.whatwg.org/#synchronous-flag :

Синхронный запрос XMLHttpRequest вне рабочих находится в процессе удаления с веб-платформы, поскольку он оказывает пагубное влияние на работу конечного пользователя. (Это долгий процесс, который занимает много лет.) Разработчики не должны передавать false для асинхронного аргумента, когда глобальная среда JavaScript является средой документов. Пользовательским агентам настоятельно рекомендуется предупреждать о таком использовании в инструментах разработчика и могут поэкспериментировать с генерированием исключения InvalidAccessError при его возникновении.

Будущее направление - разрешить XMLHttpRequests только в рабочих потоках. Сообщение предназначено для предупреждения об этом.

PedanticDan
источник
6
нет, предупреждение о сообщении является НАСТОЯЩИМ из-за запроса XMLHttpRequest в основном потоке с установленным в асинхронном флаге значением false. Это вполне может быть ошибкой в ​​Firefox (но это, скорее всего, функция / реализация jQuery); в любом случае, как описание части спецификации можно считать ответом на вопрос, который, как утверждает console.logзаявитель, направляет эти предупреждения?
Бретт Касвелл
1
@ Бретт - последние два предложения моего ответа объясняют, почему я включил часть спецификации, которую я сделал. Я отредактирую свой ответ, чтобы быть более точным.
PedanticDan
2
с учетом всего сказанного: все, что вы указали в этом ответе, является правильной информацией; кроме того, это, вероятно, относится к вероятной проблеме; то есть повышение этого предупреждения влияет на поведение и / или стабильность отладчика. Таким образом, обходной путь вполне может состоять в том, чтобы предупредить повышение предупреждения путем устранения причины его возникновения.
Бретт Касвелл
Они должны добавить флаг about :, чтобы включить его для локальной отладки. Синхронизация XHR может быть очень полезна для инструментов / отладки фреймворков под управлением localhost.
user2800679
63

Я также столкнулся с той же проблемой, но смог исправить ее, поставив async: true. Я знаю, что по умолчанию это правда, но это работает, когда я пишу это явно

$.ajax({
   async: true,   // this will solve the problem
   type: "POST",
   url: "/Page/Method",
   contentType: "application/json",
   data: JSON.stringify({ ParameterName: paramValue }),
});
Ирфан Ашраф
источник
2
В моем случае это не было причиной ... только удаление асинхронного: ложного без изменения на истинное исправленное это
hsobhy
@Irfan в моем случае это настройка синхронизации: ложь, которая помогла!
t_plusplus
34

Живой отладчик Visual Studio 2015/2017 внедряет код, содержащий устаревший вызов.

Чарли
источник
13
Я провел довольно много времени, пытаясь понять, почему я вижу это предупреждение; Я подумал, что поделюсь наиболее подходящим вопросом SO, чтобы другие могли сэкономить время.
Чарли
22

Иногда необходимо ajax загрузить скрипт, но отложить готовность документа до окончания загрузки скрипта.

JQuery поддерживает это с помощью holdReady()функции.

Пример использования:

$.holdReady(true);                              //set hold
function releaseHold() { $.holdReady(false); }  //callback to release hold
$.getScript('script.js', releaseHold);          //load script then release hold

Фактическая загрузка скрипта является асинхронной ( без ошибок ), но эффект является синхронным, если остальная часть вашего JavaScript выполняется после того, как документ готов .

Эта расширенная функция обычно используется динамическими загрузчиками сценариев, которые хотят загрузить дополнительный JavaScript, такой как плагины jQuery, перед тем как разрешить событие ready, даже если DOM может быть готов.

Документация:
https://api.jquery.com/jquery.holdready


ОБНОВЛЕНИЕ 7 января 2019

От JQMIGRATE :

jQuery.holdReady () устарела

Причина . jQuery.holdReady()Метод устарел из-за его пагубного влияния на общую производительность страницы. Этот метод может предотвратить инициализацию всего кода на странице в течение продолжительного времени.

Решение: переписать страницу так, чтобы не требовалось откладывать все готовые обработчики jQuery. Это может быть достигнуто, например, поздней загрузкой только кода, который требует задержки, когда это безопасно для выполнения. Из-за сложности этого метода jQuery Migrate не пытается заполнить функциональность. Если базовая версия jQuery, используемая с jQuery Migrate, больше не содержит jQuery.holdReady()код, произойдет сбой вскоре после появления этого предупреждения.

Дем Пилафян
источник
17

Чтобы избежать этого предупреждения, не используйте:

async: false

в любом из ваших вызовов $ .ajax (). Это единственная особенность XMLHttpRequest, которая устарела.

По умолчанию

async: true

JQuery устарел синхронный XMLHTTPRequest

Сону К
источник
13

Частичный ответ @Webgr на самом деле помог мне отладить это предупреждение @ консоли журнала, позор другая часть этого ответа принесла так много отрицательных голосов :(

Во всяком случае, вот как я узнал, что послужило причиной этого предупреждения в моем случае:

  1. Используйте Chrome Browser> нажмите F12, чтобы вызвать DevTools
  2. Откройте меню ящика (в Chrome 3 вертикальные точки в правом верхнем углу)
  3. Под Консоль > проверьте Log XMLHttpRequests вариант
  4. Перезагрузите страницу, которая выдает ошибку, и наблюдайте, что происходит с каждым ajax-запросом в журнале консоли.

В моем случае другой плагин загружал 2 библиотеки .js после каждого вызова ajax, которые были абсолютно не нужны и не нужны. Отключение мошеннического плагина удалило предупреждение из журнала. С этого момента вы можете либо попытаться решить проблему самостоятельно (например, ограничить загрузку сценариев определенными страницами или событиями - это слишком специфично для ответа здесь), либо связаться со сторонним разработчиком плагина для его решения.

Надеюсь, это кому-нибудь поможет.

dev101
источник
// , Спасибо за ответ! Этот вопрос относится только к Firefox. Мне интересно увидеть, что это произошло на Chrome. Это только кажется, что удаляет предупреждение, а не исправляет проблему. Это верно?
Натан Басанезе
Похоже, что Chrome имеет более продвинутые возможности в DevTools, чем версия Firefox. Тот факт, что это не сообщается в Firefox, не означает, что его нет. Это полностью исправило мою проблему, а не просто скрыло ее. Я удалил скрипты из проблемного плагина и страницы, которые «перезагружались» при каждом вызове ajax.
dev101
// Как вы думаете, стоит ли поднимать вопрос с разработчиками Firefox?
Натан Басанезе
Нет, не обязательно. Я только что повторно протестировал мой случай с последним Firefox и предупреждением «Synchronous XMLHttpRequest в главном потоке ...», также определенно было сообщено в журнале консоли. Так что, по крайней мере, в моем случае, это не проблема браузера. Теперь, как вы можете использовать Firefox для отладки XMLHttpRequest через вкладку Network, наблюдая за ресурсами .js, вызываемыми после каждого ajax-запроса. Делает то же самое, хотя в Chrome он более оптимизирован / отфильтрован. developer.mozilla.org/en-US/docs/Tools/Network_Monitor
dev101
8

Я смотрел на ответы все впечатляющие. Я думаю, что Он должен предоставить код, который дает ему проблему. Учитывая приведенный ниже пример: если у вас есть скрипт для ссылки на jquery в page.php, вы получите это уведомление.

$().ready(function () {
    $.ajax({url: "page.php",
        type: 'GET',
        success: function (result) {
        $("#page").html(result);
   }});
 });
Йовели Качала
источник
6

Я получаю такое предупреждение в следующем случае:

1) файл1, который содержит <script type="text/javascript" src="/javascript/jquery-1.10.2.js"></script>. Страница имеет поля ввода. Я ввожу какое-то значение в поле ввода и нажимаю кнопку. Jquery отправляет ввод во внешний файл php.

2) внешний файл php также содержит jquery и во внешний файл php я также включен <script type="text/javascript" src="/javascript/jquery-1.10.2.js"></script>. Потому что, если это, я получил предупреждение.

Удалено <script type="text/javascript" src="/javascript/jquery-1.10.2.js"></script>из внешнего php-файла и работает без предупреждения.

Как я понимаю при загрузке первого файла (file1), я загружаюсь, jquery-1.10.2.jsи поскольку страница не перезагружается (она отправляет данные во внешний php-файл с помощью jquery $.post), то jquery-1.10.2.jsпродолжает существовать. Так что нет необходимости снова загружать его.

Андрис
источник
5

Я получил это исключение, когда я установил URL в запросе, например, «example.com/files/text.txt». Я изменил URL на « http://example.com/files/text.txt », и это исключение исчезло.

Radren
источник
Моя проблема также, кажется, связана с URL. Я скопировал скрипт на временный URL для работы над ним, и именно тогда появилась ошибка. Не с оригинального URL.
jeffery_the_wind
5

И я получил это исключение для включения одного скрипта can.js в другой, например,

{{>anotherScript}}
Чарльз Мерриам
источник
Похоже, это основная причина (загрузка дополнительных <scripts> и добавление их в <head> в DOM)
Восстановление Nerdaholic
5

В приложении MVC я получил это предупреждение, потому что я открывал окно Kendo с методом, который возвращал View () вместо PartialView (). View () пытался снова получить все сценарии страницы.

Misi
источник
5

Это происходило со мной в ZF2. Я пытался загрузить модальный контент, но я забыл отключить макет раньше.

Так:

$viewModel = new ViewModel();
$viewModel->setTerminal(true);
return $viewModel;
Рикардо Рувер
источник
5

Как @Nycen, я также получил эту ошибку из-за ссылки на Cloudfare. Мой был для плагина Select2 .

чтобы исправить это я просто удалил

 src="//cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/js/select2.min.js"

и ошибка ушла.

Роквелл Райс
источник
5
  1. В Chrome press F12
  2. Разработка инструментов-> пресс F1.
  3. См. Настройки-> общие-> внешний вид: "Don't show chrome Data Saver warning"- установите этот флажок.
  4. Смотрите настройки-> общие-> Консоль: "Log XMLHTTPRequest"- установите этот флажок тоже.

наслаждаться

Webgr
источник
4

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

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

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

NB: это копия моего ответа на эту тему. Синхронное предупреждение XMLHttpRequest и <script> (я посетил оба, когда искал решение)

Nycen
источник
3

Я исправил это с помощью следующих шагов:

  1. Проверьте свои сценарии CDN и добавьте их локально.
  2. Переместите ваши скрипты, включенные в заголовок раздела.
mzonerz
источник
3

В моем конкретном случае я рендерил частичку Rails, без render layout: falseкоторой заново рендеринг всего макета, включая все скрипты в <head>теге. Добавление render layout: falseв контроллер действия исправило проблему.

дпс
источник
3

Для меня проблема заключалась в том, что в запросе OK я ожидал, что ответ ajax будет хорошо отформатированной строкой HTML, такой как таблица, но в этом случае на сервере возникла проблема с запросом, перенаправляющая на страницу ошибки, и поэтому возвращал обратно HTML-код страницы с ошибкой (где-то был <scriptтег. Я консоль записал ответ ajax, и тогда я понял, что это не то, чего я ожидал, а затем приступил к отладке.

gthuo
источник
2

Вопрос был поднят в 2014 году, и сейчас 2019 год, поэтому я думаю, что лучше искать лучший вариант.

Вы можете просто использовать fetchAPI в Javascript, что обеспечивает большую гибкость.

например, посмотрите этот код

fetch('./api/some.json')
    .then((response) => {
        response.json().then((data) => { 
            ... 
        });
    })
    .catch((err) => { ... });
Анирудха Гупта
источник
это чистый JS, плагин не требуется?
Alok
1
@Alok Да, пожалуйста, посмотрите этот developer.google.com/web/updates/2015/03/introduction-to-fetch
Анирудха Гупта