Page doesn't respond to HREF until AJAX completes asynchronous fetch - javascript

I have an ajax request executing through the XMLHttpRequest() object
My AJAX method is called in this format:
var xmlhttp = new XMLHttpRequest();
$(document).ready(function () { LoadData(); });
function LoadData()
{
var parameters = "DisplayData=true";
var url = "default.aspx";
Send(url, parameters, "DisplayData");
CheckForAbort();
}
function Send(url, parameters, QueryType)
{
...
xmlhttp.open("POST", url, true);
xmlhttp.setRequestHeader("Content-type", "application/x-www-form-lencoded");
xmlhttp.send(parameters);
xmlhttp.onreadystatechange = function (){...}
}
There is also a timer on the page which refreshes the data by making a new request through the Send(...) method in intervals of 15 seconds. Every .3 seconds and it calls an Elipsis() method that displays and "blinks" the "loading message" (if appropriate to be displayed) and checks for the abort.
var Color = "red";
function Elipsis() {
if (ResponseMessage != "")
{
if (Color == "darkred") { Color = 'red'; } else { Color = 'darkred'; }
$("#StatusResponse").css("display", "block");
$("#StatusResponse").css("color", Color);
CheckForAbort();
}
}
function CheckForAbort()
{
console.log("MenuActivted: " + MenuActivted);
if (MenuActivted)
{
xmlhttp.abort();
ResponseMessage = "Aborting Request";
MenuActivted = false;
}
}
But when the user clicks the menu bar which is an anchor tag with the HREF set to another page. The browser doesn't respond until the ajax request has completed it's fetch.
The HTML HREF is called the following way on an ASPX page:
<%#Eval("Text")%>
the Ajax Abort sets the flag that is checked in the CheckForAbort() method:
var MenuActivted = false;
function AbortAjax()
{
MenuActivted = true;
return false;
}
I am running IE 11 on Win 7. I have called an abort() method in another section of the code. which executes the xmlhttp.abort(). The response status and ready state respond (console output below) but the page still waits to respond to the HREF
Console output:
HTML1300: Navigation occurred.
File: ChangePassword.aspx
MenuActivted: true
ReadyState: 4
Status: 0
Does anyone have a solution to this problem?
[Updated **********]
I thought I had the solution but I didn't.
I commented out the set header but although it allowed my HREF to execute it was because the xhr was throwing an error and the fetch was terminating.
xmlhttp.open("POST", url, true);
//xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xmlhttp.send(parameters);
Please read the entire post before responding.

Related

How to stream new data to clients browser when index.html change, without the need of refreshing or reloading the web page

I am new on Html. What i need is this.
I have an index.html file on a server which is blank.
I open it and write some text inside the body all the time.
What i want is that when i save the html,
the new data to appear on my clients browser
without the need to refresh or reload the page.
I have no idea on how to do it,so i haven't try anything.
Is it possible? Is it simple?
This is a sample javascript code to read an online url and update the content container with the result.
I couldn't find a simple live update page so used my own website readme in github...
var timeout = 2000,
index = 1,
cancel = false,
url = 'https://raw.githubusercontent.com/petjofi/krivoshiev.com/master/README.md';
function update() {
updateIndex();
load(url, done);
if (!cancel) setTimeout(update, timeout);
}
function updateIndex() {
document.getElementById("index").innerHTML = index++;
}
function done(result) {
document.getElementById("content").innerHTML = result;
}
function load(url, callback) {
var xmlHttp = new XMLHttpRequest();
xmlHttp.onreadystatechange = function() {
if (xmlHttp.readyState == 4 && xmlHttp.status == 200)
callback(xmlHttp.responseText);
}
xmlHttp.open("GET", url, true); // true for asynchronous
xmlHttp.send(null);
}
<button onclick="update()">start</button>
<button onclick="cancel=true">stop</button>
<span>updating: <span id="index">0</span></span>
<div style="margin-top: 20px" id="content"></div>

xmlhttprequest special send

I would like to seek your help about xmlhttprequest. I would like to perform xmlhttp request sending out to get pictures repeatly from server only when the previous http response is received.
In server side, I have created http responses which tagged with xmlhttp status =900.So I want to send out the request once the response due to previous request is received, otherwise, the program should wait until its arrival.
For example:
When I press the button somewhere in the browser, it triggers first picture (jpeg) request to server, then waiting the server's response. After getting the Http response with status marked as 900, xmlhttp will decode the response and display the picture on (image).
In the following code, by capturing the packet with wireshark, I think I success to get the right packet flow. However, the picture can not be shown in the DIV.
Can anyone help me ? Thanks a lot and a lot!
enter code here
function init(url)
{
var xmlHTTP = new XMLHttpRequest();
xmlHTTP.open('GET',url,true);
xmlHTTP.send();
xmlHTTP.responseType = 'arraybuffer';
xmlHTTP.onload = function(e)
{
var arr = new Uint8Array(this.response);
var raw = String.fromCharCode.apply(null,arr);
var b64=btoa(raw);
var dataURL="data:image/jpeg;base64,"+b64;
document.getElementById("image").src = dataURL;
};
xmlHTTP.onreadystatechange=function(){
buff(xmlHTTP.status);
}
}
buff(status){
if (status=900){
sleep(1000);
init('/images/photos/badger.jpg');
}
}
function sleep(milliseconds) {
var start = new Date().getTime();
for (var i = 0; i < 1e7; i++) {
if ((new Date().getTime() - start) > milliseconds){
break;
}
}
}
</script>
</head>
<body>
<div id="image"><h2>picture display here</h2></div>
<button type="button" onclick=buff(900)>Get Picture</button>
enter code here
There are several problems with your code.
Markup
The problem with your markup is, that you are using a div tag to display an image. The src attribute is not supported on div tags. You should use an img tag instead like this:
....
<img id="image" />
<button type="button" onclick="buff(900)">Get Picture</button>
Statuscode
Why are you using a status of 900? If the request was correct and the image was loaded, please use a status of 200.
Image loading
Why are you even using an XMLHttpRequest for loading images?
You could simply change the src attribute on the img tag and the browser will request the image.
If you want to reload the image you could just refresh the src attribute. If all images a served under the same URL, you can add a request param like the current time:
document.getElementById("image").src = "/images/photos/badger.jpg#" + new Date().getTime();
This way the browser will request the image again and won't use the one allready loaded and cached. See this answer for further info. (Actually the question is nearly the same as yours...)
Sleep function
Your sleep function will use resources because it's a loop that will constantly run for the specified time. While it runs, it will add numbers and do comparisons that are completly unnecessary.
please use something like the javascript build in setTimeout():
buff(status) {
if(status === 900) {
setTimeout(funciton(){
init('/images/photos/badger.jpg');
}, 1000);
}
}
Update: working example
I set up a working example in the code snippet. It loads images from the same url, but they are served randomly on each request by lorempixel.
I reorganized the image loading. Actually there was another problem. You startet the next image loading with onreadystatechange. This will fire for each change of the readystate and not only when the image is loaded. Therefore I start the next buff() from the onload() like so:
var xmlHTTP = new XMLHttpRequest();
xmlHTTP.open('GET',url,true);
xmlHTTP.responseType = 'arraybuffer';
xmlHTTP.onload = function(e) {
var arr = new Uint8Array(this.response);
var raw = String.fromCharCode.apply(null,arr);
var b64 = btoa(raw);
var dataURL = "data:image/jpeg;base64," + b64;
document.getElementById("image").src = dataURL;
buff(this.status);
};
xmlHTTP.send();
For convenience I added a button for stopping the loading of new images.
For your example you just have to change the imageUrl and imageStatus variables.
var imageUrl = "http://lorempixel.com/400/200/", // set to "/images/photos/badger.jpg" for your example
imageStatus = 200, // set to 900 for your example
stopped = true;
function stopLoading() {
stopped = true;
}
function loadNextImage(url) {
if(!stopped) { // only load images if loading was not stopped
var xmlHTTP = new XMLHttpRequest();
xmlHTTP.open('GET',url,true);
xmlHTTP.responseType = 'arraybuffer';
xmlHTTP.onload = function(e) {
var arr = new Uint8Array(this.response);
var raw = String.fromCharCode.apply(null,arr);
var b64 = btoa(raw);
var dataURL = "data:image/jpeg;base64," + b64;
document.getElementById("image").src = dataURL;
buff(this.status); // set the next timer when the current image was loaded.
};
xmlHTTP.send();
}
}
function buff(status) {
if (status === imageStatus) {
setTimeout(function() {
loadNextImage(imageUrl + "?" + new Date().getTime());
}, 1000);
} else {
// Status does not match with expected status.
// Therefore stop loading of further images
stopLoading();
}
}
function init() {
stopped = false;
loadNextImage(imageUrl);
}
document.getElementById("start").onclick = function(){
init(imageUrl);
};
document.getElementById("stop").onclick = stopLoading;
<img id="image" />
<button type="button" id="start">Get pictures</button>
<button type="button" id="stop">No more pictures</button>

Control skips the ajax object onreadystatechange function. why?

I'm new to web-development. Created a signup page making some asynchronous calls to php. Ran debugging found the control skips the onreadystatechange function completely. Please help...
var ajax = ajaxObj("POST", "signup.php"); //defines the ajax object, definition is below
ajax.onreadystatechange = function () { //doesn't run after this line
if(ajaxReturn(ajax) == true) {
if(ajax.responseText != "signup_success"){
status.innerHTML = ajax.responseText;
_("signupbtn").style.display = "block";
} else {
window.scrollTo(0,0);
_("signupform").innerHTML = "OK "+u+", check your email inbox and junk mail box
at <u>"+e+"</u> in a moment to complete the sign up process.";
}
}
}
ajax.send("u="+u+"&e="+e+"&p="+p1+"&c="+c+"&g="+g); //control reaches here directly
}
}// control exits here
The ajax object is created externally here..
function ajaxObj( meth, url ) {
var x = new XMLHttpRequest();
x.open( meth, url, true );
x.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
return x;
}
function ajaxReturn(x){
if(x.readyState == 4 && x.status == 200){
return true;
}
}
This is because it's an event callback function and it will be called when server responds to your ajax request. If you're using firefox press F12, switch to network tab and check html and xhr to see it's status.
Because it is asynchronous so the function won't be called as you step through the code in a linear fashion.
It gets called by native code when the ready state changes.
Stick a breakpoint inside the function if you want to debug it.

Ajax, call multiple PHP function from a single js

i have a trouble with my project.
In my site i have a page html with a single button and at onclick() eventa js function call intro.js, trough a XmlHttpRequestObject have to do many calls at many php function, in detail:
in js i call scan() function
function scan() {
if (xmlHttp)
{
// try to connect to the server
try
{
// initiate reading the async.txt file from the server
xmlHttp.open("GET", "php/intro.php?P1=http://"+oStxt.value, true);
xmlHttp.onreadystatechange = handleRequestStateChange;
xmlHttp.send(null);
// change cursor to "busy" hourglass icon
document.body.style.cursor = "wait";
}
// display the error in case of failure
catch (e)
{
alert("Can't connect to server:\n" + e.toString());
// revert "busy" hourglass icon to normal cursor
document.body.style.cursor = "default";
}
}
}
And in handleRequestStatuschange i have:
function handleRequestStateChange()
{
// obtain a reference to the <div> element on the page
// display the status of the request
if (xmlHttp.readyState == 0 || xmlHttp.readyState == 4)
{
// revert "busy" hourglass icon to normal cursor
document.body.style.cursor = "default";
// read response only if HTTP status is "OK"
if (xmlHttp.status == 200)
{
try
{
// read the message from the server
response = xmlHttp.responseText;
// display the message
document.body.appendChild(oRtag);
oPch = document.getElementById("divRtag");
oOch = document.createTextNode(response);
oPch.appendChild(oOch);
}
catch(e)
{
// display error message
alert("Error reading the response: " + e.toString());
}
}
else
{
// display status message
alert("There was a problem retrieving the data:\n" +
xmlHttp.statusText);
// revert "busy" hourglass icon to normal cursor
document.body.style.cursor = "default";
}
}
}
It works for just one php call, but i need to call different php page in scan function after intro.php (scan2.php, scan3.php, ecc ecc) and with json_decode write single data of the array that return in div tags on my html page.
Which is the best way to call different php pages and manage the results with a single js function in ajax?
Thanks in advance
Alessandro
Not sure how you built your php-functions. Cant you create a function, that calls other functions (scans)?
function doScan(){
$data = array();
//like this, or with a loop
$data['scan1'] = scan1();
....
$data['scanN'] = scanN();
echo json_encode($data);
}
Really, the simplest method that comes to mind is just to parameterise this function. This is as simple as
function doScan(url) { // Code here }
Then simply make the exact same ajax request with the url variable.
xmlHttp.open("GET", "php/" + url + "?P1=http://"+oStxt.value, true);
Next, simply call the doScan function with various parameters.
doScan("index.php");
doScan("otherPage.php");
doScan("somethingElse.php");
This will make ajax requests on the PHP file that you specify.

To call servlet from javascript function, called on onClick event without redicting page to link in 'href'

I have an tag with href and onClick event. I want to execute the function specified for onClick event and then redirect the page to the link in href. But when i call servlet from that function,the page get redirected to the link in href rather than that servlet.I want to first complete the processing in servlet and then redirect that page to href lin.What can be done?
Google
This is the javascript function used to call servlet.
function createHttpRequest(obj)
{
link=obj.href;
if(typeof XMLHttpRequest != "undefined") {
request = new XMLHttpRequest();
}
else if(window.ActiveXObject) {
request = new ActiveXObject("Msxml2.XMLHTTP");
if(!request) {
request = new ActiveXObject("Microsoft.XMLHTTP");
}
}
if(request) {
url="http://localhost:8080/HitCounter/InsertCount?sent_url="+link;
request.onreadystatechange = handleRequest;
request.open("GET",url,true);
request.send(null);
}
else {
alert("error on Page createHttpRequest");
}
return true;
}
return true;
should be
return false;
Within the onclick attribute and the method - return false prevents the default action - ie to follow the link.

Categories