简介
网络错误日志记录 (NEL) 是一种 从源收集客户端网络连接错误。
它使用 NEL
HTTP 响应标头告知浏览器收集网络连接错误,然后与 Reporting API 集成以将错误报告给服务器。
旧版 Reporting API 概览
旧版 Report-To
标头
要使用旧版 Reporting API,您需要设置 Report-To
HTTP 响应标头。其
值是一个对象,用于描述浏览器的端点组
将错误报告给:
Report-To:
{
"max_age": 10886400,
"endpoints": [{
"url": "https://analytics.provider.com/browser-errors"
}]
}
如果您的端点网址与您的网站位于不同的源,
端点应支持 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 名称,则会将端点名称指定为“default”。 |
max_age |
number | 必需。一个非负整数,用于定义端点的生命周期(以秒为单位)。值为“0”会使端点组从用户代理的报告缓存中移除。 |
endpoints |
数组<对象> | 必需。一组 JSON 对象,用于指定报告收集器的实际网址。 |
include_subdomains |
布尔值 | 可选。一个布尔值,用于为当前源主机的所有子网域启用端点组。如果省略此参数或设置除“true”以外的任何其他值,则系统不会将子网域报告给端点。 |
group
名称是用于将字符串与
端点。在集成
使用 Reporting API 引用特定的端点组。
max-age
字段也是必填字段,用于指定
则浏览器应使用该端点并向其报告错误。
endpoints
字段是一个数组,用于提供故障切换和负载均衡功能
功能。请参阅故障切换和负载均衡部分。时间是
请务必注意,浏览器只会选择一个端点,即使
如果该组在 endpoints
中列出了多个收集器,则会发生此错误。如果您想发送
同时向多个服务器发送报告,您的后端需要将
报告。
浏览器如何发送报告?
浏览器会定期批量发送报告,并将其发送到 您配置的端点。
为了发送报告,浏览器会发出一个 POST
请求
Content-Type: application/reports+json
以及包含
捕获的警告/错误。
浏览器何时发送报告?
报告是从您的应用带外传送的,也就是说浏览器 控制何时向您的服务器发送报告。
浏览器会尝试 在最合适的时间传送已加入队列的报告。系统可能会在相关工作准备就绪后立即更新(以便提供 及时向开发者提供反馈),但如果存在延迟,浏览器也会延迟 正忙于处理优先级较高的工作,或者用户运行速度缓慢且/或 当时网络处于拥塞状态 浏览器也可能会优先发送 如果用户是常客,系统会优先报告特定来源的相关信息。
几乎没有性能问题 (例如,与您的应用进行网络争用)。还有 也无法控制浏览器何时发送排队的报告。
配置多个端点
单个响应可以通过发送
多个 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
值,将所有这些讨厌的控制台
警告/错误。
故障切换和负载均衡
大多数情况下,您需要为每个群组配置一个网址收集器。不过, 由于报告可以产生大量流量,因此该规范包含故障切换功能, 以及受 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
将应用于以后向同一来源发出的请求,并会持续
根据用于设置 YouTube 的 max_age
值收集错误
收集器。
标头值应为包含 max_age
和
report_to
字段。后者应引用您
网络错误收集器:
GET /index.html HTTP/1.1
NEL: {"report_to": "network-errors", "max_age": 2592000}
子资源
示例:如果 example.com
加载 foobar.com/cat.gif
,而该资源失败
以加载:
foobar.com
的 NEL 收集器会收到通知example.com
的 NEL 收集器不会收到通知
通过 一般来说,NEL 会重现服务器端日志, 客户端。
由于 example.com
无法获知 foobar.com
的服务器
日志,也无法查看其 NEL 报告。
调试报告配置
如果服务器上没有显示报告,请访问
chrome://net-export/
。这个网页对于
验证配置是否正确,以及是否发送了报告
正确输出。
ReportingObserver 怎么样?
ReportingObserver
是相关但不同的举报机制。它基于 JavaScript 调用。
它不适用于网络错误日志记录,因为网络错误
无法通过 JavaScript 拦截。
示例服务器
以下是一个使用 Express 的 Node 服务器示例。它展示了如何配置网络错误报告,并创建专用处理程序来捕获结果。
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}`);
});