您可以使用 Reporting API 监控违规问题、已弃用的 API 调用等。
有些错误只发生在生产环境中。您无法在本地或直播期间看到这些消息 因为真实用户、真实网络和真实设备 改变游戏。Reporting API 可帮助捕捉其中一些错误,如 视为违规,或者已弃用且即将弃用的 API 并将这些调用传输到您的 。
它可让您通过 HTTP 标头声明要监控的内容, 由浏览器运行。
设置 Reporting API 后,当用户遇到 您就会知道这些类型的错误,以便解决这些问题。
本文介绍此 API 的功能和使用方法。现在就开始吧!
演示和代码
从以下时间开始查看 Reporting API 的实际应用: Chrome 96 及更高版本 (Chrome Beta 版或 Canary 版)。
概览
<ph type="x-smartling-placeholder">我们假设您的网站 (site.example
) 同时设置了内容安全政策和文档政策。不知道这些方法有什么用?没关系,您仍然处于
能够理解这个示例。
您决定监控自己的网站,以便了解您的网站在哪些情况下违反了这些政策,但这还因为一个原因: 您需要关注代码库可能正在使用的已废弃或即将弃用的 API。
为此,您可以配置 Reporting-Endpoints
标头,并映射这些端点
根据需要通过政策中的 report-to
指令指定该目录。
Reporting-Endpoints: main-endpoint="https://reports.example/main", default="https://reports.example/default"
# Content-Security-Policy violations and Document-Policy violations
# will be sent to main-endpoint
Content-Security-Policy: script-src 'self'; object-src 'none'; report-to main-endpoint;
Document-Policy: document-write=?0; report-to=main-endpoint;
# Deprecation reports don't need an explicit endpoint because
# these reports are always sent to the `default` endpoint
出现了不可预见的情况, 用户。
违规行为示例
index.html
<script src="script.js"></script>
<!-- CSP VIOLATION: Try to load a script that's forbidden as per the Content-Security-Policy -->
<script src="https://example.com/script.js"></script>
script.js
,加载者:index.html
// DOCUMENT-POLICY VIOLATION: Attempt to use document.write despite the document policy
try {
document.write('<h1>hi</h1>');
} catch (e) {
console.log(e);
}
// DEPRECATION: Call a deprecated API
const webkitStorageInfo = window.webkitStorageInfo;
浏览器生成 CSP 违规报告、文档违规报告以及弃用 来找出这些问题的报告
在短暂的延迟(最多一分钟)后,浏览器会将报告发送到 此违规类型配置的端点。报告会发送到 带外 (而不是由您的服务器或您的网站进行)。
端点接收这些报告。
现在,您可以访问这些端点上的报告并监控出了什么问题。 您已准备好开始排查影响用户的问题。
示例报告
{
"age": 2,
"body": {
"blockedURL": "https://site2.example/script.js",
"disposition": "enforce",
"documentURL": "https://site.example",
"effectiveDirective": "script-src-elem",
"originalPolicy": "script-src 'self'; object-src 'none'; report-to main-endpoint;",
"referrer": "https://site.example",
"sample": "",
"statusCode": 200
},
"type": "csp-violation",
"url": "https://site.example",
"user_agent": "Mozilla/5.0... Chrome/92.0.4504.0"
}
用例和报告类型
通过配置 Reporting API,您可以监控多种值得关注的警告或问题 出现的所有问题
报告类型 | 生成报告的情况示例 |
---|---|
CSP 违规行为(仅限级别 3) | 您在自己的一个网页上设置了Content-Security-Policy (CSP),但该网页正尝试加载您的 CSP 不允许使用的脚本。 |
违反 COOP | 您已在网页上设置了 Cross-Origin-Opener-Policy ,但跨源窗口正尝试与文档直接互动。 |
违反 COEP | 您在某网页上设置了 Cross-Origin-Embedder-Policy ,但该文档包含未选择让跨源文档加载的跨源 iframe。 |
违反文档政策 | 该网页的某项文档政策禁止使用 document.write ,但脚本会尝试调用 document.write 。 |
违反权限政策 | 该页面包含一个禁止使用麦克风的权限政策,以及一个请求音频输入的脚本。 |
弃用警告 | 网页使用的 API 已弃用或即将弃用;它可以直接调用它,也可以通过顶级第三方脚本调用它。 |
干预 | 出于安全、性能或用户体验方面的原因,网页正在尝试执行浏览器决定不认可的操作。Chrome 中的示例:网页在慢速网络上使用 document.write ,或者在用户尚未互动过的跨源帧中调用 navigator.vibrate 。 |
崩溃 | 在您的网站打开时,浏览器崩溃。 |
报告
报告的外观是怎样的?
浏览器会向您已配置的端点发送报告。它会发送如下所示的请求:
POST
Content-Type: application/reports+json
这些请求的负载是一个报告列表。
报告列表示例
[
{
"age": 420,
"body": {
"columnNumber": 12,
"disposition": "enforce",
"lineNumber": 11,
"message": "Document policy violation: document-write is not allowed in this document.",
"policyId": "document-write",
"sourceFile": "https://site.example/script.js"
},
"type": "document-policy-violation",
"url": "https://site.example/",
"user_agent": "Mozilla/5.0... Chrome/92.0.4504.0"
},
{
"age": 510,
"body": {
"blockedURL": "https://site.example/img.jpg",
"destination": "image",
"disposition": "enforce",
"type": "corp"
},
"type": "coep",
"url": "https://dummy.example/",
"user_agent": "Mozilla/5.0... Chrome/92.0.4504.0"
}
]
以下是您可以在各种报告中找到的数据:
字段 | 说明 |
---|---|
age |
报告的时间戳与当前时间之间的毫秒数。 |
body |
实际报告数据,已序列化为 JSON 字符串。报告的 body 中包含的字段由报告的 type 确定。⚠️ 不同类型的报告具有不同的正文。
如需查看每种报告类型的确切正文,请访问演示报告端点 ,并按照说明生成示例报告。 |
type |
报告类型,例如 csp-violation 或 coep 。 |
url |
生成报告的文档或工作器的地址。系统会从此网址中删除用户名、密码和片段等敏感数据。 |
user_agent |
生成报告的请求的 User-Agent 标头。 |
经认证的报告
与生成报告的网页具有相同来源的报告端点会接收凭据 (Cookie)。
凭据可提供有关报告的其他有用背景信息;用于 例如,指定用户的账号是始终如一地触发错误, 在其他网页上执行的操作会触发此页上的报告。
浏览器何时以及如何发送报告?
报告会从您的网站带外发送:浏览器会控制何时 它们会发送到已配置的端点。此外,您也无法控制 浏览器发送报告;它会自动捕获数据,将其加入队列, 确定合适的时间
这意味着,使用 Reporting API 时几乎没有性能问题。
报告会延迟发送(最长可达一分钟),以提高批量发送报告的几率。 这能在一定程度上考虑用户的网络连接,从而节省带宽, 非常重要如果浏览器忙于处理优先级更高的任务,也会延迟递送 或者用户使用的是速度缓慢和/或拥塞的网络。
第三方和第一方问题
系统会发送由于您的网页发生违规行为或弃用情况而生成的报告 您已配置的端点。这包括第三方脚本的违规行为 您的网页上所运行的广告素材
您网页中嵌入的跨源 iframe 中出现的违规或弃用情况将会导致 不会向您的端点报告(至少默认情况下不会)。iframe 可以设置自己的 甚至向您网站的(即第一方的)报告服务生成报告;不过已经结束了 访问加框网站。另请注意,大多数报告仅在用户违反网页政策时才生成报告, 并且您的网页政策与 iframe 政策不同。
弃用情况示例
<ph type="x-smartling-placeholder">浏览器支持
下表总结了浏览器对 Reporting API v1 的支持情况(使用
Reporting-Endpoints
标头。浏览器对 Reporting API v0(Report-To
标头)的支持是
相同的,只不过有一种报告类型:新 Reporting API 不支持网络错误日志记录。
如需了解详情,请参阅迁移指南。
报告类型 | Chrome | iOS 版 Chrome | Safari | Firefox | Edge |
---|---|---|---|---|---|
内容安全政策违规(仅限 3 级)* | ✔ 是 | ✔ 是 | ✔ 是 | ✘ 否 | ✔ 是 |
网络错误日志记录 | ✘ 否 | ✘ 否 | ✘ 否 | ✘ 否 | ✘ 否 |
违反 COOP/COEP | ✔ 是 | ✘ 否 | ✔ 是 | ✘ 否 | ✔ 是 |
所有其他类型的:违反文档政策、弃用、干预、崩溃 | ✔ 是 | ✘ 否 | ✘ 否 | ✘ 否 | ✔ 是 |
下表仅总结了对带有新 Reporting-Endpoints
标头的 report-to
的支持。如果您想要迁移到 Reporting-Endpoints
,请阅读 CSP 报告迁移提示。
使用 Reporting API
决定将报告发送到何处
您有两种选择:
- 将报告发送到现有的报告收集器服务。
- 将报告发送给您自己构建和运营的报告收集器。
方法 1:使用现有的报告收集器服务
报告收集器服务的一些示例如下:
- report-uri
- uriports
如果您知道其他解决方案,请提出问题告诉我们,我们会更新此博文!
选择报告收集器时,除了价格之外,还应考虑以下几点:🧐?
- 此收集器是否支持所有报告类型?例如,并非所有报告端点解决方案 支持 COOP/COEP 报告。
- 您是否愿意与第三方报告收集器共享您的应用的任何网址? 即使浏览器从这些网址中删除敏感信息,敏感信息也可能通过这种方式泄露。如果这听起来太危险了 运行您自己的报告端点
方法 2:构建和运行您自己的报告收集器
构建您自己的服务器来接收报告并非易事。首先,您可以创建我们的 轻量级样板文件它是使用 Express 构建的,可以接收和显示报告。
前往样板报告收集器。
点击 Remix to Edit 以使项目可修改。
您现在拥有自己的克隆了!您可以根据自己的用途对其进行自定义。
如果您没有使用样板代码,而是要从零开始构建自己的服务器,请执行以下操作:
- 检查
Content-Type
为application/reports+json
的POST
请求,以识别报告 发送到端点的请求。 - 如果您的端点与您的网站位于不同的来源,请确保它支持 CORS 预检请求。
方法 3:组合方法 1 和方法 2
您可能希望让某特定提供商处理某些类型的报告, 解决方案。
在这种情况下,请按如下所示设置多个端点:
Reporting-Endpoints: endpoint-1="https://reports-collector.example", endpoint-2="https://my-custom-endpoint.example"
配置 Reporting-Endpoints
标头
设置 Reporting-Endpoints
响应标头。其值必须是一个或一系列以英文逗号分隔的值
键值对:
Reporting-Endpoints: main-endpoint="https://reports.example/main", default="https://reports.example/default"
如果您要从旧版 Reporting API 迁移到新版 Reporting API,那么采用
同时设置了 Reporting-Endpoints
和 Report-To
。如需了解详情,请参阅迁移指南。特别要指出的是,如果您为
Content-Security-Policy
违规行为只能通过 report-uri
指令进行,请查看 CSP 报告的迁移步骤。
Reporting-Endpoints: main-endpoint="https://reports.example/main", default="https://reports.example/default"
Report-To: ...
键(端点名称)
每个键可以是您选择的名称,例如 main-endpoint
或 endpoint-1
。
您可以决定为不同的报告设置不同的已命名端点
类型,例如 my-coop-endpoint
、my-csp-endpoint
。通过这种方法
可以根据报告的类型将报告路由到不同的端点。
如果您希望收到干预、弃用和/或崩溃
设置一个名为 default
的端点。
如果 Reporting-Endpoints
标头未定义 default
端点,系统将不会发送此类报告(尽管会生成此类报告)。
值(网址)
每个值都是您选择的一个网址,报告将发送到该网址。网址 取决于您在第 1 步中确定的设置。
端点网址:
- 必须以斜杠 (
/
) 开头。相对路径不受支持。 - 可以是跨域;但在这种情况下,凭据不会随报告一起发送。
示例
Reporting-Endpoints: my-coop-endpoint="https://reports.example/coop", my-csp-endpoint="https://reports.example/csp", default="https://reports.example/default"
然后,您可以使用相应政策中的每个已命名端点,或使用某个 跨所有政策的单个端点
在何处设置标题?
此 API 的
后 - 报表的范围限定为文档。这意味着,对于某个给定的
来源不同的文档,例如 site.example/page1
和
site.example/page2
,可以将报告发送到不同的端点。
为了接收有关违规行为或弃用情况的报告,您的 请将标头设置为所有响应的中间件。
下面是一个 Express 示例:
const REPORTING_ENDPOINT_BASE = 'https://report.example';
const REPORTING_ENDPOINT_MAIN = `${REPORTING_ENDPOINT_BASE}/main`;
const REPORTING_ENDPOINT_DEFAULT = `${REPORTING_ENDPOINT_BASE}/default`;
app.use(function (request, response, next) {
// Set up the Reporting API
response.set(
'Reporting-Endpoints',
`main-endpoint="${REPORTING_ENDPOINT_MAIN}", default="${REPORTING_ENDPOINT_DEFAULT}"`,
);
next();
});
修改政策
现在,Reporting-Endpoints
标头已配置完毕,接下来添加 report-to
指令添加到您希望收到违规通知的各个政策标头中
报告。report-to
的值应该是
配置。
您可以将多个端点用于多项政策,或使用不同的 端点。
弃用、干预和崩溃时不需要 report-to
报告。这些报告不受任何政策约束。只要
已设置 default
端点,并发送到此 default
端点。
示例
# Content-Security-Policy violations and Document-Policy violations
# will be sent to main-endpoint
Content-Security-Policy: script-src 'self'; object-src 'none'; report-to main-endpoint;
Document-Policy: document-write=?0;report-to=main-endpoint;
# Deprecation reports don't need an explicit endpoint because
# these reports are always sent to the default endpoint
示例代码
为了在上下文中查看,下面是一个使用 Express 的 Node 服务器示例 并将本文讨论的所有部分汇总到一起。其中介绍了如何 为几种不同的报告类型配置报告并显示结果。
调试报告设置
有意生成报告
设置 Reporting API 时,您可能需要故意违反 政策,检查报告是否按预期生成和发送。 查看违反政策以及存在其他不良行为的示例代码 可生成所有类型的报告,请查看相应演示。
节省时间
报告可能会延迟发送(大约一分钟),这可能需要很长时间
。📲? 幸运的是,在 Chrome 中调试时,您可以使用
--short-reporting-delay
,即可在报告生成后立即收到相关报告。
在终端中运行以下命令即可开启此标志:
YOUR_PATH/TO/EXECUTABLE/Chrome --short-reporting-delay
使用开发者工具
在 Chrome 中,使用开发者工具查看已发送或即将发送的报告。
截至 2021 年 10 月,此功能处于实验阶段。要使用该功能,请按以下步骤操作:
- 使用 Chrome 96 及更高版本(请在浏览器中输入
chrome://version
进行确认) - 在 Chrome 的网址栏中输入或粘贴
chrome://flags/#enable-experimental-web-platform-features
。 - 点击已启用。
- 重新启动浏览器。
- 打开 Chrome 开发者工具。
- 在 Chrome 开发者工具中,打开“设置”。在“实验”下,点击在以下位置启用 Reporting API 面板: “应用”面板。
- 重新加载开发者工具。
- 重新加载页面。由开发者工具打开的页面生成的报告将 Chrome 开发者工具中列出应用面板的 Reporting API 下。
报告状态
状态列会显示报告是否已成功发送。
状态 | 说明 |
---|---|
Success |
浏览器已发送报告,且端点返回了成功代码(200 或其他成功响应代码 2xx )。 |
Pending |
浏览器正在尝试发送报告。 |
Queued |
报告已生成,浏览器目前并未尝试发送报告。在以下两种情况下,报告会显示为 Queued :
<ph type="x-smartling-placeholder">
|
MarkedForRemoval |
重试一段时间 (Queued ) 后,浏览器已停止尝试发送报告,并会很快将其从要发送的报告列表中移除。 |
报告会在一段时间后移除,无论报告是否成功发送。
问题排查
是否未生成报告或未按预期发送到您的端点? 以下是排查此问题的一些提示。
未生成报告
开发者工具中显示的报告已正确生成。 如果预期的报告没有显示在此列表中,请执行以下操作:
- 请查看您的政策中的
report-to
。如果配置有误 系统将不会生成报告。请前往修改政策, 解决此问题。排查此问题的另一种方法是查看 Chrome 中的开发者工具控制台:如果 错误,这表示您的政策可能 已正确配置。 - 请注意,只有为开发者工具打开的文档生成的报告才会打开
所有资源例如:如果您的网站
site1.example
嵌入了 iframesite2.example
并因此生成了报告,那么只有在您打开 iframe 中打开,然后为该窗口打开开发者工具。
生成报告,但无法发送或接收
如果您可以在开发者工具中看到报告,但端点没有收到报告,该怎么办?
- 请务必使用短暂的延迟。您看不到报告的原因可能是 尚未发送!
检查您的
Reporting-Endpoints
标头配置。如果存在问题, 正确生成的文件将无法发送。在开发者工具中,报告的状态将保持不变Queued
(如果尝试传送,可能会跳转到Pending
,然后快速恢复为Queued
)。可能会导致这种情况的一些常见错误:端点正在使用中,但未配置。示例:
Document-Policy: document-write=?0;report-to=endpoint-1; Reporting-Endpoints: default="https://reports.example/default"
缺少“
default
”端点。某些报告类型,例如弃用和干预 报告只会发送到名为default
的端点。如需了解详情,请参阅配置 Reporting-Endpoint 标头。检查政策标头语法中是否存在问题,例如缺少引号。查看详情。
检查您的端点是否可以处理传入请求。
确保您的端点支持 CORS 预检请求。否则,设备将无法接收报告。
测试端点的行为。为此,您无需生成 您可以模拟浏览器,方法是向端点发送请求,格式类似于 浏览器会发送什么内容运行以下命令:
curl --header "Content-Type: application/reports+json" \ --request POST \ --data '[{"age":420,"body":{"columnNumber":12,"disposition":"enforce","lineNumber":11,"message":"Document policy violation: document-write is not allowed in this document.","policyId":"document-write","sourceFile":"https://dummy.example/script.js"},"type":"document-policy-violation","url":"https://dummy.example/","user_agent":"xxx"},{"age":510,"body":{"blockedURL":"https://dummy.example/img.jpg","destination":"image","disposition":"enforce","type":"corp"},"type":"coep","url":"https://dummy.example/","user_agent":"xxx"}]' \ YOUR_ENDPOINT
您的端点应会返回一个成功代码(
200
或另一个成功响应代码2xx
)。如果没有, 其配置存在问题
相关举报机制
仅用于报告
-Report-Only
政策标头和 Reporting-Endpoints
可搭配使用。
在 Reporting-Endpoints
中配置并在以下实例的 report-to
字段中指定的端点:
Content-Security-Policy
、
Cross-Origin-Embedder-Policy
和
Cross-Origin-Opener-Policy
在违反这些政策时会收到报告。
在 Reporting-Endpoints
中配置的端点也可以在
report-to
字段
Content-Security-Policy-Report-Only
、
Cross-Origin-Embedder-Policy-Report-Only
和
Cross-Origin-Opener-Policy-Report-Only
。
他们还会在违反这些政策时收到举报。
虽然在这两种情况下都会发送报告,但 -Report-Only
标头不会强制实施
政策不会中断,也不会被阻止
报告哪些地方会出现问题或被屏蔽。
ReportingObserver
ReportingObserver
JavaScript API 可以帮助您
并观察客户端警告。
ReportingObserver
和 Reporting-Endpoints
标头会生成
看起来一样,但它们的使用场景略有不同。
在以下情况下可使用 ReportingObserver
:
- 您只想监控废弃和/或浏览器干预。
ReportingObserver
会显示客户端警告,例如弃用情况 但与Reporting-Endpoints
不同的是,它不会 捕获任何其他类型的报告,例如 CSP 或 COOP/COEP 违规行为。 - 您需要实时应对这些违规行为。
ReportingObserver
制造商 可以向违规事件附加回调。 - 您想向报告附加其他信息以帮助调试, (通过自定义回调实现)。
另一个区别是,ReportingObserver
仅在客户端配置:
即使您无法控制服务器端标头且无法
设置Reporting-Endpoints
。
深入阅读
主打图片作者:Nine Koepfer / @enka80 Unlaunch,已修改。非常感谢 Ian Clelland、Eiji Kitamura 和 Milica Mihajlija 对本文发表的评价和建议。