Debugging Additional Data
您可以查看事件的 JSON payload,以了解 Sentry 如何在事件中存储其他数据。数据的形状可能与描述不完全匹配。
有关详细信息,请参阅关于 Event Payload 文档。
Max JSON Payload Size
maxValueLength
的默认值为 250,但是如果您的消息较长,则可以根据需要调整此值。请注意,并非每个单个值都受此选项影响。
CORS Attributes and Headers
要了解来自不同来源的脚本引发的 JavaScript 异常,请执行以下两项操作:
- 添加一个 crossorigin=”anonymous” 脚本属性
<script src="http://another-domain.com/app.js" crossorigin="anonymous"></script>
script 属性告诉浏览器 “anonymously” 地获取目标文件。当请求此文件时,潜在的用户识别信息(如 cookie 或 HTTP 凭据)不会被浏览器传输到服务器。
- 添加一个 Cross-Origin HTTP header
Access-Control-Allow-Origin: *
跨域资源共享(CORS)是一组 API(主要是 HTTP headers),这些 API 决定了应如何跨源下载和服务文件。
通过设置 Access-Control-Allow-Origin: *
,服务器向浏览器指示任何来源都可以获取该文件。另外,您可以将其限制为您控制的已知来源:
Access-Control-Allow-Origin: https://www.example.com
大多数社区 CDN 正确设置了 Access-Control-Allow-Origin
标头。
$ curl --head https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.js | \ grep -i "access-control-allow-origin" Access-Control-Allow-Origin: *
instrument.js
Line Numbers for Console Log statements
如果在调试时在控制台显示 instrument.js
,添加 Sentry 到你的框架 blackboxing ,设置如下:/@sentry/
,这样 Chrome 在调试时忽略 SDK stackframes。
Dealing with Ad-Blockers
当您使用我们的 CDN 时,广告拦截(ad-blocking)或脚本拦截(script-blocking)扩展程序可能会阻止我们的 SDK 无法正确获取和初始化。因此,对 SDKs API 的任何调用都将失败,并可能导致您的应用程序行为异常。如果这适用于您的用例,则以下任何一种解决方案都可以缓解此问题。
处理脚本阻止扩展的最好方法是直接通过 npm
使用SDK软件包,并将其与您的应用程序捆绑在一起。这样,您可以确保代码将始终如您所愿地存在。
第二种方法是从 CDN 下载 SDK 并自己托管。这样,SDK 仍将与您的其余代码分开,但是您可以确定它不会被阻止,因为它的来源与您网站的来源相同。
您可以使用 curl
或任何其他类似的工具轻松获取它:
curl https://browser.sentry-cdn.com/5.20.1/bundle.min.js -o sentry.browser.5.20.1.min.js -s
最后一个选项是使用 Proxy
防护,即使您调用被阻止的 SDK,也可以确保您的代码不会中断。除 Internet Explorer 之外,所有浏览器均支持 Proxy
,尽管该浏览器没有扩展。同样,如果您的用户浏览器中没有安装 Proxy
,它也会被静默跳过,因此您不必担心它会破坏任何东西。
将此片段放在包含我们的 CDN bundle 软件的 <script>
标记上方。可读格式的代码段显示如下:
if ("Proxy" in window) { var handler = { get: function(_, key) { return new Proxy(function(cb) { if (key === "flush" || key === "close") return Promise.resolve(); if (typeof cb === "function") return cb(window.Sentry); return window.Sentry; }, handler); }, }; window.Sentry = new Proxy({}, handler); }
如果你想直接复制和粘贴代码片段,这里是缩小过后的:
<script> if ("Proxy" in window) { var n = { get: function(o, e) { return new Proxy(function(n) { return "flush" === e || "close" === e ? Promise.resolve() : "function" == typeof n ? n(window.Sentry) : window.Sentry; }, n); }, }; window.Sentry = new Proxy({}, n); } </script>
Using a Client directly
为了能够管理多个 Sentry 实例而彼此之间没有任何冲突,您需要创建自己的 Client
。如果您的应用程序集成在其中,这也有助于防止跟踪任何父应用程序错误。在此示例中,我们使用 @sentry/browser
,但它也适用于 @sentry/node
。
import { BrowserClient } from "@sentry/browser"; const client = new BrowserClient({ dsn: "___PUBLIC_DSN___", }); client.captureException(new Error("example"));
尽管上面的示例工作得很好,但是 Client
上缺少诸如 configureScope
和 withScope
的某些方法,因为 Hub
负责状态管理。这就是为什么创建一个新的 Hub
并将其 Client
绑定到它上可能更容易的原因。结果是相同的,但是您还将获得状态管理。
import { BrowserClient, Hub } from "@sentry/browser"; const client = new BrowserClient({ dsn: "___PUBLIC_DSN___", }); const hub = new Hub(client); hub.configureScope(function(scope) { scope.setTag("a", "b"); }); hub.addBreadcrumb({ message: "crumb 1" }); hub.captureMessage("test"); try { a = b; } catch (e) { hub.captureException(e); } hub.withScope(function(scope) { hub.addBreadcrumb({ message: "crumb 2" }); hub.captureMessage("test2"); });
Dealing with integrations
Integrations 是在 Client
上设置的,如果你需要处理多个 clients 和 hubs,你必须确保也正确地进行集成处理。下面是一个工作示例,演示如何使用多个 clients 和多个 hubs 运行全局集成。
import * as Sentry from "@sentry/browser"; // Very happy integration that'll prepend and append very happy stick figure to the message class HappyIntegration { constructor() { this.name = "HappyIntegration"; } setupOnce() { Sentry.addGlobalEventProcessor(event => { const self = Sentry.getCurrentHub().getIntegration(HappyIntegration); // Run the integration ONLY when it was installed on the current Hub if (self) { event.message = `\\o/ ${event.message} \\o/`; } return event; }); } } HappyIntegration.id = "HappyIntegration"; const client1 = new Sentry.BrowserClient({ dsn: "___PUBLIC_DSN___", integrations: [...Sentry.defaultIntegrations, new HappyIntegration()], beforeSend(event) { console.log("client 1", event); return null; // Returning null does not send the event }, }); const hub1 = new Sentry.Hub(client1); const client2 = new Sentry.BrowserClient({ dsn: "___PUBLIC_DSN___", // Can be a different DSN integrations: [...Sentry.defaultIntegrations, new HappyIntegration()], beforeSend(event) { console.log("client 2", event); return null; // Returning null does not send the event }, }); const hub2 = new Sentry.Hub(client2); hub1.run(currentHub => { // The hub.run method makes sure that Sentry.getCurrentHub() returns this hub during the callback currentHub.captureMessage("a"); currentHub.configureScope(function(scope) { scope.setTag("a", "b"); }); }); hub2.run(currentHub => { // The hub.run method makes sure that Sentry.getCurrentHub() returns this hub during the callback currentHub.captureMessage("x"); currentHub.configureScope(function(scope) { scope.setTag("c", "d"); }); });
Third Party Promise Libraries
当您包含并配置 Sentry 时,我们的 JavaScript SDK 会自动将 global handlers 附加到 capture 未捕获的 exceptions 和未处理的 promise rejections。您可以通过在 GlobalHandlers 集成中将 onunhandledrejection
选项设置为 false
来禁用此默认行为,并手动挂钩到每个事件 handler,然后直接调用 Sentry.captureException
或 Sentry.captureMessage
。
如果您使用第三方库来实现 promises,则可能还需要管理您的配置。另外,请记住,浏览器经常实施安全措施,当提供来自不同来源的脚本文件时,这些措施会阻止错误报告。
Supported Browsers
Sentry 的 JavaScript SDK 支持以下浏览器:
Android | Firefox | Chrome | IE | iPhone | Edge | Safari |
4.4 | latest | latest | IE 10 |
iOS12 | latest | latest |
5.0 | IE 11 | iOS13 | ||||
6.0 | ||||||
7.1 | ||||||
8.1 | ||||||
9.0 | ||||||
10.0 |
Support for <= IE 11
在 5.7.0 版之前,我们的 JavaScript SDK 需要为旧版浏览器(如IE 11和更低版本)提供一些 polyfill。如果您正在使用它,请先升级到最新版本或在下面添加脚本标签,然后再加载我们的 SDK。
<script src="https://polyfill.io/v3/polyfill.min.js?features=Promise%2CObject.assign%2CString.prototype.includes%2CNumber.isNaN"></script>
我们需要以下polyfill:
Promise
Object.assign
Number.isNaN
String.prototype.includes
此外,请记住在 HTML 页面顶部定义一个有效的 HTML 文档类型,以确保 IE 不会进入兼容模式。