July 1, 2012
filed in the early afternoon by dr_who in: hacking
average time to read 2:15 minutes

the other day i tried to come up with a minimalistic Ajax setup — minimalistic in the sense of minimal coding overhead. my ingredients of choice were jquery and JavaScript on the client side and python on the server side. the goal was to use both GET and POST REST calls for obtaining the dynamic data and utilize JSON as the data format.

the python server code makes use of python’s BaseHTTPServer.HTTPServer and BaseHTTPServer.BaseHTTPRequestHandler classes:

AjaxServer extends BaseHTTPServer.HTTPServer and supplies Handler which in turn extends BaseHTTPServer.BaseHTTPRequestHandler. the Handler class also implements the GET and POST REST interfaces.

the server supports

  • text/html GETs on file names from the document root, retrieving index.html for GETs on directories, and
  • application/json GETs on
  • /ajax/time returning the current time
  • /ajax/processcount returning the number of currently running processes
  • application/json POSTs on any URL returning the length of the posted content

the client is a simple HTML5 page that uses jquery’s ajax() support to invoke the GET REST and POST REST calls on our python server.

client code

the HTML5 code itself doesn’t really do anything. the magic happens in the ajax-datetime.js, ajax-processcount.js, ajax-processinput.js javascripts:

ajax-datetime.js calls the /ajax/time GET REST method every 3 seconds and sets the content of the #ajax-datetime div element to the return value of the GET REST call:

pretty much the same procedure is used for ajax-processcount.js:

the only difference is that ajax-processcount.js invokes the /ajax/processcount GET REST method and does so every 5 seconds — demonstrating the asynchronous nature of AJAX rather nicely.

while the previous two javascripts used GET to retrieve information from our python server, the next, ajax-processinput.js attaches itself to the #typehere text input field and POSTs the content of the field to /ajax/processinput, returning the result of the POST REST call via the #ajax-processedinput div element:

unfortunately, even though i tell ajax(...) that i’m sending JSON — the contentType: "application/json" line — jquery will not convert the data i’m sending into JSON and i need to explicitly turn it into JSON myself:

server code

the server code consists of two modules: ajaxserver and handler.

handler contains the Handler class which extends BaseHTTPServer.BaseHTTPRequestHandler and implements the GET and POST REST calls explained earlier:

ajaxserver contains the AjaxServer class which extends the BaseHTTPServer.HTTPServer class and is the driver of my simple python web server. it also contains the setup code to instantiate the server and start it:

running it

start the ajax server:

then point your browser to http://localhost:8000/ — in your terminal running ajaxserver you’ll see a bunch of log lines showing you the requests triggered by loading the index.html page.

the browser will initially show just the static text of index.html

— after a couple of seconds the current date and time will be displayed and continuously updated, followed by the current process count of your machine. when you enter text into the text input field and tab out, the length of your input will be shown next to it.

all three activities are happening independently from one another, the page itself is never reloaded (as you can verify in the ajaxserver log output).

m4s0n501
all content posted on these pages is an expression of my own mind. my employer is welcome to share these opinions but then again he might not want to.

4 comments »

  1. For “ajax-processedinput.js”, you missed a $ as the first character.

    After all, this is a wonderful demo. Thanks a lot.

    comment by Alex — October 21, 2013 @ 18:13

  2. thx! also, the formatting was completely borked. fixed that as well.

    comment by Dr. Dirk Husemann — October 21, 2013 @ 20:19

  3. C:\essai_ajax>python ajaxserver.py Tue, 05 Nov 2013 17:09:22 INFO ajaxserver: starting HTTP server on 127.0.0.1 :8000 Traceback (most recent call last): File “ajaxserver.py”, line 53, in run(server_class=AjaxServer, handler_class=handler.Handler, ip=ip, port=port , root=docRoot) NameError: name ‘run’ is not defined

    I don’t know why … Thank you to explain me

    comment by tb — November 5, 2013 @ 16:10

  4. there was an indentation error in my code example, the def run() function block should have been “de-dented” one level — i’ve fixed it.

    comment by dr_who — January 17, 2014 @ 17:50

RSS feed for comments on this post. TrackBack URI

Leave a comment