PDA

View Full Version : Resolved XMLHttpRequest state change randomly not picked up.


Galcian
03-01-2010, 07:22 PM
I've started again with some help and it seems to be working now.

Hi there, I'm working on a project to create a Semantic search engine, I've only just started using JavaScript and it features heavily in the overall design.

I'm having trouble with what was supposed to be just the first prototype, I've been trying to make a page with a simple form which allows direct input of the query language, and displays the results of the query. The query itself is handled by a Java Servlet, which seems to be working fine, however I'm having a lot of trouble with the JavaScript, which seems to fail unpredictably.

Here is the script invoked by the form:

function Query(form) {

document.getElementById("status").innerHTML="Contacting Server...";
//handle inputs
var server = escape(form.server.value);
if(server == ''){
server = 'http://sparql.org/sparql';
}

var query = form.sparqlinput.value;
var c = form.c.value;

var url = ' QueryServlet?c='+ escape(c) +'&server='+ server +'&query='+ escape(query);
var xmlhttp = null;
// Create xmlhttprequest
if (window.XMLHttpRequest) {
xmlhttp = new XMLHttpRequest();
//make sure that Browser supports overrideMimeType
if ( typeof xmlhttp.overrideMimeType != 'undefined') { xmlhttp.overrideMimeType('text/xml'); }
} else if (window.ActiveXObject) {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
} else {
alert('Your browser does not seem to support AJAX, please lower your security settings or update your browser software');
}

// Create an HTTP GET request

alert("Query Sent");
xmlhttp.open('GET', url, false); //Freezes the screen, switching to True causes a refresh after state 2 which messes it up
document.getElementById("status").innerHTML="Query Being Processed";

// Set the callback function

xmlhttp.onreadystatechange = function() {
alert("Ready state=" + xmlhttp.readyState);
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
document.getElementById("status").innerHTML="Received Response";
// Output the results
var data = xmlhttp.responseXML; //get the XML results of the SPARQL query
alert("On Ready State");
displayResult(data);

}
};

// Make the actual request
xmlhttp.send(null);

}

function loadXMLDoc(fname)
{
var xmlDoc;
// code for IE
if (window.ActiveXObject)
{
xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
}
// code for Mozilla, Firefox, Opera, etc.
else if (document.implementation
&& document.implementation.createDocument)
{
xmlDoc=document.implementation.createDocument("","",null);
}
else
{
alert('Your browser cannot handle this script');
}
xmlDoc.async=false;
xmlDoc.loadXML(fname);
return(xmlDoc);
}

function displayResult(data)
{
alert('Display Result');
//xml=loadXMLDoc(data);
xsl=loadXSLDoc("xml-to-html.xsl");
// code for IE
if (window.ActiveXObject)
{
ex=data.transformNode(xsl);
document.getElementById("targetElement").innerHTML=ex;
}
// code for Mozilla, Firefox, Opera, etc.
else if (document.implementation
&& document.implementation.createDocument)
{
xsltProcessor=new XSLTProcessor();
xsltProcessor.importStylesheet(xsl);
resultDocument = xsltProcessor.transformToFragment(data,document);
document.getElementById("targetElement").appendChild(resultDocument);
}
}

</script>


There's quite a bit of debugging code in there, but the gist of it is that it should set up the XHMLHttpRequest, fire it off to the servlet and then throw an alert on every state change until the request is complete, then it should trigger the displayResult function which should load an XSL template to format the raw XML the Servlet sends back.

What's happening is that about 70% of the time, the state is changed to 1 and then the page refreshes, which seems to mess everything up, I've tried setting asynchronous to false but that hasn't stopped the refresh. 20% of the time it does nothing at all and throws no errors, and finally 10% of the time it does all the state changes, throwing an alert for every one, then triggers the displayResult function which doesn't do anything for some reason.

What I need is to figure out why it acts so damned unpredictably, it's driving me nuts. Once I can get it reliably going through the state changes and reliably firing off displayResult, I can start looking at why displayResult doesn't work.

I believe this to be a problem with the script as I've got the servlet running a System.out.println for every line of the output, and it's producing a well formed XML document, the webpage just isn't responding to this in a reliable fashion.

Cheers

Galcian
03-02-2010, 11:43 AM
Newer version of the script:

function Query(form) {

document.getElementById("status").innerHTML="Contacting Server...";
//handle inputs
var server = escape(form.server.value);
if(server == ''){
server = 'http://sparql.org/sparql';
}

var query = form.sparqlinput.value;
var c = form.c.value;

var url = ' QueryServlet?c='+ escape(c) +'&server='+ server +'&query='+ escape(query);
var xmlhttp = null;
// Create xmlhttprequest
if (window.XMLHttpRequest) {
xmlhttp = new XMLHttpRequest();
//make sure that Browser supports overrideMimeType
if ( typeof xmlhttp.overrideMimeType != 'undefined') { xmlhttp.overrideMimeType('text/xml'); }
} else if (window.ActiveXObject) {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
} else {
alert('Your browser does not seem to support AJAX, please lower your security settings or update your browser software');
}

// Create an HTTP GET request

alert("Query Sent");
xmlhttp.open('GET', url, false); //Freezes the screen, switching to True causes a refresh after state 2 which messes it up
document.getElementById("status").innerHTML="Query Being Processed";

// Set the callback function

xmlhttp.onreadystatechange = function() {
alert("Ready state=" + xmlhttp.readyState);
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
document.getElementById("status").innerHTML="Received Response";
// Output the results
var data = xmlhttp.responseXML; //get the XML results of the SPARQL query
alert("On Ready State");
displayResult(data);

}
};

// Make the actual request
xmlhttp.send(null);

}

function loadXSLDoc(fname)
{
alert('loadXSL');
var xmlDoc;
// code for IE
if (window.ActiveXObject)
{
xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
}
// code for Mozilla, Firefox, Opera, etc.
else if (document.implementation
&& document.implementation.createDocument)
{
xmlDoc=document.implementation.createDocument("","",null);
}
else
{
alert('Your browser cannot handle this script');
}
xmlDoc.async=false;
xmlDoc.loadXML(fname);
return(xmlDoc);
}

function displayResult(data)
{
alert('Display Result');
//xml=loadXMLDoc(data);
xsl=loadXSLDoc("xml-to-html.xsl");
alert('load done');

// code for IE
if (window.ActiveXObject)
{
ex=data.transformNode(xsl);
document.getElementById("targetElement").innerHTML=ex;
alert(ex);
}
// code for Mozilla, Firefox, Opera, etc.
else if (document.implementation
&& document.implementation.createDocument)
{
xsltProcessor=new XSLTProcessor();
xsltProcessor.importStylesheet(xsl);
resultDocument = xsltProcessor.transformToFragment(data,document);
document.getElementById("targetElement").appendChild(resultDocument);
}
}

</script>

Things are gradually becoming clearer - it doesn't work at all in Firefox, but the state changes are picked up in IE.

Also, setting Asynchronous to true messes it up for some reason.

So far it'll run through to "alert('load done');" but no further, there's something wrong with how the XML is being transformed.

My other problem which I think is exacerbating the whole situation is that it runs incredibly slowly - it'll take up to a minute to process the query, and I'm not sure what's holding it up.