Synchronous Xmlhttprequest error on the main thread is deprecated

Asked

Viewed 16,671 times

7

When I use this code in my file, an error occurs in the log, and ends up giving problems in other javascript calls.

Current page file (the problem javascript is at the end):

<html>
<head>

  <script src="../../assets/js/common-scripts.js"></script>
  <script type="text/javascript">
    $(document).ready(
      $.ajax('indicadores.php?id_indicador=1').done(function(data) {
        $("#collapse1").html(data);
      });
    );
  </script>

</head>

  <body>

  <section id="container" >
    <section id="main-content">
      <section class="wrapper">
        <div class="row">
          <div class="col-lg-12 main-chart">
            <h3 class="text-center"><i class="fa fa-bar-chart-o"></i> Indicadores</h3>
            <div class="panel-group" id="accordion">
              <div class="panel panel-default">
               <div class="panel-heading">
                  <h4 class="panel-title">
                    <a data-toggle="collapse" data-parent="#accordion" href="#collapse1" id="collapse11">Teste</a>
                  </h4>
                </div>
                <div id="collapse1" class="panel-collapse collapse active">
                <!-- Carrega conteúdo do arquivo pa_nr_atendimentos.php através de Javascript-->
                </div>
              </div>      
            </div> 
          </div>
        </div>
      </section>
    </section>
  </section>

  </body>
</html>

The last script calls the content that is in the file indicadores.php:

<!--Com esta chamada apresenta o erro citado. Se eu tirar não apresenta o erro, porém, o conteúdo abaixo sai desconfigurado pela falta do arquivo.-->
  <script src="../../assets/js/common-scripts.js"></script>

  <div class="panel-body">
    <div class="row mt">
      <!--AQUI HTML COM GRÁFICOS QUE SE BASEIAM NO ARQUIVO COMMOM-SCRIPTS.JS-->
    </div> 
  </div>

CONSOLE ERROR:

Synchronous Xmlhttprequest on the main thread is deprecated because of its detrimental effects to the end user’s Experience. For more help, check http://xhr.spec.whatwg.org/.

This occurs when I upload the content present on the page indicadores.php through an asynchronous ajax call, executed on the current page. Does anyone know how to resolve?

Contents of common-scripts.js: http://fiddle.jshell.net/tamh2mo5/:

/*---LEFT BAR ACCORDION----*/
$(function() {
    $('#nav-accordion').dcAccordion({
        eventType: 'click',
        autoClose: true,
        saveState: true,
        disableLink: true,
        speed: 'slow',
        showCount: false,
        autoExpand: true,
//        cookie: 'dcjq-accordion-1',
        classExpand: 'dcjq-current-parent'
    });
});

var Script = function () {


//    sidebar dropdown menu auto scrolling

    jQuery('#sidebar .sub-menu > a').click(function () {
        var o = ($(this).offset());
        diff = 250 - o.top;
        if(diff>0)
            $("#sidebar").scrollTo("-="+Math.abs(diff),500);
        else
            $("#sidebar").scrollTo("+="+Math.abs(diff),500);
    });



//    sidebar toggle

    $(function() {
        function responsiveView() {
            var wSize = $(window).width();
            if (wSize <= 768) {
                $('#container').addClass('sidebar-close');
                $('#sidebar > ul').hide();
            }

            if (wSize > 768) {
                $('#container').removeClass('sidebar-close');
                $('#sidebar > ul').show();
            }
        }
        $(window).on('load', responsiveView);
        $(window).on('resize', responsiveView);
    });

    $('.fa-bars').click(function () {
        if ($('#sidebar > ul').is(":visible") === true) {
            $('#main-content').css({
                'margin-left': '0px'
            });
            $('#sidebar').css({
                'margin-left': '-210px'
            });
            $('#sidebar > ul').hide();
            $("#container").addClass("sidebar-closed");
        } else {
            $('#main-content').css({
                'margin-left': '210px'
            });
            $('#sidebar > ul').show();
            $('#sidebar').css({
                'margin-left': '0'
            });
            $("#container").removeClass("sidebar-closed");
        }
    });

// custom scrollbar
    $("#sidebar").niceScroll({styler:"fb",cursorcolor:"#4ECDC4", cursorwidth: '3', cursorborderradius: '10px', background: '#404040', spacebarenabled:false, cursorborder: ''});

    $("html").niceScroll({styler:"fb",cursorcolor:"#4ECDC4", cursorwidth: '6', cursorborderradius: '10px', background: '#404040', spacebarenabled:false,  cursorborder: '', zindex: '1000'});

// widget tools

    jQuery('.panel .tools .fa-chevron-down').click(function () {
        var el = jQuery(this).parents(".panel").children(".panel-body");
        if (jQuery(this).hasClass("fa-chevron-down")) {
            jQuery(this).removeClass("fa-chevron-down").addClass("fa-chevron-up");
            el.slideUp(200);
        } else {
            jQuery(this).removeClass("fa-chevron-up").addClass("fa-chevron-down");
            el.slideDown(200);
        }
    });

    jQuery('.panel .tools .fa-times').click(function () {
        jQuery(this).parents(".panel").parent().remove();
    });


//    tool tips

    $('.tooltips').tooltip();

//    popovers

    $('.popovers').popover();



// custom bar chart

    if ($(".custom-bar-chart")) {
        $(".bar").each(function () {
            var i = $(this).find(".value").html();
            $(this).find(".value").html("");
            $(this).find(".value").animate({
                height: i
            }, 2000)
        })
    }


}();

With common-scripts.js in the.php indicators file: inserir a descrição da imagem aqui No common-scripts.js in.Pho indicators file: inserir a descrição da imagem aqui

This occurs even though common-scripts.js has already been loaded previously on the current page.

Version of jQuery: 1.8.3

  • I think it has something to do with this async - true. But I couldn’t fix it. Any hints?

  • It doesn’t seem that Warning is coming from this question snippet, since jQuery never does synchronous requests by default. This alert is displayed when an Xmlhttprequest request is opened with the parameter async as false, example (see the alert on the console).

  • And how could I solve it? You would know to help me?

  • The first step would be to identify which script is making the synchronous ajax call

  • I can identify it is at the moment it calls 'load' as quoted in the question. Because if I take this code works correctly.

  • I know the error occurs when the jquery 'load' method occurs

  • I found this post: http://tedk.com.br/blog/html/carregar-uma-pagina-dentro-de-umadiv-com-ajax/ maybe you have something that can help solve the problem, however, I do not know how to apply in my code

  • On that page indicadores.php does another request (via Ajax)? I’m pretty sure it’s conflicting with another request.

  • there is an error on the.php indicator page if you leave this request: <script src=".. /.. /Assets/js/common-scripts.js"></script>. If you take this line it works perfectly

  • The problem is that if I take it out the contents I’m carrying disfigure.

  • Duplicate question http://answall.com/questions/48011/nos-newbrowsers-agora-n%C3%A3o-haver%C3%A1-mais-requisi%C3%A7%C3%B5es-s%C3%Adncronas

  • @Wallacemaxters I don’t think it’s duplicated this one, because the problem is with using Ajax, although both are the same problem, the solution in the question you linked will not help solve the problem that should actually be solved with jQuery (for example using the $.ajaxSetup). I believe they are related but not duplicated :)

  • @Wallacemaxters I don’t think so. Your question is about the theoretical aspect, it’s about the prohibition of synchronous AJAX itself. There you are asking if you should change the way of programming, but you have not addressed there how to identify the points that the synchronous AJAX occurs and nor how to eliminate them after identified, which is what occurs in this question here.

  • Okay, you guys, let’s go. ;)

  • @Rodrigosegatto leaves this inclusion <script src="../../assets/js/common-scripts.js"></script> on the page where you load. And remove indicadores.php

  • I have it on the page where you load, but after loading the content of.php indicators it’s like it’s gone and I need to load it again there

  • I don’t quite understand? After all, what do you use this for?

  • It’s from the template I downloaded. It makes some graphics work on the screen. On the page where you load has already loaded the JS file, but if I do not also click on indicators.php charts stop working

  • Test in an older browser. Chrome version 20, IE10, etc. I think jQuery is using some Xmlhttprequest function that is no longer supported. If it functions in an older browser, it must be the cause.

  • In older browser worked. I do not know what can be

  • 1

    I did not understand the reason of the Graphs in relation to doubt, something else your code can not be reproduced, you put the How-js, but did not put the jquery in your html, this gives to understand that this is not your code that is with problem, since if you didn’t include jquery.js the problem would be another in javascript execution.

  • Dude I have the same problem. Managed to solve ?

Show 17 more comments

4 answers

9

1. Asynchronous AJAX

What you are using (through the method .load) is synchronous AJAX. Instead, use asynchronous AJAX like this:

$.ajax("indicadores.php?id_indicador=2").done(function(data) {
    $("#collapse1").html(data);
});

Note that there are some differences:

  • In synchronous AJAX, which is what the .load does, the page will freeze completely, while a request is sent to the server and will only defrost after receiving the response from the server. While the browser waits for the server to respond, the page becomes completely frozen and dead, which is bad for the user experience, especially if the server response takes a while to load.

  • In asynchronous AJAX, the execution continues soon after as if nothing had happened and the body of the callback in the .done will only be executed well after.

Thus this synchronous code:

alert("Antes");
$("#collapse1").load('indicadores.php?id_indicador=2');
alert("Depois");

The user will see Alert Antes, the frozen page, downloaded content from the server will appear and finally Alert Depois. In this order.

This is different from what happens with this asynchronous code:

alert("Antes");
$.ajax("indicadores.php?id_indicador=2").done(function(data) {
    alert("Surpresa");
    $("#collapse1").html(data);
});
alert("Depois");

The user will see Alert Antes and the Alert Depois soon after. The page will be running normally for a short time, when suddenly Alert Surpresa appears and the dynamic content of the server appears.

So be careful if you have it:

$("#collapse1").load('indicadores.php?id_indicador=2');
var x = xpto($("#collapse1"));
var y = blabla(x);

'Cause this ain’t gonna work:

$.ajax("indicadores.php?id_indicador=2").done(function(data) {
    $("#collapse1").html(data);
});
var x = xpto($("#collapse1"));
var y = blabla(x);

And what you’re gonna have to use is this:

$.ajax("indicadores.php?id_indicador=2").done(function(data) {
    $("#collapse1").html(data);
    var x = xpto($("#collapse1"));
    var y = blabla(x);
});

2. Tags <script> in the <body>

The tags <script> attribute-ridden src within the <body> can also cause problems (if you are inside the <head> no problem). The reason is that in the middle of loading the page, when the page has already rendered in half, the browser is forced to stop and download a script from the server, causing the same problem of synchronous AJAX.

For example, see this example. There are three tags <script>. Two of them are ok, while one causes this problem:

<html>
    <head>
        <title>Título da página</title>

        <!--
            Esta tag <script> está ok, pois não está no <body>, e sim no <head>.
            Neste momento, o navegador ainda não começou a carregar a página propriamente
            dita, ele está apenas baixando os recursos necessários para fazer isso.
        -->
        <script type="text/javascript" src="xpto1.js"></script>
    </head>
    <body>
        <p>Lorem ipsum dolor sit amet</p>

        <!--
            Esta tag <script> também está ok, pois não usa o atributo src.
            O javascript já está aqui, e portanto o navegador não vai precisar abrir uma
            nova requisição para baixá-lo.
        -->
        <script type="text/javascript">
            alert("script 2");
        </script>

        <p>Consectetuer adispiting elit</p>

        <!--
            Esta tag <script> é um problema!
            Ela vai forçar o navegador a parar o carregamento da página na metade para
            carregar o script do servidor.
        -->
        <script type="text/javascript" src="xpto2.js"></script>

        <p>Lorem ipsum dolor sit amet</p>
    </body>
</html>

And if within this page I download, via asynchronous AJAX, the indicadores.php with HTML code?

First of all, this HTML code will only be a fragment of an HTML, not a complete HTML (see more below about this). So let’s assume that the HTML fragment looks like this:

<div>
    <span>Lorem ipsum dolor sit amet</span>
    <script type="text/javascript" src="xpto3.js"></script>
    <span>Consectetuer adispiting elit</span>
</div>

In this case, the <script> that it’s there will get you into trouble. Because the browser will download this HTML asynchronously (so far so good) and then you will have to download the javascript synchronously, and then we will have the problem.

One way to solve this is to download this other code also asynchronously:

<div>
    <span>Lorem ipsum dolor sit amet</span>
    <script type="text/javascript">
        $.ajax("xpto3.js").done(function(data) {
            eval(data);
        });
    </script>
    <span>Consectetuer adispiting elit</span>
</div>

And that should solve the problem. However, it may not be the best solution yet, because we will still be making two AJAX requests to the server to download the content, and we could use only one. In this case, the solution would be to use a server-side include (note the inline PHP code):

<div>
    <span>Lorem ipsum dolor sit amet</span>
    <script type="text/javascript">
        <!-- O arquivo PHP incluído abaixo contém/gera código javascript. -->
        <?php include 'xpto3.php'; ?>
    </script>
    <span>Consectetuer adispiting elit</span>
</div>

And also worth mentioning that loading Java into HTML snippets brought by AJAX can be a bit strange. Maybe it’s best to simply include all the necessary Avascripts in <head> from the main page, especially if it’s static content like this from here:

<!-- Deve ser colocado dentro do <head>. -->
<script src="../../assets/js/common-scripts.js"></script>

3. And if the fragment is a complete HTML?

Let’s assume that what you download by AJAX is this:

<html>
<head>
  <!--Com esta chamada apresenta o erro citado. Se eu tirar não apresenta o erro, porém, o conteúdo abaixo sai desconfigurado pela falta do arquivo.-->
  <script src="../../assets/js/common-scripts.js"></script>

</head>
<body>
  <div class="panel-body">
    <div class="row mt">
      <!--AQUI HTML COM GRÁFICOS QUE SE BASEIAM NO ARQUIVO COMMOM-SCRIPTS.JS-->
    </div> 
  </div>
</body>
</html>

This is not a good idea, because your HTML at the end of the upload would look like this:

<html>
<head>

  <script src="../../assets/js/common-scripts.js"></script>

</head>

  <body>

  <section id="container" >
    <section id="main-content">
      <section class="wrapper">
        <div class="row">
          <div class="col-lg-12 main-chart">
            <h3 class="text-center"><i class="fa fa-bar-chart-o"></i> Indicadores</h3>
            <div class="panel-group" id="accordion">
              <div class="panel panel-default">
               <div class="panel-heading">
                  <h4 class="panel-title">
                    <a data-toggle="collapse" data-parent="#accordion" href="#collapse1" id="collapse11">Teste</a>
                  </h4>
                </div>
                <div id="collapse1" class="panel-collapse collapse active">
<html>
<head>
  <!--Com esta chamada apresenta o erro citado. Se eu tirar não apresenta o erro, porém, o conteúdo abaixo sai desconfigurado pela falta do arquivo.-->
  <script src="../../assets/js/common-scripts.js"></script>

</head>
<body>
  <div class="panel-body">
    <div class="row mt">
      <!--AQUI HTML COM GRÁFICOS QUE SE BASEIAM NO ARQUIVO COMMOM-SCRIPTS.JS-->
    </div> 
  </div>
</body>
</html>
                </div>
              </div>      
            </div> 
          </div>
        </div>
      </section>
    </section>
  </section>

  </body>
</html>

<script type="text/javascript">
  $.ajax('indicadores.php?id_indicador=1').done(function(data) {
    $("#collapse1"+).html(data);
  });
</script>

Note that we have twice the tag <html>, what is illegal (the second tag <html> is inside the <body>), and we are also importing twice the same javascript, which is also not a good idea. Also, the error will return because the <script> of the downloaded page, although it is inside the <head> of this page, is also inside the <body> from the external page. It is not allowed in <html> if you have one page inside the other in this way.

The best thing in this case would be to force the upload to be just a chunk of HTML. One way to do this is to turn the second page into just that:

  <div class="panel-body">
    <div class="row mt">
      <!--AQUI HTML COM GRÁFICOS QUE SE BASEIAM NO ARQUIVO COMMOM-SCRIPTS.JS-->
    </div> 
  </div>

Note that there is nothing of <html>, nor of <head>, nor of <body> nor <script> in this, because it is a fragment of HTML, not a complete HTML. These things that are not on this internal page already exist on the external page and therefore not only are not needed on the internal page, but putting them there is a violation of the HTML standard.

4. Where to tag <script>?

There is another important HTML breach: You should NEVER have ANYTHING after the closing tag </html>. However, you put a <script> there, after the </html>. This is absolutely illegal in the HTML standard (but the browser wants to be nice and tolerates these things). The correct thing is to try to put the scripts in the <head> whenever possible:

<html>
<head>

  <script src="../../assets/js/common-scripts.js"></script>

  <script type="text/javascript">
    $(document).ready(function() {
      $.ajax('indicadores.php?id_indicador=1').done(function(data) {
        $("#collapse1").html(data);
      });
    });
  </script>

</head>

  <body>

  <section id="container" >
    <section id="main-content">
      <section class="wrapper">
        <div class="row">
          <div class="col-lg-12 main-chart">
            <h3 class="text-center"><i class="fa fa-bar-chart-o"></i> Indicadores</h3>
            <div class="panel-group" id="accordion">
              <div class="panel panel-default">
               <div class="panel-heading">
                  <h4 class="panel-title">
                    <a data-toggle="collapse" data-parent="#accordion" href="#collapse1" id="collapse11">Teste</a>
                  </h4>
                </div>
                <div id="collapse1" class="panel-collapse collapse active">
                <!-- Carrega conteúdo do arquivo pa_nr_atendimentos.php através de Javascript-->
                </div>
              </div>      
            </div> 
          </div>
        </div>
      </section>
    </section>
  </section>

  </body>
</html>

Or, if you can’t do that, put at the end of the <body>, but within it:

<html>
<head>

  <script src="../../assets/js/common-scripts.js"></script>

</head>

  <body>

  <section id="container" >
    <section id="main-content">
      <section class="wrapper">
        <div class="row">
          <div class="col-lg-12 main-chart">
            <h3 class="text-center"><i class="fa fa-bar-chart-o"></i> Indicadores</h3>
            <div class="panel-group" id="accordion">
              <div class="panel panel-default">
               <div class="panel-heading">
                  <h4 class="panel-title">
                    <a data-toggle="collapse" data-parent="#accordion" href="#collapse1" id="collapse11">Teste</a>
                  </h4>
                </div>
                <div id="collapse1" class="panel-collapse collapse active">
                <!-- Carrega conteúdo do arquivo pa_nr_atendimentos.php através de Javascript-->
                </div>
              </div>      
            </div> 
          </div>
        </div>
      </section>
    </section>
  </section>

  <script type="text/javascript">
    $(document).ready(function() {
      $.ajax('indicadores.php?id_indicador=1').done(function(data) {
        $("#collapse1").html(data);
      });
    });
  </script>

  </body>
</html>

And finally, note that I took the + what was in it:

<script type="text/javascript">
  $.ajax('indicadores.php?id_indicador=1').done(function(data) {
    $("#collapse1"+).html(data); // <-- Tire esse + daqui!
  });
</script>

For that + leftover will cause a syntax error in javascript!

5. Some rules about the structure of an HTML page

Remember these golden rules below. They should NEVER be violated:

  • Page should have one and only one element <html>. Not allowed to have an element <html> within the other even if it is indirectly.
  • The element <html> can only have one, and only one <head> within it.
  • The element <html> can only have one, and only one <body> within it.
  • The element <html> can have nothing more than the elements <head> and <body> within it.
  • The element <head> must be before the <body>.
  • There should be nothing between the opening tag <html> and the opening tag <head>.
  • There should be nothing between the closing tag </head> and the opening tag <body>.
  • There should be nothing between the closing tag </body> and the closing tag </html>.
  • The only thing that can appear before the tag <html> is the doctype. In the case of HTML5, this is: <!DOCTYPE html>.
  • Nothing should appear after the </html>.

3

Try it like this, and see if it solves your problem:

<script type="text/javascript">
$(function(){
    $("#collapse1").load('indicadores.php?id_indicador=2');
});
</script>

Obs: jquery does not load events if there is no autoload before.

See a working example

EDITED: from here down, due to the issue of the question:

Even doing it the way you did, it’s still wrong, the right thing would be:

$(document).ready(function() {
       $.ajax('indicadores.php?id_indicador=1').done(function(data) {
             $("#collapse1").html(data);
       });
});

Note that in your ready you are not loading an anonymous function.

  • So it was before I edit the question. I just changed by the staff tips here. hehe

  • @Rodrigosegatto, you’re trying to execute your method, only the way you did, it got indirect on .ready(...), ready will not work if you do not pass a value, variable, method or event.

  • 2

    @Rodrigosegatto, you need to think and know what you need in your code, if you keep editing your question even without having a final solution to your problem, you will make it even more difficult for people to help you and present a solution to the problem.

1

@Rodrigosegatto

DOM handlers on newer versions of browsers are no longer supporting synchronous calls. That’s exactly what he’s returning to you.

Certainly, the jQuery 1.8 library should still use some method already obsolete and no longer supported. As you yourself tested and commented, in older browsers it works.

Try updating to the jQuery 1.11.3 (since it is version 1.x, you should not have problems with Breaking changes), I believe you should solve the problem for newer browser.

UPDATE:

Try another syntax, maybe?

$(function() {
    $.ajax({
        url: 'indicadores.php?id_indicador=1',
        type: 'GET',
        success: function(data) {
            $("#collapse1").html(data);
        }
    });
});
  • It did not work Thiago. It continued working everything, but in the console follows the same message.

  • @Rodrigosegatto, I did an update.

0

I had the same problem, and with it my page recharged without my request. entered the code below and solved the Reload problem.

e.stopPropagation();
return false;

Follow an example below:

var saveUsuario = function (objUsuario) {
        $.ajax({
            method: 'GET',
            dataType: 'json',
            contentType: "application/json; charset=utf-8",
            url: "/minhaURL",
            success: function (result) {            },
            error: function (resultErro) {           }
        });
     e.stopPropagation();
     return false;
    };

Browser other questions tagged

You are not signed in. Login or sign up in order to post.