Why we handle the response before the request in AJAX? - javascript

I am new to AJAX, As i understood that the handler function executes when response is ready.
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("demo").innerHTML =
this.responseText;
}
};
And then we create and send our request
xhttp.open("GET", url, true);
xhttp.send();
does it make sense to handle the response while not sending the request yet !? Thanks

It makes sense because we may get the response while the response event handler was not set. Also, we do not handle the response right away, but we define the handler function which deals with the response.
On the other hand, in 99% of cases one will make no mistake to define the handler after the send(), in case he does not care whether the request failed immediately.
So, if there is no other way, than define the response handler after sending the request, but in all other cases do it a proper and secure way - before.

Related

Is it possible to retry an XMLHttpRequest that I Intercepted?

I am overriding the XMLHttpRequest.prototype.send = function(a,b) { } and XMLHttpRequest.prototype.open = function(a,b) { } so I can intercept every single response I get from every ajax call. Sometimes, some of those requests fail, and when that happens I need to update the cookies for the DOM and retry the failed original XHRs.
Taking in consideration that I have no control over those XHRs, meaning that I don't create them, or execute them, would it be possible for me to retry those XHR with new updated cookies?
Right now, I save the original XHR in a new variable, and when it fails, I do an xhr.open.apply() and then xhr.send.apply(). Using an HTTP Web Proxy like Charles I am able to check my response and I always get error message: Invalid request... I also realized that the difference between the original XHR and the retried XHR is that the X-Request-With header is always missing.
Any ideas on how to solve this issue?
Well, it is possible and I managed to do it.
I created a function to retry the original request, where I pass the same parameters that were passed to the XMLHTTPRequest.prototype.send function that intercepted the XMLHTTPRequest before being send.
function retryOriginalRequest(a,b, args) {
var originalRequest = new XMLHttpRequest();
originalRequest.open(a,b, true);
// The request headers need to be set up after the open call and before the send.
originalRequest.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
originalRequest.send(args, null);
};

XHR status 0, readystate 1 on localhost

Working on my own project. I'm sending an XMLHttpRequest to localhost from Firefox 44 to XAMPP. I'm receiving a status of 0 and a readystate of 1. Here's the code in question.
function sendReq(php,segment){
alert("sendreq called ");
//we out here getting 0 statuses. check out cwd, check out what php value is,
xhr.open("POST", php, true);
xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xhr.onreadystatechange = getData(segment);
xhr.send();
}
//callback function for ajax request.
function getData(div){
if ((xhr.readyState == 4) && (xhr.status == 200))
{
var serverResponse = xhr.responseText;
div.innerHTML = serverResponse;
}else{
div.innerHTML = "<p>loading!</p> ready state: " + xhr.readyState +"</br> status: "+ xhr.status;
}
}
I've read elsewhere the RS:1 / S:0 XHR properties indicate a unsuccessful cross domain request, but this is all occuring on localhost, with the files all in the same directory, and when inspecting the XHR response in Firebug, the return text is in there.
I've built a login to this page almost identical code and it works, its only pointing to a different .php file. Comparing the two and googling around are not enlightening me. So any advice is welcome. Thanks!
You're executing the getData() function once, on pageload, and returning undefined to the onreadystatechange handler, as that's what happens when you add the parentheses.
It has to be either
xhr.onreadystatechange = getData;
Note the lack of parentheses, or if you have to pass arguments
onreadystatechange = function() {
getData(segment);
}

Empty response of XMLHttpRequest

In my Java Web application I am calling ajax request as below.
<script type="text/javascript">
function selectTableHandler() {
console.log("indise selectTableHandler");
var xhttp = new XMLHttpRequest();
var selectedTable = document.getElementById('selectTable').value;
alert(selectedTable);
xhttp.open("GET", "populateTableColumList.action?tablename="
+ selectedTable, true);
xhttp.send();
console.log(xhttp.responseText);
}
</script>
The Action is calling and returns status code 200 as below.
Remote Address:[::1]:8080
Request URL:http://localhost:8080/ReportBuilder/populateTableColumList.action?tablename=films
Request Method:GET
Status Code:200 OK
But, it gives empty response of XMLHttpRequest. The line console.log(xhttp.responseText); prints nothing. Also, there is no error in console log.
Any suggestions would be appreciated.
Thanks
You need to add a callback function to get the result of the ajax request.
xhttp.onreadystatechange = function() {
if (xhttp.readyState == 4 && xhttp.status == 200) {
console.log(xhttp.responseText);
}
}
Your ajax request is asynchronous. That means it returns the result some time LATER. You will need to install an event handler for onload or onreadystatechange to get the result.
There are plenty of Ajax tutorials on how to do this. Here are a couple useful references:
https://developer.mozilla.org/en-US/docs/AJAX/Getting_Started
https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest
If you want to use vanilla js you have to attach event handler onreadystatechange which will handle response, but my advice instead of use vanilla js, use library like jQuery to initiate the ajax request. It will be more easily and it will run without problems on all types of browsers. see here. If you want vanilla js, here is a sample snippet:
xhttp.onreadystatechange = function() {
if (xhttp.readyState == XMLHttpRequest.DONE ) {
if(xhttp.status == 200){
console.log(xhttp.responseText);
}
}
}

Get all xhr request

I'm trying to get all xhr status 200 and their information when completed. It is possible to get them together in some way or I would have to keep a reference to each of them when i send?
You can use jQuery's ajaxComplete,
$(document).ajaxComplete(function(event, xhr, settings) {
if (xhr.status === 200) {
//rest of the handler
}
});
This will ensure all your ajax responses will hit this method when they're complete, an extra check will be required for the status of the response.
if you are using asp.net then you can add Application_EndRequest method in your global.asax file and check the response.

How can I tell XHR is sent to server using readyState?

This question is related to my prior question:
Is READYSTATE_LOADED across browsers?
So I know that readyState is not reliable across browsers. I'm currently just trying to do a proof-of-concept in ANY browser at this point.
I'm in my plugin and have code like this:
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
if (xhr.readyState == 4){
self._onComplete(id, xhr);
}
else if (xhr.readyState == 2 ){
self._onSent( id, xhr );
}
};
If I log the callbacks, "sent" fires immediately before "complete", AFTER my server side script responds. Am I misunderstanding what readyState 2 is? I tried 1 for kicks and that didn't fire before the server responded either.
I took a look into the upload object of the xhr object, which does at least have a "progress" event, but I still didn't see anything about progress being done. In fact if the last progress was at 97%, it will not fire at 100% as the file completes sending to server. Therefore while the server processes the upload, the progress hangs at 97% before the readyState becomes 4.
This makes the user think the upload stalled even thought it actually went up all the way.
There is no state to check to see when a request has been sent off.
readyState 2 means that the server has responded and all headers have come in. This is fired right before the main body section of the request comes in.
Your best bet is to fire your own event when you issue the send() command.
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
if (xhr.readyState == 4){
self._onComplete(id, xhr);
}
else if (xhr.readyState == 2 ){
// Headers received
}
};
xhr.send(data)
self._onSend( id, xhr );
4.6 States
UNSENT (numeric value 0) The object has been constructed.
OPENED (numeric value 1) The open() method has been successfully
invoked. During this state request headers can be set using
setRequestHeader() and the request can be made using the send()
method.
HEADERS_RECEIVED (numeric value 2) All redirects (if any) have been
followed and all HTTP headers of the final response have been
received. Several response members of the object are now available.
LOADING (numeric value 3) The response entity body is being received.
DONE (numeric value 4) The data transfer has been completed or
something went wrong during the transfer (e.g. infinite redirects).
http://www.w3.org/TR/XMLHttpRequest/#states
EDIT
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
if (xhr.readyState == 4){
self._onComplete(id, xhr);
}
else if (xhr.readyState == 2 ){
// Headers received
}
else if (xhr.readyState == 1 ){
// xhr.open() called
// You can set headers here amoung other things
xhr.send(data)
self._onSend( id, xhr );
}
};
xhr.open(method, url, async, user, password)
http://www.w3.org/TR/XMLHttpRequest/#the-open-method

Categories

Resources