Während eine statische HTML-Site angezeigt wird per JavaScript im Hintergrund Abfragen machen – die Möglichkeit bietet JavaScript schon seit Jahren.
Allerdings werden immer zahlreiche Zeilen Code nötig, den XMLHttpRequest() einzurichten und die Antwort entgegenzunehmen.

Ich selbst kopiere mir meine dafür verwendete Funktion immer wieder aus einem anderen Projekt raus und will es nun lieber mal hier in meiner Sammlung hilfreicher Web-Tipps posten.

Hauptanwendung ist bei mir:
Per POST Daten an ein PHP-Skript senden und eine JSON-Antwort erhalten.

Dafür habe ich mir folgende Funktion geschrieben, die sich wie darauffolgend beschrieben verwenden lässt:

AJAX-Funktion

v1.0
function ajax(args) {
  var xmlhttp;
  if (args.url == null) { console.error("ajax: Keine URL \u00fcbergeben", args); return false; }
  if (args.type == null) { args.type = "POST"; }
  if (args.args == null) { args.args = {}; }
  if (args.anfrage != null) { args.args.anfrage = args.anfrage; }
  var callback = (ajax.arguments.length > 1 && typeof ajax.arguments[1] == "function") ? ajax.arguments[1] : function(ret) {};
  xmlhttp = new XMLHttpRequest();
  xmlhttp.onreadystatechange = function() {
    if (xmlhttp.readyState == 4) {
      if (xmlhttp.status == 200) {
        // Erfolgreiche Antwort vom Server
        if (args.noJSON)
          callback(xmlhttp.responseText);
        else {
          try {
            var json = eval("("+xmlhttp.responseText+")");
          } catch(err) {
            console.error("AJAX-Fehler: Keine JSON-Antwort erhalten / ", err);
            if (!args.quiet) alert("Unerwartete Antwort vom Server erhalten.");
            return false;
            }
          callback(json);
          }
      } else {
        // Irgendwas ist hier schief gegangen...
        console.error("Bei der Anfrage ist ein Fehler aufgetreten.", xmlhttp);
        if (!args.quiet) alert("Bei der Anfrage ist ein Fehler aufgetreten.\nStatus "+xmlhttp.status);
        }
      }
    }
  xmlhttp.open(args.type, args.url, true);
  if (args.type == 'POST')
    xmlhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
  var send_arguments = "";
  for (x in args.args) send_arguments += "&"+encodeURIComponent(x)+"="+encodeURIComponent(args.args[x]);
  xmlhttp.send(send_arguments.substring(1));
  }

Verwendung

ajax({url: "URL.php" [, anfrage: 'sichern'] [, args: POST-Daten-als-jsonObjekt] [, noJSON: false] [, quiet: false] } [, function(json) { // fertig... } ] );

ajax({url: "scripts/url.php",
      anfrage: 'datenabruf',
      args: {datum: '31.12.2016', kostenstelle: 350}
      }, function(json) {
            console.log(json);
            }
      );

ajax({url: "scripts/url.php",  
      args: {anfrage: 'datenabruf', datum: '31.12.2016', kostenstelle: 350}
      }, function(json) {
            console.log(json);
            }
      );

Die hinteren beiden Beispiele sind dieselben, da das anfrage-Objekt wie alle weiteren POST-Daten mit dem Schlüssel anfrage gesendet wird.
Ich hatte es aus dem args-Objekt ausgekoppelt, da es die Funktion für mich etwas übersichtlicher machte: Ich POSTe immer anfrage mit einem Wert an das verarbeitende PHP-Skript und drösle dort die verschiedenen Anfragen, die so per JavaScript rein kommen per switch-Statement auseinander:

Beispiel PHP-Skript
<?php
switch ($_POST['anfrage']) {
  case 'datenabruf':
    // ... Tu' hier was
    die("{'summe': '127.27'}");
    break;
  case 'wertSetzen':
    // ... Tu' hier was
    die("{'ok': '1'}");
    break;
  //...
  }
?>

Methoden und Objekte

ajax(argumente, function(serverantwort) { ... } );

argumente:

url       Pflicht   String        Adresse des PHP-Skriptes, welches aufgerufen werden soll
type      optional  "POST"|"GET"  Standard: "POST"
args      optional  JSON-Objekt   POST-Daten als JSON-Objekt
anfrage   optional  String        Wert für $_POST['anfrage']
                                  (statt in args-Objekt; zur Vereinfachung)
noJSON    optional  true|false    Es soll davon ausgegangen werden, dass die Server-
                                  Antwort kein JSON-Objekt darstellt. Standard: false
quiet     optional  true|false    Bei Fehlern keinen Alert-Dialog anzeigen.
                                  Standard: false

Ausgeführte Funktion bei Server-Antwort:

JavaScript-Funktion, die genau ein Argument übergeben bekommt.
Im Normalfall handelt es sich bei diesem Objekt um ein JSON-Objekt; wurde zuvor das Argument noJSON:true übergeben, handelt es sich um einen String.