RESTful HTTP Client in a Browser using JavaScript

A frustration I’ve often faced when interacting with RESTful HTTP servers is that browsers make poor RESTful HTTP clients. Specifically, browsers only support the GET and POST methods and do not allow you to specify media types or other header values. This does not make for simple, self-served, human interfaces in the IoT world.

It turns out, with a little JavaScript magic, your browser can make a pretty decent RESTful HTTP client.

The code snippets below show how to perform a GET with a specified Accept header as well as a PUT with a specified Content-Type header. I’ll leave the extension to other methods and headers as an exercise to the reader.

function getOnOff(contentType)
{
    var xmlhttp = new XMLHttpRequest();
    var ds = "";
    xmlhttp.open("GET", "/onoff");
    xmlhttp.setRequestHeader("Accept", contentType);
    xmlhttp.onreadystatechange = function()
    {
        if(xmlhttp.readyState == 4)
        {
            ds = xmlhttp.responseText;
            document.forms[0].textArea1.value = ds;
        }
    }
    xmlhttp.send();
}

function putOnOff(state, contentType)
{
    var xmlhttp = new XMLHttpRequest();
    xmlhttp.open("PUT", "/onoff");
    xmlhttp.setRequestHeader("Content-Type", contentType);
    if(contentType == "application/xml")
    {
        if(state == "on")
        {
            xmlhttp.send("<OnOff>\n\t<state>on</state>\n</OnOff>");
        }
        else if(state == "off")
        {
            xmlhttp.send("<OnOff>\n\t<state>off</state>\n</OnOff>");
        }
    }
    else if(contentType == "application/json")
    {
        if(state == "on")
        {
            xmlhttp.send("{\n\"state\": \"on\"\n}");
        }
        else if(state == "off")
        {
            xmlhttp.send("{\n\"state\": \"off\"\n}");
        }
    }
}

I’ve integrated a page with similar functions into the Deuterium demo to provide a simple human interface. The demo server simply serves up this page and the user can easily interact RESTfully with the server’s resources. Check out the Deuterium test servers to see this in action.

One limitation (unless you want to fool around with your browser’s security settings) is that these snippets are subject to cross domain scripting restrictions, making a generic client less easy. At that point, you may want to look into various browser plugins.

As a bonus, if your browser supports HTTP/2, then this trick will work seamlessly with HTTP/2 (essentially the JavaScript utilizes whatever transport the browser is using).