Ajax request to return Forbidden error 403?

Asked

Viewed 1,373 times

3

I have the following code on my website.

setInterval(function(){
    var id = $("#id_radio").val();
    var id_glob;
    $.ajax({
        type: "POST",
        url: "ajax/update_radio.php",
        data: "id="+id,
        success:function(e){
            $("#nome_radio").removeClass("ellipsis");
            $("#hora_radio").removeClass("ellipsis");
            if(e!==""){
                var expl = e.split(",");
                var id_glob = expl[3];
                if(expl[3] !== id){
                $("#img_radio").animate({
                    opacity: 0
                }, 300);
                setTimeout(function(){
                    $("#img_radio").attr("src", "radio/programas/"+expl[3]+"/"+expl[0]);
                    $("#img_radio").css("width", "100%");
                }, 300)
                setTimeout(function(){
                    $("#img_radio").animate({
                        opacity: 1
                    }, 300);
                }, 300)
                $("#nome_radio").html(expl[1]);
                $(".programa_radio").html(expl[1]);
                $(".horario_radio").html(expl[2]);
                $("#hora_radio").html(expl[2]);
                $("#id_radio").val(expl[3]);
                $("#pub_radio").animate({
                    opacity: 0
                }, 300);
                setTimeout(function(){
                    $("#pub_radio").attr("src", "adm/images/publicidades/"+expl[5]+"/"+expl[6]);
                    $("#pub_radio").css("max-width", "100%");
                }, 300)
                setTimeout(function(){
                    $("#pub_radio").animate({
                        opacity: 1
                    }, 300);
                }, 300)
                    $.ajax({
                        type: "POST",
                        url: "ajax/update_pub_radio.php",
                        data: "id="+$("#id_radio").val(),
                        success: function(t){
                             $(".carousel_imgs").animate({
                                opacity: 0
                            }, 300);
                            setTimeout(function(){
                                $(".carousel_imgs").html(t);
                            }, 300)
                            setTimeout(function(){
                                $(".carousel_imgs").animate({
                                    opacity: 1
                                }, 300);
                            }, 300)
                        }
                    })
                }
            }
        }
    });

}, 1000);

With this code he updates the current radio program every second but after a while an error starts to appear on the console (403 Forbidden). I have the exact same code on another website and it works perfectly.

And besides giving 403 error on the console, the whole site gets Forbidden 403 until after a few seconds.

Something’s wrong with me?

  • Look at the guy POST you are trying to send a type variable GET, "id="+id. If you intend to send via post try to send so: data: { id: id }, don’t forget the dataType: 'json'

  • It has nothing to do with the code Javascript. https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/403

  • @Valdeirpsr But the request is made through this code so there must be something I can do.

  • @I_like_trains Already tried to simulate requests with Curl or Postman and ascertain the outcome?

  • @Valdeirpsr No, you can create an example of how to do it?

  • I made a .sh basic good (and not tested) https://hastebin.com/jihalutuha.bash

  • 1

    You are sending a request every second to the server, even if you do not receive the reply you send another one right away. Maybe it’s best to change the way you update the data. What can happen is you are filling the server with requests and after a while it "hangs". Believe me, even being light data has server that is worth nothing.

Show 2 more comments

2 answers

6


It’s like I told reply from @Henrique Pauli, but I think one can go deeper into the problem and still make some observations in the code.

The problem of setInterval:

The setInterval never should be used to make Ajax requests at intervals of time. As the above-mentioned response suggests, setInteval does not have any sync with Ajax, IE, Ajax depends on the return of the request, while the timer setInterval will be processed at each interval reported (in your case, 1 second) firing the Ajax once after another in a very short interval, without waiting or wondering if the previous request has been completed. The result of this is overload of the server and the browser, causing crashes in the browser, as it will create a bottleneck for much information in the processing queue, a behavior very similar to an infinite loop, which completely locks the system.

In view of this, possibly the 403 error is due to the excess of requests in short intervals of time and/or the overload of the server. With this, as a way to defend against abuse, the server may be temporarily suspending access, hence error 403.

Interval of 1 second

Even with the fixes, I believe that 1 second is still a very short interval to send requests in a row, but if the server can handle this volume, then fine.

Redundancy in the code

I also notice some redundancies in code that could make your code a little lighter:

1) 4 setTimeouts with the same time in the first Ajax and 2 in the second. Ex.:

setTimeout(function () {
    $(".carousel_imgs").html(t);
}, 300)
setTimeout(function () {
    $(".carousel_imgs").animate({
        opacity: 1
    }, 300);
}, 300)

When it could be 1 setTimeout only:

setTimeout(function () {
    $(".carousel_imgs")
   .html(t)
   .animate({
        opacity: 1
    }, 300);
}, 300)

2) Identical amendments separately. Ex.:

$("#nome_radio").removeClass("ellipsis");
$("#hora_radio").removeClass("ellipsis");

When it could reduce this way below, since both elements will lose the class .ellipsis at the same time:

$("#nome_radio, #hora_radio").removeClass("ellipsis");

Calling again the function raDio() after the Ajax:

As you are using two nested Ajax, the logic would be:

If the first Ajax work out (success), call the second. But if he go wrong (error), call the function again after 1 second.

If the first worked out (success), will call the second, but in the second you should use the callback complete to start all over again after 1 second. Why complete? Because regardless of whether an error occurred or not in this second Ajax, you will want to start the function again. The complete is always called, whether it was wrong or not.

In all cases, as suggested by the other reply, you will use the setTimeout in those callbacks.

Explanations completed, see how the organized code would look:

function raDio(){
   var id = $("#id_radio").val();
   var id_glob;
   $.ajax({
      type: "POST",
      url: "ajax/update_radio.php",
      data: "id="+id,
      success:function(e){
         $("#nome_radio, #hora_radio").removeClass("ellipsis");
         if(e!==""){
            var expl = e.split(",");
            var id_glob = expl[3];
            if(expl[3] !== id){
               $("#img_radio").animate({
                  opacity: 0
               }, 300);

               setTimeout(function(){
                  $("#img_radio")
                  .attr("src", "radio/programas/"+expl[3]+"/"+expl[0])
                  .css("width", "100%")
                  .animate({
                     opacity: 1
                  }, 300);

                  $("#pub_radio")
                  .attr("src", "adm/images/publicidades/"+expl[5]+"/"+expl[6])
                  .css("max-width", "100%")
                  .animate({
                     opacity: 1
                  }, 300);
               }, 300)

               $("#nome_radio, .programa_radio").html(expl[1]);
               $(".horario_radio, #hora_radio").html(expl[2]);
               $("#id_radio").val(expl[3]);
               $("#pub_radio").animate({
                  opacity: 0
               }, 300);

               $.ajax({
                  type: "POST",
                  url: "ajax/update_pub_radio.php",
                  data: "id="+$("#id_radio").val(),
                  success: function(t){
                     $(".carousel_imgs").animate({
                        opacity: 0
                     }, 300);
                     setTimeout(function(){
                        $(".carousel_imgs")
                        .html(t)
                        .animate({
                           opacity: 1
                        }, 300);
                     }, 300);
                  },
                  complete: function(){
                     setTimeout(raDio, 1000); // chama a função
                  }
               });
            }
         }
      },
      error: function(){
         setTimeout(raDio, 1000); // chama a função se deu erro
      }
   });
}

$(document).ready(raDio); // chama a função após o carregamento do DOM
  • Perfect! I used your code and it worked but however another problem appeared but I managed to solve. The site I’m working on was made by another programmer and is all with mysql while the code of the ajax was all in mysqli

  • But now that I realized, it didn’t quite happen what I wanted, because the goal was for him to see the current time and compare it with the time of the programs in the database and see which one was on schedule. With this code he only sees when the page loads

  • I used a setInterval but this time I put to update every 5 seconds and it works beautifully. It seems the server did not allow so many requests

2

As I said in my comment I think the problem is that you are sending too many requests to the server. Imagine the following:

Every second you send a request, if one of them takes more than 1 second to answer you will send another one on top of it. Soon you have a cascade waiting for answer and locks everything.

What you can do to try to mitigate this is send the request 1 second AFTER it’s all over. Something like:

function atualizarRadio() {
    var id = $("#id_radio").val();
    var id_glob;
    $.ajax({
        type: "POST",
        url: "ajax/update_radio.php",
        data: "id=" + id,
        success: function (e) {
            $("#nome_radio").removeClass("ellipsis");
            $("#hora_radio").removeClass("ellipsis");
            if (e !== "") {
                var expl = e.split(",");
                var id_glob = expl[3];
                if (expl[3] !== id) {
                    $("#img_radio").animate({
                        opacity: 0
                    }, 300);
                    setTimeout(function () {
                        $("#img_radio").attr("src", "radio/programas/" + expl[3] + "/" + expl[0]);
                        $("#img_radio").css("width", "100%");
                    }, 300)
                    setTimeout(function () {
                        $("#img_radio").animate({
                            opacity: 1
                        }, 300);
                    }, 300)
                    $("#nome_radio").html(expl[1]);
                    $(".programa_radio").html(expl[1]);
                    $(".horario_radio").html(expl[2]);
                    $("#hora_radio").html(expl[2]);
                    $("#id_radio").val(expl[3]);
                    $("#pub_radio").animate({
                        opacity: 0
                    }, 300);
                    setTimeout(function () {
                        $("#pub_radio").attr("src", "adm/images/publicidades/" + expl[5] + "/" + expl[6]);
                        $("#pub_radio").css("max-width", "100%");
                    }, 300)
                    setTimeout(function () {
                        $("#pub_radio").animate({
                            opacity: 1
                        }, 300);
                    }, 300)
                    $.ajax({
                        type: "POST",
                        url: "ajax/update_pub_radio.php",
                        data: "id=" + $("#id_radio").val(),
                        success: function (t) {
                            $(".carousel_imgs").animate({
                                opacity: 0
                            }, 300);
                            setTimeout(function () {
                                $(".carousel_imgs").html(t);
                            }, 300)
                            setTimeout(function () {
                                $(".carousel_imgs").animate({
                                    opacity: 1
                                }, 300);
                            }, 300)
                            setTimeout(atualizarRadio,1000); // Terminou tudo, reiniciar.
                        }
                    })
                }else setTimeout(atualizarRadio,1000); // Não chegou ao fim mas precisa reiniciar.
            }else setTimeout(atualizarRadio,1000); // Não chegou ao fim mas precisa reiniciar.
        }
    });
}
atualizarRadio();

NOTE: I edited your code a little to not use interval and become a function. I don’t have access to your data so only you can test. I hope it helps at least to shed light on your problem.

Browser other questions tagged

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