Регистрация сетевых ошибок (NEL)

Введение

Регистрация сетевых ошибок (NEL) — это механизм сбора сетевых ошибок на стороне клиента от источника.

Он использует заголовок ответа HTTP NEL чтобы сообщить браузеру о необходимости сбора сетевых ошибок, а затем интегрируется с API отчетов, чтобы сообщать об ошибках на сервер.

Обзор устаревшего API отчетов

Чтобы использовать устаревший 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 .

Браузер сделает все возможное, чтобы доставить отчет не более чем в одну конечную точку в группе. Endpoints can be assigned a weight to distribute load, with each endpoint receiving a specified fraction of reporting traffic. Конечным точкам также можно назначить 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.

Отладка конфигураций отчетов

If you don't see reports showing up on your server, head over to 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}`);
});

Дальнейшее чтение