HTML in XMLHttpRequest

Baseline Widely available *

This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.

* Some parts of this feature may have varying levels of support.

Die W3C-XMLHttpRequest-Spezifikation fügt HTML-Parsing-Unterstützung zu XMLHttpRequest hinzu, das ursprünglich nur XML-Parsing unterstützte. Diese Funktion ermöglicht es Web-Apps, eine HTML-Ressource als geparstes DOM mithilfe von XMLHttpRequest zu erhalten.

Um einen Überblick darüber zu bekommen, wie man XMLHttpRequest allgemein verwendet, siehe Using XMLHttpRequest.

Einschränkungen

Um die synchrone Nutzung von XMLHttpRequest zu entmutigen, ist HTML-Unterstützung im synchronen Modus nicht verfügbar. Außerdem ist HTML-Unterstützung nur verfügbar, wenn die responseType-Eigenschaft auf "document" gesetzt wurde. Diese Einschränkung vermeidet es, Zeit mit dem sinnlosen Parsen von HTML zu verschwenden, wenn Legacy-Code XMLHttpRequest im Standardmodus verwendet, um responseText für text/html-Ressourcen abzurufen. Ebenso vermeidet diese Einschränkung Probleme mit Legacy-Code, der davon ausgeht, dass responseXML null für HTTP-Fehlerseiten ist (die oft einen text/html-Response-Body haben).

Nutzung

Das Abrufen einer HTML-Ressource als DOM mit XMLHttpRequest funktioniert genauso wie das Abrufen einer XML-Ressource als DOM mit XMLHttpRequest, außer dass Sie nicht den synchronen Modus verwenden können und explizit ein Dokument anfordern müssen, indem Sie den String "document" der responseType-Eigenschaft des XMLHttpRequest-Objekts zuweisen, nachdem Sie open() aufgerufen haben, aber bevor Sie send() aufrufen.

js
const xhr = new XMLHttpRequest();
xhr.onload = () => {
  console.log(xhr.responseXML.title);
};
xhr.open("GET", "file.html");
xhr.responseType = "document";
xhr.send();

Funktionsprüfung

Methode 1

Diese Methode stützt sich auf die "force async"-Natur der Funktion. Wenn Sie versuchen, responseType eines XMLHttpRequest-Objekts einzustellen, nachdem es als "sync" geöffnet wurde. Dies wirft einen Fehler in den Browsern, die die Funktion implementieren, und funktioniert in anderen.

js
function HTMLinXHR() {
  if (!window.XMLHttpRequest) {
    return false;
  }
  const req = new window.XMLHttpRequest();
  req.open("GET", window.location.href, false);
  try {
    req.responseType = "document";
  } catch (e) {
    return true;
  }
  return false;
}

View on JSFiddle

Diese Methode ist synchron, verlässt sich nicht auf externe Ressourcen, mag jedoch nicht so zuverlässig sein wie Methode 2, die unten beschrieben wird, da sie nicht die tatsächliche Funktion, sondern ein Indiz für diese Funktion prüft.

Methode 2

Es gibt zwei Herausforderungen beim Erkennen, ob ein Browser HTML-Parsing in XMLHttpRequest genau unterstützt. Erstens wird das Erkennungsergebnis asynchron erhalten, da HTML-Unterstützung nur im asynchronen Modus verfügbar ist. Zweitens müssen Sie tatsächlich ein Testdokument über HTTP abrufen, da das Testen mit einer data:-URL gleichzeitig die Unterstützung von data:-URLs testen würde.

Um also HTML-Unterstützung zu erkennen, wird eine Test-HTML-Datei auf dem Server benötigt. Diese Testdatei ist klein und ist kein wohlgeformtes XML:

html
<title>&amp;&<</title>

Wenn die Datei detect.html genannt wird, kann die folgende Funktion zum Erkennen der HTML-Parsing-Unterstützung verwendet werden:

js
function detectHtmlInXhr(callback) {
  if (!window.XMLHttpRequest) {
    setTimeout(() => {
      callback(false);
    }, 0);

    return;
  }
  let done = false;
  const xhr = new window.XMLHttpRequest();
  xhr.onreadystatechange = () => {
    if (xhr.readyState === 4 && !done) {
      done = true;
      callback(
        !!(
          xhr.responseXML &&
          xhr.responseXML.title &&
          xhr.responseXML.title === "&&<"
        ),
      );
    }
  };
  xhr.onabort = xhr.onerror = () => {
    if (!done) {
      done = true;
      callback(false);
    }
  };
  try {
    xhr.open("GET", "detect.html");
    xhr.responseType = "document";
    xhr.send();
  } catch (e) {
    setTimeout(() => {
      if (!done) {
        done = true;
        callback(false);
      }
    }, 0);
  }
}

Das Argument callback ist eine Funktion, die asynchron mit true als einzigem Argument aufgerufen wird, wenn HTML-Parsing unterstützt wird, und mit false als einzigem Argument, wenn HTML-Parsing nicht unterstützt wird.

View on JSFiddle

Zeichencodierung

Wenn die Zeichencodierung im HTTP-Content-Type-Header angegeben ist, wird diese Zeichencodierung verwendet. Andernfalls, wenn ein Byte-Order-Mark vorhanden ist, wird die durch das Byte-Order-Mark angegebene Codierung verwendet. Andernfalls, wenn ein <meta>-Element innerhalb der ersten 1024 Bytes der Datei die Codierung angibt, wird diese Codierung verwendet. Andernfalls wird die Datei als UTF-8 decodiert.

Spezifikationen

Specification
XMLHttpRequest
# interface-xmlhttprequest

Browser-Kompatibilität

Siehe auch