如何解析通过 Report-To header 端点报告的 NEL(网络错误记录)错误?
How to parse NEL (Network Error Logging) errors reported through Report-To header endpoint?
我正在使用库 Network Error Logging to add NEL
header and report-to 在我的 Express.js 服务器上添加 Report-To
header。
我的代码是这样的
app.use(reportTo({
groups: [
{
group: 'default',
max_age: 31536000,
include_subdomains: true,
endpoints: [
{
url: myReportToURL,
priority: 1,
},
],
},
],
}));
app.use(NEL({
report_to: 'default',
max_age: 31536000,
include_subdomains: true,
}));
有关它们的更多信息,请访问
- https://www.w3.org/TR/reporting/
- https://www.w3.org/TR/network-error-logging/#network-error-reports
- https://scotthelme.co.uk/network-error-logging-deep-dive/
我以前使用 https://report-uri.com 来收集 NEL 错误,效果很好。
它收集了不同类型的 NEL 错误,如屏幕截图所示:
但是,现在我想构建自己的错误解析器,然后进行收集。
我从 CSP 错误解析器中得到了见解,根据 我可以通过
解析
bodyParser.json({ type: 'application/json' });
bodyParser.json({ type: 'application/csp-report' });
对于 NEL,我发现了这个 https://w3c.github.io/reporting/#media-type-registration
那么我应该这样解析吗?
bodyParser.json({ type: 'application/reports+json' });
或者是什么意思?
bodyParser.json({ type: 'application/json' });
bodyParser.json({ type: 'application/reports' });
如果有人知道如何在本地触发 NEL 错误,那对测试也很有帮助。谢谢!
更新 1(2020 年 10 月 14 日)
发现 one W3C example 正在使用 application/reports+json
。
Another W3C example 正在使用 application/report
(注意没有 s
)。
所以我在 here 的 W3C GitHub 创建了一个请求单。
更新 2(2020 年 10 月 14 日)
我已请求 fix W3C 文档问题。正确的格式是 application/reports+json
.
关于如何在本地触发 NEL 错误。 Express.js NEL 和 Report-To 库作者 James (@Cherry) 在 GitHub 上 here 得到了一个建议。所以我尝试连接 https://fakedomainabccba.com
以获得 dns.name_not_resolved
或类似的 DNS 错误。
但是,Chrome 88.0.4291.0 并没有发送 NEL 错误,也没有显示在网络选项卡中。
更新 3(2020 年 10 月 16 日)
这是我最新的代码。我尝试通过使用两个端点进行比较来登录到 Report URI 和我自己的服务器。报告 URI 确实收到了新报告,但是,我的服务器仍然有问题。
(网站和 API 域相同,所以我不应该有 CORS 问题。如果它被 CORS 阻止,我可以在日志中看到它。)
app.use(reportTo({
groups: [
{
group: 'default',
max_age: 31536000,
include_subdomains: true,
endpoints: [
{
url: 'https://xxx.report-uri.com/xxx', // Report URI still works
priority: 1,
},
{
url: 'https://www.example.com/api/report-to', // "example" is my domain currently still has issue
priority: 1,
},
],
},
],
}));
app.use(NEL({
report_to: 'default',
max_age: 31536000,
include_subdomains: true,
}));
router.post('/api/report-to', bodyParser.json({ type: 'application/reports+json' }), (req, res) => {
console.log('reportTo', req.body);
res.sendStatus(200);
});
更新 4(工作解决方案,10/28/2020)
感谢@IanClelland 的帮助!在我删除 URL 中误用的内部端口后,它现在可以工作了。也证实了,正如 Ian 提到的
The Reporting API will only deliver to a single endpoint, to minimize outgoing bandwidth, and so that people who use multiple endpoints for redundancy don't double-count reports.
所以最终的工作版本看起来像
app.use(reportTo({
groups: [
{
group: 'default',
max_age: 31536000,
include_subdomains: true,
endpoints: [
{
url: 'https://www.example.com/api/report-to',
priority: 1,
},
],
},
],
}));
app.use(NEL({
report_to: 'default',
max_age: 31536000,
include_subdomains: true,
}));
router.post('/api/report-to', bodyParser.json({ type: 'application/reports+json' }), (req, res) => {
console.log('reportTo', req.body);
res.sendStatus(200);
});
我收到的成功日志看起来像
{
"age":42187,
"body":{
"elapsed_time":674,
"method":"GET",
"phase":"application",
"protocol":"h2",
"referrer":"",
"sampling_fraction":1,
"server_ip":"2606:4700:3032::681b:b258",
"status_code":404,
"type":"http.error"
},
"type":"network-error",
"url":"https://www.example.com/undefined",
"user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4305.0 Safari/537.36"
}
如果您 https://report-uri.com 工作了,那么您可能已经完成了大部分工作。
现在很难准确地说出什么对您不起作用,但有几点可能会有所帮助:
application/reports+json
是正确的内容类型;解释器不正确。 (谢谢,我会解决的。)
- 触发报告的站点和报告端点都需要使用 HTTPS; Chrome 将从其缓存中删除任何不安全的端点。
- 如果报告端点与您的站点位于不同的来源,则它将需要支持 CORS:您需要处理 CORS 预检请求以允许请求继续。
- 您不会在 Devtools 网络选项卡中看到报告; Chrome 在浏览器进程中将它们单独排队,然后在任何特定浏览器选项卡之外发送它们。它们通常会在一分钟内发送,但如果发送失败,Chrome 会重试几次然后放弃。从chrome://net-export/导出网络日志,然后在https://netlog-viewer.appspot.com/
查看,就可以看到网络交换
我正在使用库 Network Error Logging to add NEL
header and report-to 在我的 Express.js 服务器上添加 Report-To
header。
我的代码是这样的
app.use(reportTo({
groups: [
{
group: 'default',
max_age: 31536000,
include_subdomains: true,
endpoints: [
{
url: myReportToURL,
priority: 1,
},
],
},
],
}));
app.use(NEL({
report_to: 'default',
max_age: 31536000,
include_subdomains: true,
}));
有关它们的更多信息,请访问
- https://www.w3.org/TR/reporting/
- https://www.w3.org/TR/network-error-logging/#network-error-reports
- https://scotthelme.co.uk/network-error-logging-deep-dive/
我以前使用 https://report-uri.com 来收集 NEL 错误,效果很好。
它收集了不同类型的 NEL 错误,如屏幕截图所示:
但是,现在我想构建自己的错误解析器,然后进行收集。
我从 CSP 错误解析器中得到了见解,根据
bodyParser.json({ type: 'application/json' });
bodyParser.json({ type: 'application/csp-report' });
对于 NEL,我发现了这个 https://w3c.github.io/reporting/#media-type-registration
那么我应该这样解析吗?
bodyParser.json({ type: 'application/reports+json' });
或者是什么意思?
bodyParser.json({ type: 'application/json' });
bodyParser.json({ type: 'application/reports' });
如果有人知道如何在本地触发 NEL 错误,那对测试也很有帮助。谢谢!
更新 1(2020 年 10 月 14 日)
发现 one W3C example 正在使用 application/reports+json
。
Another W3C example 正在使用 application/report
(注意没有 s
)。
所以我在 here 的 W3C GitHub 创建了一个请求单。
更新 2(2020 年 10 月 14 日)
我已请求 fix W3C 文档问题。正确的格式是 application/reports+json
.
关于如何在本地触发 NEL 错误。 Express.js NEL 和 Report-To 库作者 James (@Cherry) 在 GitHub 上 here 得到了一个建议。所以我尝试连接 https://fakedomainabccba.com
以获得 dns.name_not_resolved
或类似的 DNS 错误。
但是,Chrome 88.0.4291.0 并没有发送 NEL 错误,也没有显示在网络选项卡中。
更新 3(2020 年 10 月 16 日)
这是我最新的代码。我尝试通过使用两个端点进行比较来登录到 Report URI 和我自己的服务器。报告 URI 确实收到了新报告,但是,我的服务器仍然有问题。
(网站和 API 域相同,所以我不应该有 CORS 问题。如果它被 CORS 阻止,我可以在日志中看到它。)
app.use(reportTo({
groups: [
{
group: 'default',
max_age: 31536000,
include_subdomains: true,
endpoints: [
{
url: 'https://xxx.report-uri.com/xxx', // Report URI still works
priority: 1,
},
{
url: 'https://www.example.com/api/report-to', // "example" is my domain currently still has issue
priority: 1,
},
],
},
],
}));
app.use(NEL({
report_to: 'default',
max_age: 31536000,
include_subdomains: true,
}));
router.post('/api/report-to', bodyParser.json({ type: 'application/reports+json' }), (req, res) => {
console.log('reportTo', req.body);
res.sendStatus(200);
});
更新 4(工作解决方案,10/28/2020)
感谢@IanClelland 的帮助!在我删除 URL 中误用的内部端口后,它现在可以工作了。也证实了,正如 Ian 提到的
The Reporting API will only deliver to a single endpoint, to minimize outgoing bandwidth, and so that people who use multiple endpoints for redundancy don't double-count reports.
所以最终的工作版本看起来像
app.use(reportTo({
groups: [
{
group: 'default',
max_age: 31536000,
include_subdomains: true,
endpoints: [
{
url: 'https://www.example.com/api/report-to',
priority: 1,
},
],
},
],
}));
app.use(NEL({
report_to: 'default',
max_age: 31536000,
include_subdomains: true,
}));
router.post('/api/report-to', bodyParser.json({ type: 'application/reports+json' }), (req, res) => {
console.log('reportTo', req.body);
res.sendStatus(200);
});
我收到的成功日志看起来像
{
"age":42187,
"body":{
"elapsed_time":674,
"method":"GET",
"phase":"application",
"protocol":"h2",
"referrer":"",
"sampling_fraction":1,
"server_ip":"2606:4700:3032::681b:b258",
"status_code":404,
"type":"http.error"
},
"type":"network-error",
"url":"https://www.example.com/undefined",
"user_agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4305.0 Safari/537.36"
}
如果您 https://report-uri.com 工作了,那么您可能已经完成了大部分工作。
现在很难准确地说出什么对您不起作用,但有几点可能会有所帮助:
application/reports+json
是正确的内容类型;解释器不正确。 (谢谢,我会解决的。)- 触发报告的站点和报告端点都需要使用 HTTPS; Chrome 将从其缓存中删除任何不安全的端点。
- 如果报告端点与您的站点位于不同的来源,则它将需要支持 CORS:您需要处理 CORS 预检请求以允许请求继续。
- 您不会在 Devtools 网络选项卡中看到报告; Chrome 在浏览器进程中将它们单独排队,然后在任何特定浏览器选项卡之外发送它们。它们通常会在一分钟内发送,但如果发送失败,Chrome 会重试几次然后放弃。从chrome://net-export/导出网络日志,然后在https://netlog-viewer.appspot.com/ 查看,就可以看到网络交换