I searched stackoverflow but got contradictory answers:
Why should I reuse XmlHttpRequest objects?
Ajax-intensive page: reuse the same XMLHttpRequest object or create new one every time?
Also, there's a recommendation on w3schools.com :
If you have more than one AJAX task on your website, you should create
ONE standard function for creating the XMLHttpRequest object, and call
this for each AJAX task.
Why this recommendation? I'm instead using a global XMLHttpRequest object on my page for handling all Ajax tasks.
You misunderstood W3School's recommendation. I'll highlight the relevant part:
If you have more than one AJAX task on your website, you should create ONE standard function for creating the XMLHttpRequest object, and call this for each AJAX task.
It says that you use one AJAX function to fetch requests. This function will deal with the inconsistencies between IE and other browsers. XMLHttpRequest in standard-compliant browsers, and ActiveXObject in IE.
I recommend to use multiple XHR objects. With one global xhr object, your application can only deal with one request at a given time. It's also error-prone (eg. XMLHttpRequest launches multiple times without initiating the onreadystatechange function).
W3schools meant something like:
function createXHR() {
try {
return new XMLHttpRequest();
} catch (e) {
try {
return new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {
return new ActiveXObject("Msxml2.XMLHTTP");
}
}
}
var xhr = createXHR();
xhr.open('get', '/test', true);
xhr.send();
Although it's better to create a function which handles requests, such as jQuery.ajax.
It is best to use different objects for each XHR you are making. Even if there's a way of doing it, avoid it! There's no problem with creating new object for each request. If you are worried about memory leak or something of that sort, do not worry, they are all properly GC`ed.
If you have more than one AJAX task on your website, you should create ONE standard function for creating the XMLHttpRequest object, and call this for each AJAX task.
It actually means that you have one function that creates a new object and returns it every time you call it. It something like:
function newXHR(){
return a new instance of XHR();
}
The recommendation you highlight is saying you should have one FUNCTION which handles AJAX, rather than specifically one XMLHTTPRequest object.
I would use a different one for each question.
The common argument against this concerns the overheads involved in setting up XHRs. However this is going to be pretty much negligible in any site that uses AJAX as it was intended (i.e. not as a labouring substitute for web sockets) and, in any case, much of the same overheads would apply with re-using an XHR. You'd still have to open the connection, fire it, attach listeners etc.
Browsers vary in terms of how many connection gateways are allowed at a given time, so it's up to the browser to control what XHRs can do what. In other words, you don't have to worry about managing this aspect.
Finally, there's nothing stopping you manually deleting the XHRs after you've used them, provided they are deletable (properties of an object rather than variables).
From MDN Web Docs:
If the httpRequest variable is used globally, competing functions
calling makeRequest() can overwrite each other, causing a race
condition. Declaring the httpRequest variable local to a closure
containing the AJAX functions avoids this.
Source: https://developer.mozilla.org/en-US/docs/Web/Guide/AJAX/Getting_Started
I am using a pattern like this
var xhrSendBuffer = new Object();
function sendData(url, model) {
if (!xhrSendBuffer[url]) {
let xhr = new XMLHttpRequest();
xhr.onloadend = xhrDone;
xhr.error=xhrError;
xhr.onabort = xhrAbborted;
xhr.open('POST', url, true);
xhr.setRequestHeader('Content-Type', 'application/json; charset=utf-8');
xhrSendBuffer[url] = xhr;
}
xhrSendBuffer[url].send(JSON.stringify(model));
}
function xhrDone(e) {
console.log(e);
}
function xhrError(e) {
console.error(e);
}
function xhrAbborted(e) {
console.warn(e);
}
if I end up producing a DOS on my own site because I send to the same url multiple requests I could use the xhr.readyState to see how busy it is before sending the next request, however I have yet to encounter this as an issue.
Related
I'm kind of new to using ajax but I've been largely successful. Most of my ajax calls look very similar to this:
function saveQueryProf(){
var currentDate = new Date();
var date=currentDate.getDate()+'/'+(currentDate.getMonth()+1)+'/'+currentDate.getFullYear();
$.ajax({
type: "POST",
url: "API.php",
data: { method: "createQueryProfile",
prof_name: $('#nameTxt').val(),
prof_SQL: $('#sqlTxt').val(),
date: date
},
datatype: "json"
}).done(function(returnresult) {
})
}
Using the $.ajax({ method. However, any time I see someone using "ajax" on youtube or other sites, their code looks more like this:
function loadDoc() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("demo").innerHTML = this.responseText;
}
};
xhttp.open("GET", "ajax_info.txt", true);
xhttp.send();
}
I realize that these are doing different things, but what is the difference in these 2? And when I'm looking for answers online how could I find an answer that is more along the lines of the first style?
The first example, using $.ajax(), is specific to jQuery. It's a lot simpler than the built-in Javascript API, XMLHttpRequest. XMLHttpRequest doesn't require any external libraries to use, though it's more difficult. $.ajax() relies on XMLHttpRequest.
Your code requires the jQuery library to work (that's where $ and $.ajax come from). Their code is using XMLHttpRequest directly, which is built in to JavaScript, so it doesn't need any libraries. If you want your AJAX code to depend on jQuery, then just include it as a search term.
I saw that the question was already answered, but I think that more information can be added.
In your first example you are using jQuery ($.ajax call). You will need to add this library to your website in order to make it work. The easiest way is to add a tag with jQuery CND to your website.
The second example is using vanilla JavaScript, the XMLHttpRequest. It has more complex syntax (a strange mixture of upper and lowercase characters), but you don't need to add anything to the site. It will do the work, and once you are used to the syntax it might be all you need.
Third option that I have used for AJAX request is the fetch() method. Like XMLHttpRequest it is build in in the JavaScript language. fetch() has very simple syntax and allows easy use of promises. You might need promises if you will be making requests that will not return data immediately. Here's more information on fetch:
https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch
Fourth option that I've used for AJAX is Axios library. If you are including jQuery only for AJAX requests Axios is probably better choice. More read on Axios: https://github.com/axios/axios
If you want to dig a bit more on the differences and pros/cons between fetch() and XMLHttpRequest take a look on this thread:
Fetch API vs XMLHttpRequest
Shortly Ajax is an extension method which defined in JQuery for factory class XmlHttpRequest.
I am new to Ajax, and to make things worse, also a Javascript noob, and I have posted the bellow code of a chat script, to retrieve text from db, in real time, and the code is working, but I need to understand what certain requests are all about.
<script>
function retrieve(){
var xmlhttp;
if(window.XMLHttpRequest){
xmlhttp = new XMLHttpRequest(); }
else if(window.ActiveXObject) {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); }
else {
alert('Please update your browser to start chatting');
}
Simply, I understand the above is (I created it) just a function with global variable declared to be assigned whether XMLHttpRequest/ActiveXObject Object is declared depending if browser is IE6,7 and others if not throw in alert...
xmlhttp.onreadystatechange = function(){
if(xmlhttp.readyState == 4 && xmlhttp.status == 200){
document.getElementById("canvas").innerHTML = xmlhttp.responseText;
}
}
Similarly, the above I assume takes the onreadystatechange property of the Ajax API and checks for it's state, readyState & status which, if only they match 4 and 200 means, Ajax is working as wanted
t = setTimeout("retrieve()", 2000);
I know the setTimeout() is a bit like setInterval() function, which runs the function inside it, every 2 seconds, to check for new messages.
xmlhttp.open("GET", "getajax.php", true);
xmlhttp.send();
Now, the problem is with the above, I can almost understand that the .open method is supposed to get data from getajax.php even though, I have no idea of what true means in this instance, but as far as the xmlhttp.send(); I have absolutely no clue,
So, All I need is for you to explain to me what I have missed during my illaboration, and
what the last queries mean, just in brief.
}
retrieve();
</script>
<div id="canvas"></div>
xmlhttp.open("GET", "getajax.php", true);
xmlhttp.send();
true is what tells the request to be performed A -synchronously, which is the A in AJAX. Then finally .send() actually send the request.
Asynchronous requests are non-blocking meaning that the rest of your code wont wait for them to finish and return before continuing. That is why you sent event handlers before starting the request via xmlhttp.onreadystatechange. That way once the request is complete you have already told your script what to do with the returned information.
Hope this helps.
Edit Additionally I recommend using some sort of framework or library for javascript like jQuery. While it is good to learn some of the javascript core, something like jQuery will make your life much easier.
Simply, I understand the above is (I created it) just a function with global variable declared to be assigned
xmlhttp isn't a global. It's a local variable in the global function retrieve.
Similarly, the above I assume takes the onreadystatechange property of the Ajax API and checks for it's state
onreadystatechange is a property that accepts a function. That function is run when the value of readyState changes. That function is usually used to check the status of the request.
I know the setTimeout() is a bit like setInterval() function, which runs the function inside it, every 2 seconds, to check for new messages.
setTimeout is like setInterval in a sense that it runs a function at a later time. Unlike setInterval, it only runs the code once. Also, that's not the proper way of running a timer. Here's a post that explains how to properly use timers.
the .open method is supposed to get data from getajax.php even though, I have no idea of what true means in this instance, but as far as the xmlhttp.send(); I have absolutely no clue
The open builds your request by accepting:
The type of request (GET/POST)
The url where you want the request sent
The third argument determines if the request is asynchronous or not.
If set to false, this makes the request synchronous. The browser will freeze and wait for the response.
If true, the request us asynchronous. The browser will not freeze in waiting.
The default value is true, so you can omit it.
send is the actual function that ultimately sends the request to the server.
For further reading, I suggest you read MDN's section regarding AJAX.
I'm pretty new to javascript and am working on an embedded system which decodes video over IP.
I have written a small app for setting up and changing channels using javascript and included a key handler for remote controls and an event handler so I can take some action or present a message if video stops or the network goes down, but now I also want to set up an automatic HTTP POST that gets sent when I change channel to include some data about the device and the url currently being played.
This is a small embedded hardware device running busybox, so I can't use Ajax or add any other normal web technologies, I just need to use Javascript to send a HTTP POST triggered by events I am monitoring, so my first goal is to be able to press a button and send that POST message then work out when to trigger it later.
Anyone familiar with doing such things that can give me a quick overview of how to send a post to a known listening device/location and include data in it?
Many thanks
This is easy if your Javascript engine supports XMLHttpRequest (XHR), which is ubiquitous on the web. Google it or see this page for details. I've provided a code snippet below. Read it carefully, particularly the comments on "async" being true and closures in response handlers. Also, this code is super lightweight as far as Javascript goes and I would expect it would work fine on just about any contemporary hardware footprint.
var url = "http://www.google.com/";
var method = "POST";
var postData = "Some data";
// You REALLY want shouldBeAsync = true.
// Otherwise, it'll block ALL execution waiting for server response.
var shouldBeAsync = true;
var request = new XMLHttpRequest();
// Before we send anything, we first have to say what we will do when the
// server responds. This seems backwards (say how we'll respond before we send
// the request? huh?), but that's how Javascript works.
// This function attached to the XMLHttpRequest "onload" property specifies how
// the HTTP response will be handled.
request.onload = function () {
// Because of javascript's fabulous closure concept, the XMLHttpRequest "request"
// object declared above is available in this function even though this function
// executes long after the request is sent and long after this function is
// instantiated. This fact is CRUCIAL to the workings of XHR in ordinary
// applications.
// You can get all kinds of information about the HTTP response.
var status = request.status; // HTTP response status, e.g., 200 for "200 OK"
var data = request.responseText; // Returned data, e.g., an HTML document.
}
request.open(method, url, shouldBeAsync);
request.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
// Or... request.setRequestHeader("Content-Type", "text/plain;charset=UTF-8");
// Or... whatever
// Actually sends the request to the server.
request.send(postData);
In the follow ajax request could some one please explain (tryMS)
function createRequest() {
try {
request = new XMLHttpRequest();
} catch (tryMS) {
try {
request = new ActiveXObject("Msxml2.XMLHTTP");
} catch (otherMS) {
try {
request = new ActiveXObject("Microsoft.XMLHTTP");
} catch (failed) {
request = null;
}
}
}
return request;
}
Is (tryMS), and (otherMS) part of javascript or is it just a common argument used in the code, do they have specific functions? If its an argument wheres it value coming from.
In this case, tryMS and otherMS are just variable names. You could replace them with any valid variable name and the logic would be exactly the same. In this case, the object they will represent at runtime is a subclass of Exception as they are used in the catch clause of a try-catch statement.
You can read more about try-catch-finally here.
I wouldn't agree with the naming convention being used here, but the variable name is essentially describing the flow of control based on the browser being used. For example, if the creation of an XMLHttpRequest object causes an exception to be raised, then we should try an AJAX technique for microsoft browsers using ActiveXObject - hence the name tryMS.
Internet Explorer doesn't have an xhr XmlHttpRequest -- they have their own object for that. This code is trying to be browser agnostic; i.e. trying to work no matter the browser. The createRequest method tries to create an XMLHttpRequest. If that fails, it tries to create the first ActiveXObject. If that fails, it falls back to the next active x object.
Is (tryMS), and (otherMS) part of javascript or is it just a common
argument used in the code, do they have specific functions? If its an
argument wheres it value coming from.
try/catch statements pass the error to to the catch block. So tryMS and otherMS and failed are all just references to a string that describes the error.
I'm fairly new to ajax but am trying to implement two simple calls to dynamically changes two separate divs on a page using javascript. I have no problems using one call at a time, but when I use two it seems like the second xmlhttprequest takes over the first and writes into both divs.
I've read and tried using the fixes listed on these two other posts both neither seem to work in my case:
Sending two Ajax requests to two different PHP scripts from single javascript function
Using two xmlhttprequest calls on a page
And here is my relevant code:
function request_handler(url, params, changed_div) {
if(window.XMLHttpRequest) {
try {
req = new XMLHttpRequest();
}catch(e) {
req = false;
}
}else if(window.ActiveXObject) {
try {
req = new ActiveXObject("Msxml2.XMLHTTP");
}catch(e) {
try {
req = new ActiveXObject("Microsoft.XMLHTTP");
}catch(e){
req = false;
}
}
}
if(req) {
req.onreadystatechange = function(){
if (req.readyState == 4 && req.status == 200){
document.getElementById(changed_div).innerHTML = req.responseText);
}
}
req.open("POST", url, true);
req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
req.send(params)
return true;
}
return false;
}
Here is the basic format of each request using the function above:
request_handler("sample.php", parameters , "sample_div");
Apologies if I'm passing something simple up here, I just can't seem to get it to work.
This question
Using two xmlhttprequest calls on a page
does answer your question.
In your request_handler function, you're using a global variable req that gets overwritten every time you call that function.
If you change it to start:
function request_handler(url, params, changed_div) {
var req;
// Rest of your function
}
you should find that it works. In this case req has a local scope and so is not overwritten when you call request_handler for the second time.
Can I also suggest that you strongly consider using the likes of jQuery, Prototype or Dojo, if you're planning on writing Ajax scripts? Writing scripts that work cross-browsers is hard to do well and these frameworks do a lot of the legwork for you.
Your req is a global variable as it is defined without the var keyword, keep that in mind.
What I think happens is that the second call overwrites the first one. This is because of the (default) asynchronous nature of the XMLHTTPRequest. Your first function call will end, but the fetching of the page is still going. The second function call then overwrites the previous request.
This however does not explain why both div get filled with the result of the second call. I must say I'm a bit lost on that one.
This is a pretty common problem, especially if you don't want to take additional measures to block further calls until the first has finished loading. Its a bigger subject that I can cover in a post but there are several examples on the web of an "Ajax Queue" that effectively manages the order of requests received.
jQuery has a plugin for managing queues and I'm certain that most other JavaScript frameworks such as Prototype and MooTools will as well. If you're wanting to stick with raw JavaScript I would take a look at this web page:
http://www.cmarshall.net/MySoftware/ajax/index.html
He implements a queue very effectively and has an excellent example of its use.