Click to See Complete Forum and Search --> : Background Server Polls (from cannot view script) or Do-it-yourself remote scripting


Vladdy
03-12-2003, 12:00 PM
If I am to write a tutorial I figured it deserves it’s own thread. So anyway here are the basics on how to implement server polls using client-side javascript without reloading the HTML page.

Goal:
Get information from the server and use it to update HTML document without reloading it.

Solution:
Spread functionality between two files:
- HTML document page.html
- Server-side script that dataserver.asp that provides the data.

For the sake of simplicity we are going to have a couple of links in HTML document, which when clicked will activate the script that polls the server. Returned information will be displayed in an alert box.

<html>
<head>
<title>Background Server Poll Demo</title>
<script>
function pollServer(query)
{ if(script) return false; //Do not send new request while
//there is one being processed
script = document.createElement('script');
script.src = ‘dataserver.asp?’ + query;
document.getElementsByTagName('head')[0].appendChild(script);
}

function processServerResponse(data)
{ alert(‘Server returned: ‘ + data);
setTimeout(‘requestProcessed()’,50);
return;
}

function requestProcessed()
{ document.getElementsByTagName('head')[0].removeChild(script);
script = null;
return;
}
</script>
</head>
<body>
<a href=”#” onclick=”pollServer(‘get=info1’); return false;”>Get info 1</a>
<a href=”#” onclick=”pollServer(‘get=info2’); return false;”>Get info 2</a>
</body>
</html>


Server side code:

<% ‘Add all the prerequisite code here
‘ We are returning js !!!
Response.Content = “text/javascript”
‘ Add all the happy http stuff to disable caching here
‘ like Response.Expires = Yesterday
Action = Request.QueryString(“get”)
If Action = “info1”Then
ReturnedData = “Returned info1 data”
Else If Action = “info2” Then
ReturnedData = “Returned info2 data”
‘Expand as needed
End If
%>
processServerResponse(‘<%=ReturnedData%>’);
<% ‘ That is pretty much it.
%>


How it works
When you click on one of the links the pollServer function is called. It creates a new script node and sets the node’s src attribute to the name of the server-side script file with attached query string that was passed as a function parameter. It then appends the created node to the document head. At this point the request is set to the server to get the javascript code to execute.
The server side script examines the query string and populates the ReturnedData string with requested information. This string is returned as a parameter to the processServerResponse function. As a result the client gets a javascript containing one line which is a call to a function residing with the HTML page.
The processServerResponse function displays the received data in alert box. Then it calls the requestProcessed function via setTimout (QUIZ: Why it is important to use setTimout and not the straight call?)
The requestProcessed function removes the script node from the document head.

Turning it into a practical application
As shown the new requests are ignored until the current one is being processed. Reception of requests from the user and their processing should be untied so that a queue can be formed.
Server side script can obtain data from sources such as files, databases and whatever else you desire. The resultant data string can be delimited to represent tables and such as long as the format is “agreed upon” between the server-side script delivering data and client side script that is presenting it.
It goes without saying that client side script can present the received data on the page and not in alert box.

khaki
03-12-2003, 12:10 PM
YOU ARE WONDERFUL !
:) ;) :) ;) :) ;) :) ;)

Apollyon
02-04-2004, 02:36 PM
Hello,

Great topic, but it isn't working here.
I receveid the message:
" 'script' isn't defined - Line 6 - Char 5 "

I'm using IE 6.0

Vladdy
02-04-2004, 02:39 PM
This code only shows the idea and therfore omits quite a few things like variable declarations.
It was never intended for cut-n-paste.

esthera
03-18-2004, 11:23 AM
This looks useful. Did anyone use this and have an example of what they did. I dont' really understand all the javascript.
(I am mainly an asp programmer)

What I really want to do is call an asp page with a javascript variable and in the asp I will do the processing.

Vladdy
03-18-2004, 11:51 AM
Since then I had made a working example ready for cut and paste:

client.html:

<html>
<head>
<title>Background Server Poll Demo</title>
<script>
var script = null;

function pollServer(query)
{ if(script) return false; //Do not send new request while
//there is one being processed
script = document.createElement('script');
script.src = 'server.asp?' + query;
script.type = 'text/javascript';
document.getElementsByTagName('head')[0].appendChild(script);
return false;
}

function processServerResponse(data)
{ alert('Server returned: ' + data);
setTimeout('requestProcessed()',50);
return;
}

function requestProcessed()
{ document.getElementsByTagName('head')[0].removeChild(script);
script = null;
return;
}
</script>
</head>
<body>
<a href="#" onclick="return pollServer('get=info1');">Get info 1</a>
<a href="#" onclick="return pollServer('get=info2');">Get info 2</a>
</body>
</html>


server.asp

<%@ Language =JScript EnableSessionState = False%>
<%
Response.Buffer = true;
Response.ContentType = 'text/JavaScript';
// Just threw in everything I heard about preventing
// the page from being cached.
Response.Expires = 0;
Response.ExpiresAbsolute = '01/01/1999';
Response.AddHeader ('pragma','no-cache');
Response.AddHeader ('cache-control','private');
Response.CacheControl = 'no-cache';

var ReturnedData = '';
Action = Request.QueryString('get');
if(Action == 'info1') ReturnedData = 'Returned info1 data';
if(Action == 'info2') ReturnedData = 'Returned info2 data';
%>
processServerResponse('<%=ReturnedData%>');


Just a reminder about the obvious fact that you need to use http protocol since asp script would not be executed if you use file:// (after double-clicking on the file name)

waynelambright
12-18-2004, 09:21 PM
<html>
<head>
<title>Background Server Poll Demo</title>
<script>
var script = null;

function pollServer(query)
{ if(script) return false; //Do not send new request while
//there is one being processed
script = document.createElement('script');
script.src = 'serverVB.asp?' + query;
script.type = 'text/javascript';
document.getElementsByTagName('head')[0].appendChild(script);
return false;
}

function processServerResponse(data)
{ alert('Server returned: ' + data);
setTimeout('requestProcessed()',50);
return;
}

function requestProcessed()
{ document.getElementsByTagName('head')[0].removeChild(script);
script = null;
return;
}
</script>
</head>
<body>
<p><a href="#" onclick="return pollServer('get=info1');">Get info 1</a>
<a href="#" onclick="return pollServer('get=info2');">Get info 2</a>
</p>
<p><a href="1.html">page 1</a></p>
</body>
</html>

and the serverVB.asp page.

<%@ Language =JScript EnableSessionState = False%>

<script language="VBScript" runat="SERVER">
Response.Buffer = True
Response.ContentType = "text/JavaScript"
' Just threw in everything I heard about preventing
' the page from being cached.
Response.Expires = 0
Response.ExpiresAbsolute = #01/01/1999#
Response.AddHeader "pragma","no-cache"
Response.AddHeader "cache-control","private"
Response.CacheControl = "Private"

ReturnedData = ""
Action = Request.QueryString("get")

if(Action = "info1") then
' do Database insert here
ReturnedData = "Returned info1 data VB"
end if

if(Action = "info2")Then
' do Database insert here
ReturnedData = "Returned info2 data VB"
end if
</SCRIPT>
processServerResponse('<%=ReturnedData%>');



---------------------------

toolz
02-03-2005, 12:37 PM
Two main problems:

1) the value passed back from the host is seen the *second*
time thru the IMgetvalue() routine. Perhaps the document is
not fully loaded before getElementByTagName is called?

2) this code makes the IE6 browser under XP exit with an error
message immediately upon load!

IE6 under Windoze 98 performs the poll correctly but never
'sees' the new value

Opera and Mozilla work fine (except for the second time thru
IMgetvalue() problem).

-------------------- javascript on client ------------------
var IMmsgid = 0; // queued message id for this user
var Script = null;

function IMpopUp(URL)
{
day = new Date();
id = day.getTime();
eval("page" + id + " = window.open(URL, '" + id + "', 'toolbar=0,scrollbars=0,location=0,statusbar=0,menubar=0,resizable=0,width=300,height=150');");
}

function IMreply(URL)
{
window.close();
IMpopUp(URL);
}

// set recall to 60 sec.
function IMinit()
{
setInterval("IMgetvalue()", 60000);
IMgetvalue();
}

function IMgetvalue()
{
Script = document.createElement('script'); // Create an element
Script.src = '/cgi-bin/im.cgi?poll'; // return data in the form 'value=1' or '0'
Script.type = "text/javascript";
// Now add the script element in the head section which automatically updates the value
document.getElementsByTagName('head')[0].appendChild(Script);
// Now get rid of the element so as not to create multiple iterations
document.getElementsByTagName('head')[0].removeChild(Script);
Script = null;
// Do as you will with the value;
if (IMmsgid > 0)
{
IMpopUp("/cgi-bin/im.cgi?display+" + IMmsgid);
IMmsgid = 0;
}
}

window.onload = IMinit;

----------------------- server code in Perl ---------------------
$qstr = "select msgid from instantmsg\
where receiver = \"$user\"\
and recvtime is null limit 1";

$Sth = $Dbh->prepare($qstr);
$count = $Sth->execute;
&logmsg('I',"poll for $user: %d",$count);

print "Content-type: text/javascript\n";
print "Expires: Tue, 04 Dec 1993 21:29:02 GMT\n";
print "Cache-Control: no-cache\n\n";

if ($count < 1)
{
$Sth->finish;
print "var IMmsgid = 0;\n";
return;
}

$msgid = $Sth->fetchrow_array;
$Sth->finish;
print "var IMmsgid = $msgid;\n";