Einführung
Network Error Logging (NEL) ist ein Mechanismus zum Erfassen von clientseitigen Netzwerkfehlern von einem Ursprung.
Dabei wird der HTTP-Antwortheader NEL verwendet, um den Browser anzuweisen, Netzwerkfehler zu erfassen. Anschließend werden die Fehler mit der Reporting API an einen Server gemeldet.
Übersicht über die alte Reporting API
Der alte Report-To-Header
Wenn Sie die alte Reporting API verwenden möchten, müssen Sie einen Report-To-HTTP-Antwortheader festlegen. Sein Wert ist ein Objekt, das eine Endpunktgruppe beschreibt, an die der Browser Fehler melden soll:
Report-To:
{
"max_age": 10886400,
"endpoints": [{
"url": "https://analytics.provider.com/browser-errors"
}]
}
Wenn sich die Endpunkt-URL an einem anderen Ursprung als Ihre Website befindet, muss der Endpunkt CORS-Preflight-Anfragen unterstützen. Beispiel: Access-Control-Allow-Origin: *; Access-Control-Allow-Methods: GET,PUT,POST,DELETE,OPTIONS; Access-Control-Allow-Headers: Content-Type, Authorization, Content-Length, X-Requested-With.
Im Beispiel wird durch Senden dieses Antwortheaders mit der Hauptseitenkonfiguration der Browser so konfiguriert, dass browsergenerierte Warnungen für max_age Sekunden an den Endpunkt https://analytics.provider.com/browser-errors gemeldet werden.
Alle nachfolgenden HTTP-Anfragen der Seite (für Bilder, Skripts usw.) werden ignoriert. Die Konfiguration wird während der Antwort der Hauptseite eingerichtet.
Erläuterung der Headerfelder
Jede Endpunktkonfiguration enthält einen group-Namen, max_age und ein endpoints-Array. Sie können auch festlegen, ob Unterdomains bei der Meldung von Fehlern berücksichtigt werden sollen. Verwenden Sie dazu das Feld include_subdomains.
| Feld | Typ | Beschreibung |
|---|---|---|
group |
String | Optional. Wenn kein group-Name angegeben ist, erhält der Endpunkt den Namen „default“. |
max_age |
Zahl | Erforderlich. Eine nicht negative Ganzzahl, die die Lebensdauer des Endpunkts in Sekunden definiert. Der Wert „0“ führt dazu, dass die Endpunktgruppe aus dem Berichtscache des User-Agents entfernt wird. |
endpoints |
Array<Object> | Erforderlich. Ein Array von JSON-Objekten, die die tatsächliche URL Ihres Berichtscollectors angeben. |
include_subdomains |
boolean | Optional. Ein boolescher Wert, der die Endpunktgruppe für alle Unterdomains des Hosts des aktuellen Ursprungs aktiviert. Wenn dieser Wert nicht angegeben wird oder etwas anderes als „true“ ist, werden die Unterdomains nicht an den Endpunkt gemeldet. |
Der group-Name ist ein eindeutiger Name, der verwendet wird, um einen String mit einem Endpunkt zu verknüpfen. Verwenden Sie diesen Namen an anderen Stellen, die in die Reporting API eingebunden sind, um auf eine bestimmte Endpunktgruppe zu verweisen.
Das Feld max-age ist ebenfalls erforderlich und gibt an, wie lange der Browser den Endpunkt verwenden und Fehler an ihn melden soll.
Das Feld endpoints ist ein Array, das Failover- und Load-Balancing-Funktionen bietet. Weitere Informationen finden Sie im Abschnitt zu Failover und Load-Balancing. Es ist wichtig zu beachten, dass der Browser nur einen Endpunkt auswählt, auch wenn in der Gruppe mehrere Collector in endpoints aufgeführt sind. Wenn Sie einen Bericht gleichzeitig an mehrere Server senden möchten, muss Ihr Back-End die Berichte weiterleiten.
Wie sendet der Browser Berichte?
Der Browser fasst Berichte regelmäßig zusammen und sendet sie an die von Ihnen konfigurierten Berichtsendpunkte.
Zum Senden von Berichten gibt der Browser eine POST-Anfrage mit Content-Type: application/reports+json und einem Textkörper aus, der das Array der erfassten Warnungen/Fehler enthält.
Wann sendet der Browser Berichte?
Berichte werden außerhalb Ihrer App gesendet. Das bedeutet, dass der Browser steuert, wann Berichte an Ihre Server gesendet werden.
Der Browser versucht, Berichte in der Warteschlange zum bestmöglichen Zeitpunkt zu senden. Das kann so bald wie möglich sein (um dem Entwickler zeitnah Feedback zu geben), aber der Browser kann die Übermittlung auch verzögern, wenn er mit der Verarbeitung von Aufgaben mit höherer Priorität beschäftigt ist oder wenn der Nutzer zu diesem Zeitpunkt ein langsames und/oder überlastetes Netzwerk verwendet. Der Browser kann auch Berichte zu einem bestimmten Ursprung zuerst senden, wenn der Nutzer die Website häufig besucht.
Bei der Verwendung der Reporting API gibt es kaum oder gar keine Leistungsprobleme (z.B. Netzwerkkonflikte mit Ihrer App). Außerdem lässt sich nicht steuern, wann der Browser Berichte in der Warteschlange sendet.
Mehrere Endpunkte konfigurieren
Mit einer einzigen Antwort können mehrere Endpunkte gleichzeitig konfiguriert werden, indem mehrere Report-To-Header gesendet werden:
Report-To: {
"group": "default",
"max_age": 10886400,
"endpoints": [{
"url": "https://example.com/browser-reports"
}]
}
Report-To: {
"group": "network-errors-endpoint",
"max_age": 10886400,
"endpoints": [{
"url": "https://example.com/network-errors"
}]
}
oder indem sie in einem einzigen HTTP-Header kombiniert werden:
Report-To: {
"group": "network-errors-endpoint",
"max_age": 10886400,
"endpoints": [{
"url": "https://example.com/network-errors"
}]
},
{
"max_age": 10886400,
"endpoints": [{
"url": "https://example.com/browser-errors"
}]
}
Nachdem Sie den Report-To-Header gesendet haben, speichert der Browser die Endpunkte gemäß ihren max_age-Werten im Cache und sendet alle diese lästigen Konsolenwarnungen/-fehler an Ihre URLs.
Failover und Load-Balancing
In den meisten Fällen konfigurieren Sie einen URL-Collector pro Gruppe. Da die Berichterstellung jedoch viel Traffic verursachen kann, enthält die Spezifikation Failover- und Load-Balancing-Funktionen, die vom DNS-SRV-Eintrag inspiriert sind.
Der Browser versucht, einen Bericht an höchstens einen Endpunkt in einer Gruppe zu senden. Endpunkten kann ein weight-Wert zugewiesen werden, um die Last zu verteilen. Jeder Endpunkt erhält einen bestimmten Anteil des Berichtstraffics. Endpunkten kann auch eine priority zugewiesen werden, um Fallback-Collector einzurichten.
Fallback-Collector werden nur verwendet, wenn Uploads zu primären Collectoren fehlschlagen.
Beispiel: Fallback-Collector unter https://backup.com/reports erstellen:
Report-To: {
"group": "endpoint-1",
"max_age": 10886400,
"endpoints": [
{"url": "https://example.com/reports", "priority": 1},
{"url": "https://backup.com/reports", "priority": 2}
]
}
Network Error Logging einrichten
Einrichtung
Wenn Sie NEL verwenden möchten, richten Sie den Report-To-Header mit einem Collector ein, der eine benannte Gruppe verwendet:
Report-To: {
...
}, {
"group": "network-errors",
"max_age": 2592000,
"endpoints": [{
"url": "https://analytics.provider.com/networkerrors"
}]
}
Senden Sie als Nächstes den NEL-Antwortheader, um Fehler zu erfassen. Da NEL für einen Ursprung optional ist, müssen Sie den Header nur einmal senden. Sowohl NEL als auch Report-To gelten für zukünftige Anfragen an denselben Ursprung und erfassen weiterhin Fehler gemäß dem max_age-Wert, der zum Einrichten des Collectors verwendet wurde.
Der Headerwert sollte ein JSON-Objekt mit den Feldern max_age und report_to sein. Verwenden Sie Letzteres, um auf den Gruppennamen Ihres Network Error-Collectors zu verweisen:
GET /index.html HTTP/1.1
NEL: {"report_to": "network-errors", "max_age": 2592000}
Unterressourcen
Beispiel: Wenn example.com die Ressource foobar.com/cat.gif lädt und das Laden dieser Ressource fehlschlägt:
- Der NEL-Collector von
foobar.comwird benachrichtigt. - Der NEL-Collector von
example.comwird nicht benachrichtigt.
Als Faustregel gilt, dass NEL serverseitige Logs reproduziert, die nur auf dem Client generiert werden.
Da example.com keinen Einblick in die Serverlogs von foobar.com hat, hat es auch keinen Einblick in die NEL-Berichte.
Berichtskonfigurationen debuggen
Wenn auf Ihrem Server keine Berichte angezeigt werden, rufen Sie chrome://net-export/ auf. Auf dieser Seite können Sie prüfen, ob alles richtig konfiguriert ist und Berichte ordnungsgemäß gesendet werden.
Was ist mit ReportingObserver?
ReportingObserver ist ein verwandter, aber anderer Berichtsmechanismus. Er basiert auf JavaScript-Aufrufen.
Er ist nicht für Network Error Logging geeignet, da Netzwerkfehler
nicht über JavaScript abgefangen werden können.
Beispielserver
Unten sehen Sie einen Beispiel-Node-Server, der Express verwendet. Dort wird gezeigt, wie Sie die Berichterstellung für Netzwerkfehler konfigurieren und einen dedizierten Handler erstellen, um das Ergebnis zu erfassen.
const express = require('express');
const app = express();
app.use(
express.json({
type: ['application/json', 'application/reports+json'],
}),
);
app.use(express.urlencoded());
app.get('/', (request, response) => {
// Note: report_to and not report-to for NEL.
response.set('NEL', `{"report_to": "network-errors", "max_age": 2592000}`);
// The Report-To header tells the browser where to send network errors.
// The default group (first example below) captures interventions and
// deprecation reports. Other groups, like the network-error group, are referenced by their "group" name.
response.set(
'Report-To',
`{
"max_age": 2592000,
"endpoints": [{
"url": "https://reporting-observer-api-demo.glitch.me/reports"
}],
}, {
"group": "network-errors",
"max_age": 2592000,
"endpoints": [{
"url": "https://reporting-observer-api-demo.glitch.me/network-reports"
}]
}`,
);
response.sendFile('./index.html');
});
function echoReports(request, response) {
// Record report in server logs or otherwise process results.
for (const report of request.body) {
console.log(report.body);
}
response.send(request.body);
}
app.post('/network-reports', (request, response) => {
console.log(`${request.body.length} Network error reports:`);
echoReports(request, response);
});
const listener = app.listen(process.env.PORT, () => {
console.log(`Your app is listening on port ${listener.address().port}`);
});