skip to content

JavaScript: Making a HEAD request via an Ajax script

As you've probably worked out, it's not possible for JavaScript to make HTTP requests to remote servers without explicit permissions being granted at one or both ends.

This is an important security feature to stop browser being caught up in DDoS or other black-hat practices unbeknownst to the uer.

In this article we present JavaScript code that invokes a cURL HEAD command by calling a local Ajax (server-side) script and parsing the result into an HTML table on the page.

There is no solution using only JavaScript that allows the browser to get responses from unauthorised remote servers, due to the web browser same-origin policy security mechanism.

Sample Output

Click the button below to make a HEAD request for various URLs on this website and see the response details appear in an HTML table:

For the different URLs you should see a range of responses, from 403 to 301 and 200. Note that when there is a redirect it will be followed and logged, up to the system redirect limit.

Please note that the Ajax script we are calling has been restricted to just the URLs that appear above. In practice, on your own system, you shoud be able to contact any address.

Source Code

The JavaScript code makes use of our AjaxRequestXML.js JavaScript class to make an Ajax request and parse the results using a callback function. This process has been described in depth already elsewhere.

<script src="AjaxRequestXML.js"></script> <script> const dataTable = document.querySelector("#curl_output"); const addHeaderRow = function(heading) { let row = document.createElement("tr"); let cell = document.createElement("th"); cell.setAttribute("colspan", 2); cell.innerText = heading; row.appendChild(cell); dataTable.appendChild(row); }; const addTableRow = function(arr) { arr.forEach(function(current) { let row = document.createElement("tr"); let label = document.createElement("td"); let cell = document.createElement("td"); let matches = current.match(/^(.+): (.+)/); if(matches) { label.innerText = matches[1]; cell.innerText = matches[2]; } else { label.innerHTML = "<strong>&gt;&gt;&gt;</strong>"; cell.innerHTML = "<strong>" + current + "</strong>"; } row.appendChild(label); row.appendChild(cell); dataTable.appendChild(row); }); }; const makeHeadRequestCallback = function(url, json) { addHeaderRow(url); const obj = JSON.parse(json); obj.forEach(function(current) { addTableRow(current); }); }; const callAjax = function(target, params, callback) { return (new AjaxRequestXML()).post("/scripts/" + target + ".xml", params, callback); }; const makeHeadRequest = function(url) { callAjax("curl-head", { url : url, }, makeHeadRequestCallback); }; </script>

To invoke the script, we just pass a valid URL:

<script> makeHeadRequest(""); </script>

Ajax Response

The bulk of the script is for parsing the Ajax response data, which arrives in XML format (the default for our Ajax libraries) and contains a JSON payload:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <response> <command method="callback"> <params></params> <params>[["301","Server: Apache\/2.4","Location: https:\/\/\/javascript\/","Content-Type: text\/html; charset=iso-8859-1"],["200","Server: Apache\/2.4","Content-Type: text\/html; charset=UTF-8"]]</params> </command> </response>

As you can see, the Ajax script returns both the original URL, as well as an array of (filtered) response codes and other headers. You could obviously modify the script yourself to include or exclude different headers.

These parameters are passed to our makeHeadRequestCallback function which unpacks the JSON data and uses it to populate the HTML data table.

cURL HEAD Request

Behind the scenes, what we are doing is using PHP to execute a cURL request as follows:

curl --silent --location --head ''

Which returns a response from the command-line as follows:

HTTP/1.1 301 Moved Permanently Date: Mon, 15 Jul 2024 19:56:08 GMTServer: Apache/2.4 Location: Content-Type: text/html; charset=iso-8859-1 HTTP/1.1 200 OK Date: Thu, 09 May 2024 08:55:05 GMT Server: Apache/2.4 Vary: User-Agent,Accept-Encoding Cache-Control: max-age=0, no-cache

Our Ajax script filters this output and returns the result to the callback function.

HTML source code

On the page itself, you just need the stub of an HTML table, as follows:

<table class="collapse"> <tbody id="curl_output"> <!-- data table --> </tbody> </table>

The URL of each/any HEAD request is displayed as a TH, with the various response headers are displayed as normal TD cells.

< JavaScript

Post your comment or question