Введение
Регистрация сетевых ошибок (NEL) — это механизм сбора сетевых ошибок на стороне клиента от источника.
Он использует заголовок ответа HTTP NEL
чтобы сообщить браузеру о необходимости сбора сетевых ошибок, а затем интегрируется с API отчетов, чтобы сообщать об ошибках на сервер.
Обзор устаревшего API отчетов
Устаревший заголовок Report-To
Чтобы использовать устаревший API отчетов, вам необходимо установить HTTP-заголовок ответа Report-To
. Его значением является объект, описывающий группу конечных точек, в которую браузер будет сообщать об ошибках:
Report-To:
{
"max_age": 10886400,
"endpoints": [{
"url": "https://analytics.provider.com/browser-errors"
}]
}
Если URL-адрес вашей конечной точки находится в другом источнике, чем ваш сайт, конечная точка должна поддерживать предварительные запросы CORS. (например 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
).
В этом примере отправка этого заголовка ответа вместе с вашей главной страницей настраивает браузер на отправку сгенерированных браузером предупреждений в конечную точку https://analytics.provider.com/browser-errors
в течение max_age
секунд. Важно отметить, что все последующие HTTP-запросы страницы (изображений, скриптов и т. д.) игнорируются. Конфигурация настраивается во время ответа главной страницы.
Объяснение полей заголовка
Каждая конфигурация конечной точки содержит имя group
, max_age
и массив endpoints
. Вы также можете выбрать, следует ли учитывать субдомены при сообщении об ошибках, используя поле include_subdomains
.
Поле | Тип | Описание |
---|---|---|
group | нить | Необязательный. Если имя group не указано, конечной точке присваивается имя «по умолчанию». |
max_age | число | Необходимый . Неотрицательное целое число, определяющее время жизни конечной точки в секундах. Значение «0» приведет к удалению группы конечных точек из кэша отчетов пользовательского агента. |
endpoints | Массив<Объект> | Необходимый . Массив объектов JSON, определяющий фактический URL-адрес вашего сборщика отчетов. |
include_subdomains | логическое значение | Необязательный. Логическое значение, которое включает группу конечных точек для всех поддоменов хоста текущего источника. Если этот параметр опущен или имеет значение, отличное от «true», о поддоменах не сообщается конечной точке. |
Имя group
— это уникальное имя, используемое для связи строки с конечной точкой. Используйте это имя в других местах, которые интегрируются с API отчетов, для ссылки на определенную группу конечных точек.
Поле max-age
также является обязательным и указывает, как долго браузер должен использовать конечную точку и сообщать ей об ошибках.
Поле endpoints
представляет собой массив, обеспечивающий функции аварийного переключения и балансировки нагрузки. См. раздел «Отработка отказа и балансировка нагрузки» . Важно отметить, что браузер выберет только одну конечную точку , даже если в группе endpoints
указано несколько сборщиков. Если вы хотите отправить отчет на несколько серверов одновременно, вашему серверу необходимо будет пересылать отчеты.
Как браузер отправляет отчеты?
Браузер периодически группирует отчеты и отправляет их на настроенные вами конечные точки отчетов.
Для отправки отчетов браузер отправляет запрос POST
с Content-Type: application/reports+json
и телом, содержащим массив зафиксированных предупреждений/ошибок.
Когда браузер отправляет отчеты?
Отчеты доставляются из вашего приложения вне канала , то есть браузер контролирует отправку отчетов на ваши серверы.
Браузер пытается доставить отчеты в очереди в наиболее подходящее время. Это может произойти, как только они будут готовы (чтобы обеспечить своевременную обратную связь с разработчиком), но браузер также может задержать доставку, если он занят обработкой более приоритетной работы или если пользователь находится в медленной и/или перегруженной сети. время. Браузер также может установить приоритет отправки отчетов об определенном источнике в первую очередь, если пользователь является частым посетителем.
При использовании API отчетов практически не возникает проблем с производительностью (например, сетевых конфликтов с вашим приложением). Также невозможно контролировать, когда браузер отправляет отчеты в очереди.
Настройка нескольких конечных точек
Один ответ может настроить несколько конечных точек одновременно, отправив несколько заголовков Report-To
:
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"
}]
}
или объединив их в один HTTP-заголовок:
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"
}]
}
После того, как вы отправили заголовок Report-To
, браузер кэширует конечные точки в соответствии с их значениями max_age
и отправляет все эти неприятные предупреждения/ошибки консоли на ваши URL-адреса.
Аварийное переключение и балансировка нагрузки
Большую часть времени вам придется настраивать один сборщик URL-адресов для каждой группы. Однако, поскольку отчеты могут генерировать большой объем трафика, спецификация включает функции аварийного переключения и балансировки нагрузки, основанные на записи DNS SRV .
Браузер сделает все возможное, чтобы доставить отчет не более чем в одну конечную точку в группе. Конечным точкам можно назначить weight
для распределения нагрузки, при этом каждая конечная точка будет получать определенную долю отчетного трафика. Конечным точкам также можно назначить priority
для настройки резервных сборщиков.
Резервные сборщики пробуются только в случае сбоя загрузки на основные сборщики.
Пример . Создайте резервный сборщик по адресу https://backup.com/reports
:
Report-To: {
"group": "endpoint-1",
"max_age": 10886400,
"endpoints": [
{"url": "https://example.com/reports", "priority": 1},
{"url": "https://backup.com/reports", "priority": 2}
]
}
Настройка журнала сетевых ошибок
Настраивать
Чтобы использовать NEL, настройте заголовок Report-To
с помощью сборщика, который использует именованную группу:
Report-To: {
...
}, {
"group": "network-errors",
"max_age": 2592000,
"endpoints": [{
"url": "https://analytics.provider.com/networkerrors"
}]
}
Затем отправьте заголовок ответа NEL
, чтобы начать сбор ошибок. Поскольку NEL поддерживает источник, вам нужно отправить заголовок только один раз. И NEL
, и Report-To
будут применяться к будущим запросам к тому же источнику и продолжат собирать ошибки в соответствии со значением max_age
, которое использовалось для настройки сборщика.
Значение заголовка должно быть объектом JSON, содержащим поля max_age
и report_to
. Используйте последнее для ссылки на имя группы вашего сборщика сетевых ошибок:
GET /index.html HTTP/1.1
NEL: {"report_to": "network-errors", "max_age": 2592000}
Подресурсы
Пример : если example.com
загружает foobar.com/cat.gif
и этот ресурс не загружается:
- Коллекционер NEL
foobar.com
уведомлен - Сборщик NEL на
example.com
не уведомлен
Эмпирическое правило заключается в том, что NEL воспроизводит журналы на стороне сервера, только что созданные на клиенте.
Поскольку example.com
не имеет доступа к журналам сервера foobar.com
, он также не имеет доступа к своим отчетам NEL.
Отладка конфигураций отчетов
Если вы не видите отчеты на своем сервере, перейдите на chrome://net-export/
. Эта страница полезна для проверки правильности настройки и правильной отправки отчетов.
А как насчет ReportingObserver?
ReportingObserver
— это родственный, но другой механизм отчетности. Он основан на вызовах JavaScript. Он не подходит для регистрации сетевых ошибок , поскольку сетевые ошибки невозможно перехватить с помощью JavaScript.
Пример сервера
Ниже приведен пример Node-сервера, использующего Express. Он показывает, как настроить отчеты о сетевых ошибках, и создает специальный обработчик для сбора результатов.
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}`);
});