Continuous DB calls with AJAX in straight JS - javascript

This is my first question here so I will start by saying: Hello to everyone!
I am trying to make a live data "presentation" in the form of a fancy table using straight JavaScript and Ajax, backend is PHP. In order to refresh the table I need to make requests at every, lets say 3 seconds, 4 is ok to. The database is RedisDB. I made the php script to fetch the data and its ok. I made a single JS file to request and handle/process the data and it's sort of ok.
The presentation looks great and the algorithm that is written in JS works excellent, it's about 600 lines, some simple if-else's and switches other a little more complex.
It now gets nasty. I can't get the freaking thing to do this continuously, I tried ways with setTimeout() and setInterval(), I made timers and infinite loops with sleep-like functions and so on, but it just can't survive that next request after the initial when the page loads.
The code for Ajax request is pretty straightforward for pure JS. I get my JSON string data parse it with jsonParse() and then do my processing of the data.
This all works, it's the next request that fails, no matter how it's initiated (user action or something else).
AJAX code:
window.onload = function(){
getEventdataFromDB();
}
function getEventdataFromDB(){
var xmlhttp;
if(window.XMLHttpRequest){
xmlhttp = new XMLHttpRequest();
}else{
xmlhttp = new ActiveXObject('Microsoft.XMLHTTP');
}
xmlhttp.onreadystatechange = function(){
if(xmlhttp.readyState == 4 && xmlhttp.status == 200){
var dbData = xmlhttp.responseText;
if(dbData != ''){
processEvents(dbData); //function for data processing
}
}
}
xmlhttp.open('GET','getEvents.php?dataRequest=true',true);
xmlhttp.send();
}
I know that it's a bit of a sin these days not to follow the flow and use jQuery and other frameworks but I'm just not big on the latest and greatest simplification of stuff that works just fine, to begin with.
What is the best way to do this, how should I proceed, what to use. I did some researched and things point to chaining callbacks and Promise objects.
There is obviously no way that I am the first one to do this so what is the way forward here.

The only way to ensure the previous request is over before starting the next one is so start the next call from the onreadystatechanged event of the previous one. Because ajax runs asynchronously, there's no guarantee whether any other code you run will execute before or after the ajax call finishes.
So you need to re-organise your script a bit:
var xmlhttp;
window.onload = function(){
setupAjaxObject();
getEventdataFromDB();
}
function setupAjaxObject()
{
if(window.XMLHttpRequest){
xmlhttp = new XMLHttpRequest();
}else{
xmlhttp = new ActiveXObject('Microsoft.XMLHTTP');
}
xmlhttp.onreadystatechange = function(){
if(xmlhttp.readyState == 4){
if(xmlhttp.status == 200){
var dbData = xmlhttp.responseText;
if(dbData != ''){
processEvents(dbData); //function for data processing
}
}
getEventdataFromDB(); //run the next request
}
}
}
function getEventdataFromDB(){
xmlhttp.open('GET','getEvents.php?dataRequest=true',true);
xmlhttp.send();
}
If you wanted a little delay between the requests, you could wrap the call to the next request inside a timeout.

Related

Adblocker blocks XMLHttpRequest

I understand the fact, that adblockers try to deny loading (image) data later on. Anyway, I want to send some data to a php script (/log.php) to save it in a sql database. So in fact I don't care about the responsetext. This is my current js function I use to call the php script:
function log(id, unix_ms, frameid, eventtype, targetid, value){
var parameters = "";
parameters = parameters.concat("id=", encodeURI(id), "&unix_ms=", encodeURI(unix_ms), "&frameid=", encodeURI(frameid), "&eventtype=", eventtype, "&targetid=", targetid, "&value=", value);
var httprequest = new XMLHttpRequest();
httprequest.open("POST", "/scripts/log.php", true);
httprequest.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
httprequest.onreadystatechange = function() {
if(httprequest.readyState == 4 && http.status == 200) {
console.log(httprequest.responseText);
}
}
httprequest.send(parameters);
}
What can I change to pass the adblocker? I mean facebook uses things like ajax in masses to load text and even images in the timeline.
Is there maybe a way to use frames in the background since I don't care about the answer?
After analysing the log as suggested in a comment I found out that log.php seems to be in the blocklist, even if it's on the same server. So name you php files a little more complex to avoid this.
log.php -> submitlog.php

Ajax & JavaScript | Limiting requests triggered by user

I am currently playing around with some Ajax code. I have come up with this scenario to try and mirror my problem to see if you, experts, can present a solution, thanks.
Scenario:
I have a HTML button like so: <p onclick="ajax_call();">Click</p>. Upon clicking this button it will launch an AJAX request to a php page like this:
function ajax_launch(){
xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = ajax_launch_callback;
xmlhttp.open("POST", "/php_script", true);
xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xmlhttp.send();
}
function ajax_launch_callback(){
if(xmlhttp.readyState==4 && xmlhttp.status==200){
// code to do something once response is here successfulyl
}
}
This then does some PHP code in the php_script file and returns an $output
Issue:
The php_script page that is called via AJAX is quiet heavy and makes several API and database calls making the page "slow" to load (which is perfectly fine). However at the moment, whilst the page is waiting for a response (it is still doing the php and not yet returned anything) a user can technically spam the button to launch many ajax calls. Ideally, this will just produce stress on the server and I need a way that once the request is pending and not come back, you cannot make further requests.
How can i achieve something like this?
Thanks in advance, looking forward for your solutions/consultation
ALSO:
By multiple requests, this is what i mean - see picture of when i spam click the button to launch several requests whilst the first one isn't done (not returned anything yet):
Image of chrome debugger (networks tab)
Although the mentioned javascript solutions here and in the linked question are a nice addition, you should really do this server-side as a spammer would not necessarily be using a browser and / or could have javascript disabled.
If you use sessions on the server, the session will be locked when a request is being processed so you will only process one request per user at a time. However, requests could queue up (that is perhaps what is showing in your networks tab data?) so you could complement that with a rate limit on for example the IP address.
You can try this:
var xmlhttp;
function ajax_launch() {
if (xmlhttp && xmlhttp.readyState == 4 || !xmlhttp) {
xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = ajax_launch_callback;
xmlhttp.open("POST", "/php_script", true);
xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xmlhttp.send();
}
}
function ajax_launch_callback() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
// code to do something once response is here successfulyl
}
}
This things might be helpful:
Add this HTML
<div style="display: none;" id="screenblocker"> </div>
And this styles:
#screenblocker {
position:absolute;
left:0px;
top:0px;
right:0px;
bottom:0px;
background-color:#ffffff;
opacity:0.4;
filter:alpha(opacity=40);
z-index:9999999;
}
And script part:After the AJAX call
var e = document.getElementById('screenblocker');
if (e != null) {
e.style.display = 'block';
setTimeout("document.getElementById('screenblocker').style.display = 'none';", 5000);//considering 5 seconds to load, you can block longer if needed
}
And on AJAX success:
document.getElementById('screenblocker').style.display = 'none';

Function execute after Ajax request is complete (pure JavaScript)

In my application I use MVC model and Views are built with JavaScript DOM API.
On each page I have to check user's information to find out if session is active and if user's role gives him ability to access that page.
To make this happen, on each page I have "onload" function that triggers "sessionCheck" function which sends AJAX request to controller and returns information with which application makes decisions.
As I said JavaScript is also used to build Views, which means that after "sessionCheck" function I also have "headerView", "sectionView" and other functions that build the structure of page.
So the problem is that, before "sessionCheck" is finished other functions are loaded and nearly for 1-2 seconds users have ability to see what happens on that page and only after that they are transported out of that page by application if that is needed.
I read that there are some solutions in JQuery where "ajax.Complete" functions are available, but I couldn't same solutions in pure JavaScript. Can someone help me to solve this problem ?
This is HTML
<body onload="sessionCheckAdmin(); adminHeaderView(); adminUser(); modalView();">
sessionCheckAdmin functions looks like this
function sessionCheckAdmin()
{
var formData = new FormData();
formData.append("Code", "3");
formData.append("Sequence", "27");
formData.append("TaskId", "All");
var xmlHttp = new XMLHttpRequest();
xmlHttp.onreadystatechange = function()
{
if(xmlHttp.readyState == 4 && xmlHttp.status == 200)
{
var array = JSON.parse(xmlHttp.responseText);
if(array["userRole"] != "Administrator")
window.location.href = "task.php";
}
}
xmlHttp.open("POST", "../Controller.php");
xmlHttp.send(formData);
}
Part of PHP controller
case 27:
$array = json_encode($_SESSION);
echo $array;
break;

difference from using ajax from jquery and javascript

i cant find an answer to this
i have been learning ajax lately but i learned how to do it all in javascript
now i go swiming around ajax question here and almost all are using jquery
so i end up confused. should i use normal javascript or do it through jquery?
so what are the differences?
this is my normal approach
var xmlHttp = createXmlHttpRequestObject(); //you first create the object to this function global
function createXmlHttpRequestObject() //here you instruct the function
{
var xmlHttp; //here you tell it to use the local variable not the global version of it because this returns to the global with the propper values
if (window.XMLHttpRequest) //if the "window" or browser is aware of this Object 90% of browsers
{
xmlHttp = new XMLHttpRequest(); // if true then the variable is now equal to the heart of ajax
}
else //for internet explorer
{
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
}
return xmlHttp; //we return it back to daddy the global variable this objects does everything
//this object is everything in ajax for the most part
}
function process() //function that gets called on load of the body
{
if(xmlHttp) //if its not void or if you can run ajax
{
try //try catch statement are sort of required for the heart of things like ajax and server communication
{
xmlHttp.open("GET", "bacon.txt", true); //here 1st type of call 2nd from where 3rd
//is it true assyscronly or at the same time
//it does not start the connection to the server, its only sets up settings for the connection
xmlHttp.onreadystatechange = handleServerResponse; //anytime something changes[propertie]
//i want to call that function handleserverresponse
//begin communication
xmlHttp.send(null); //this is what communicates to the server makesure on ready statechane before this
//if the server responds you want to make sure everything is taking care of like what function onready state change is it going to call
//or what to do like open a text file in this case
} catch(e)
{
alert( e.toString() ); //alert the error message as a string on a popup
}
}
}
//handling the server response
function handleServerResponse()
{
theD = document.getElementById('theD'); //get the div in a var
if(xmlHttp.readyState==1) //if the connection to the server is established
{ //google crhome may not show this one, some browsers ignore some states
theD.innerHTML += "Status 1: server connection established<br>";
}
else if(xmlHttp.readyState==2) //request received, hey client i am the server and i received your request
{
theD.innerHTML += "Status 2: request reveived <br>";
}
else if(xmlHttp.readyState==3) //while is doing its thing
{
theD.innerHTML += "Status 3: processing request <br>";
}
else if(xmlHttp.readyState==4) //your request is finished and ready
{ //it means your response is ready but doesnt guaranteed no trouble
if(xmlHttp.status==200) //if the status is 200 then is succesufll
{
//IF everthing finally good THE GOOD PART
try //put all your calls on a try statement REMEMBER
{
//get the txt file as a string
text = xmlHttp.responseText; //response text n a normal string
theD.innerHTML += "Status 4: request is finished and response is finished";
theD.innerHTML += text;
}catch (e)
{
alert( e.toString() );
}
} else //for the other statuses like 404 else somehting went wrong
{
alert( xmlHttp.statusText ); //this will give you a status report on the wrong
}
}
}
jQuery simply wraps all of the XmlHttpRequest calls into a simple to use library. In the guts of jQuery you will see code that creates the XmlHttpRequest objects.
You can see the code that does this here:
https://github.com/jquery/jquery/blob/master/src/ajax/xhr.js
The nice thing about using a framework like jQuery is that they handle a lot of the browser idiosyncrasies for you. They also handle a lot of the edge cases you might not think about when writing your code.
Using jQuery is just for ease of use. If you prefer doing it the javascript way then carry on doing that.
jQuery ajax calls do exactly the same as what you are doing but jQuery is a javascript framework which simplifies what you write.
jQuery is a javascript framework which contains library of simplified functions compared to the Native Javascript. One of the functions is the XMLHttpRequest.
This way we just need to implement functions that is needed to implement without needed to write the traditional codes to setup the AJAX system to work
You may learn more about jQuery ajax here:
http://api.jquery.com/jQuery.ajax/

Javascript: XMLHttpRequest Task Switch

document.getElementById('contactButton').value = "Sending";
xmlhttp.onreadystatechange=stateChanged;
xmlhttp.open("GET",url,false);
xmlhttp.send(null);
function stateChanged(){
if (xmlhttp.readyState==4) {
var response = xmlhttp.responseText;
if(response == "true"){
document.getElementById('contactButton').value = "Sent :)";
}
}
When running this javascript, contactButton never gets set to "Sending...". It hangs for one second, and then changes to "Sent :)".
I'm not real sure about the processing order of javascript, but it seems like it needs some sort of task switch to process the XMLHttpRequest().
This is obviously an abbreviated code, but I have several other javascript/css things I am trying to do before the xmlhttp. It seems like the xmlhttp just takes over when the request is sent.
Any ideas?
You're passing false to open, so it's running synchronously. That means it doesn't use the readyState and instead just delays until the request completes. If you want to do sync, it should be:
xmlhttp.open("GET",url,false);
xmlhttp.send(null);
if(xmlhttp.status == 200)
{
var response = xmlhttp.responseText;
document.getElementById('contactButton').value = "Sent :)";
}
You should change to async to avoid hanging your script, and you will probably find it easier to use a JavaScript library.

Categories

Resources