Start · Sprachen · JavaScript · Referenz · HTMLAnchorElement.ping

HTMLAnchorElement.ping

Eigenschaft

Liest oder setzt das <code>ping</code>-Attribut eines <code>&lt;a&gt;</code>-Elements, also eine durch Leerzeichen getrennte Liste von URLs, die beim Folgen des Links per POST benachrichtigt werden.

seit JavaScript Chrome, Edge, Safari, Opera; Firefox: vorhanden, V Kategorie: webapi

Signatur

HTMLAnchorElement.ping

Beschreibung

Die Eigenschaft ping spiegelt das HTML-Attribut ping eines <a>-Elements wider. Sie enthält eine durch Leerzeichen getrennte Liste von URLs. Folgt der Nutzer dem Link, schickt der Browser an jede dieser URLs im Hintergrund eine POST-Anfrage. Dieses Verfahren heißt Hyperlink Auditing. Die Navigation zum eigentlichen Ziel (href) läuft dabei ungebremst weiter.

Jede Ping-Anfrage hat den Körper PING und den Content-Type: text/ping. Dazu kommen die Header Ping-To (Ziel-URL des Links) und, je nach Referrer-Richtlinie, Ping-From (URL der aktuellen Seite). So lassen sich Klicks auf ausgehende Links zählen, ohne Weiterleitungsseiten wie /redirect?url=… und ohne JavaScript-Klickhandler, die die Navigation aufhalten.

Die Eigenschaft ist ein gewöhnlicher string. Wird ihr ein Wert zugewiesen, ändert sich das Attribut im DOM sofort. Mit einem leeren String schaltet man das Pinging für diesen Link ab. Der Browser prüft die URLs beim Setzen nicht, er zerlegt sie erst beim Klick.

Parameter

Name Typ Default Beschreibung
$value string "" Nur beim Setzen: eine durch Leerzeichen getrennte Liste absoluter oder relativer URLs. Relative URLs werden gegen die Basis-URL des Dokuments aufgelöst.

Rückgabewert

Typ
string
Beschreibung
Der aktuelle Wert des ping-Attributs genau so, wie er im Attribut steht (nicht normalisiert). Ist kein Attribut gesetzt, ist der Wert ein leerer String "".

Beispiele

Ping-URLs lesen und setzen

const link = document.createElement('a');
link.href = 'https://example.org/produkt';
link.textContent = 'Zum Produkt';

console.log(JSON.stringify(link.ping)); // noch kein Attribut

// Zwei Tracking-Endpunkte, durch Leerzeichen getrennt
link.ping = '/stats/klick https://analytics.example.com/ping';
document.body.append(link);

console.log(link.ping);
console.log(link.getAttribute('ping'));
console.log(link.ping.split(/\s+/).length);
"" /stats/klick https://analytics.example.com/ping /stats/klick https://analytics.example.com/ping 2

Alle ausgehenden Links mit einer Ping-URL versehen, falls unterstützt

const supportsPing = 'ping' in HTMLAnchorElement.prototype;

const externeLinks = [...document.querySelectorAll('a[href^="http"]')]
  .filter((a) => new URL(a.href).origin !== location.origin);

for (const a of externeLinks) {
  const ziel = encodeURIComponent(a.href);
  if (supportsPing) {
    // Vorhandene Pings erhalten, eigenen Endpunkt anhängen
    a.ping = [a.ping, `/stats/outbound?to=${ziel}`].filter(Boolean).join(' ');
  } else {
    // Ausweichlösung: Beacon beim Klick senden
    a.addEventListener('click', () => {
      navigator.sendBeacon(`/stats/outbound?to=${ziel}`);
    });
  }
}

console.log(`${externeLinks.length} externe Links vorbereitet`);
3 externe Links vorbereitet

Ping-Anfragen serverseitig empfangen (Node.js)

import { createServer } from 'node:http';

const server = createServer((req, res) => {
  if (req.method === 'POST' && req.headers['content-type'] === 'text/ping') {
    console.log('Ping-To:', req.headers['ping-to']);
    console.log('Ping-From:', req.headers['ping-from'] ?? '(nicht gesendet)');
    res.writeHead(204).end(); // Antwort wird vom Browser ignoriert
    return;
  }
  res.writeHead(404).end();
});

server.listen(3000, () => console.log('Ping-Empfänger auf Port 3000'));
Ping-Empfänger auf Port 3000 Ping-To: https://example.org/produkt Ping-From: https://meine-seite.de/

Pinging für einen Link abschalten

const link = document.querySelector('a[ping]');
if (link) {
  link.ping = ''; // oder: link.removeAttribute('ping')
  console.log(link.hasAttribute('ping'), JSON.stringify(link.ping));
}
true ""

// Wichtig · Fallstricke

  • Browser-Unterstützung: Chrome, Edge, Opera und Safari senden Pings. In Firefox gibt es die Eigenschaft, der Versand ist aber standardmäßig ausgeschaltet (Einstellung browser.send_pings). Auch Brave, viele Werbeblocker und Datenschutz-Erweiterungen unterdrücken Pings. Verlass dich deshalb für wichtige Statistiken nicht allein auf ping.
  • Feature-Erkennung: 'ping' in HTMLAnchorElement.prototype sagt nur, dass die Eigenschaft existiert. Ob der Browser tatsächlich sendet, verrät sie nicht (siehe Firefox).
  • Nur bei echter Link-Navigation: Pings werden nur gesendet, wenn der Nutzer dem Link folgt. Ein Sprung zu einem Anker im selben Dokument (#abschnitt) löst keinen Ping aus. Wird die Navigation mit preventDefault() abgebrochen oder läuft sie über location.href, gibt es ebenfalls keinen Ping. Nur http:- und https:-URLs werden angepingt.
  • Datenschutz: ping ist ein Tracking-Werkzeug. Ob Ping-From gesendet wird, hängt von referrerPolicy ab. Bei Anfragen an fremde Origins mit no-referrer fehlt der Header. Je nach Rechtslage (DSGVO, TTDSG) muss der Nutzer vorher einwilligen.
  • CORS: Pings an fremde Origins werden im Modus no-cors gesendet, standardmäßig ohne Zugangsdaten an Drittanbieter. Die Antwort des Servers ignoriert der Browser. 204 No Content ist die übliche Antwort.
  • Ausweichlösung: Für browserübergreifendes, zuverlässiges Klick-Tracking eignet sich navigator.sendBeacon() oder fetch(url, { keepalive: true }) in einem Klickhandler.