CS1116/CS5018

Web Development 2

Dr Derek Bridge

School of Computer Science & Information Technology

University College Cork

HTTP requests

A browser sends an HTTP request to a server…

But a client-side script can also send a HTTP request

XMLHttpRequest objects

Summary of what your client-side script needs to do in order to send an HTTP request:

  1. Create the request object
  2. Register a function that will handle the response (assuming asynchronous response handling)
  3. Specify the URL and the HTTP method (e.g. GET or POST)
  4. Optionally, specify any special headers that are to be sent
  5. Send the request

XMLHttpRequest example

  1. Create the request object:
    let request = new XMLHttpRequest();
  2. Register a function that will handle the response (assuming asynchronous response handling):
    request.addEventListener('readystatechange', handle_response, false);
  3. Specify the URL and the HTTP method (e.g. GET or POST):
    request.open("GET", url, true);
  4. Optionally, specify any special headers that are to be sent, e.g.:
    request.setRequestHeader("User-Agent", "XMLHttpRequest");
    request.setRequestHeader("Accept-Language", "en");
  5. Send the request:
    request.send(null);

The response

Typical function to handle the response

function handle_response() {
    // Check that the response has fully arrived
    if ( request.readyState === 4 ) {
        // Check the request was successful
        if ( request.status === 200 ) {
            // do whatever you want to do with 
            // request.responseText or request.responseXML
        }
    }
}

Ajax

Ajax…

What's the idea…

Uses of Ajax

Ajax example 1

store_score.py

#!/usr/local/bin/python3

from cgitb import enable 
enable()

from cgi import FieldStorage
from html import escape
import pymysql as db
            
print('Content-Type: text/plain')
print()

form_data = FieldStorage()
score = escape(form_data.getfirst('score', '').strip())
try:    
    connection = db.connect('localhost', 'userid', 'password', 'database_name')
    cursor = connection.cursor(db.cursors.DictCursor)
    cursor.execute("""INSERT …""", (score))
    connection.commit()
    print('success')
    cursor.close()  
    connection.close()
except db.Error:
    print('problem')

Ajax example 2

register.py (modified)

Identical except for:
print("""
    <!DOCTYPE html>
    <html lang="en">
        <head>
            <meta charset="utf-8" />
            <title>Web Dev 2</title>
            <script src="check_name_available.js" type="module"></script>
        </head>
        <body>
            <form action="register.py" method="post">
                <label for="username">User name: </label>
                <input type="text" name="username" id="username" value="%s" />
                <span id="checker"></span>
                <label for="password1">Password: </label>
                <input type="password" name="password1" id="password1" />
                <label for="passwords2">Re-enter password: </label>
                <input type="password" name="password2" id="password2" />
                <input type="submit" value="Register" />
            </form>
            %s
        </body>
    </html>""" % (username, result))

The Python program: check_name_available.py

#!/usr/local/bin/python3

from cgitb import enable 
enable()

from cgi import FieldStorage
from html import escape
import pymysql as db
            
print('Content-Type: text/plain')
print()

form_data = FieldStorage()
username = escape(form_data.getfirst('username', '').strip())
try:    
    connection = db.connect('localhost', 'userid', 'password', 'database_name')
    cursor = connection.cursor(db.cursors.DictCursor)
    cursor.execute("""SELECT * FROM users 
                      WHERE username = %s""", (username))
    if cursor.rowcount > 0:
        print('in_use')
    else:
        print('available')
    cursor.close()  
    connection.close()
except db.Error:
    print('problem')

The client-side JavaScript: check_name_available.js

let username;
let checker;
let request;
    
document.addEventListener('DOMContentLoaded', init, false);

function init() {
    username = document.querySelector('#username');
    checker = document.querySelector('#checker');
    username.addEventListener('keypress', set_link, false);
    checker.addEventListener('click', check_name_available, false);
}

function set_link() {
    checker.innerHTML = '<a href="#">Check name is available</a>';
}

function check_name_available() {
    let url = 'check_name_available.py?username=' + username.value;
    request = new XMLHttpRequest();
    request.addEventListener('readystatechange', handle_response, false);
    request.open('GET', url, true);
    request.send(null);
}
    
function handle_response() {
    // Check that the response has fully arrived
    if ( request.readyState === 4 ) {
        // Check the request was successful
        if ( request.status === 200 ) {
            if ( request.responseText.trim() === 'available' ) {
                checker.innerHTML = 'Name available';
                } else if ( request.responseText.trim() === 'in_use' ) {
                checker.innerHTML = 'Name not available';
            }
        }
    }
}

All that glitters is not gold: problems with Ajax