我在 React 应用程序中设置了哨兵云,但它被 AdBlockers 阻止了(当关闭 Adblocker 时,它会起作用)。
有人在反应应用程序中成功设置了隧道吗?
/tunnel 404 (Not Found)
虽然我在我的应用程序中添加了一条到此路径的路由,其中包含 nextjs 示例中的 handle
函数。...
Sentry.init({
dsn: 'https://[email protected]/mine',
integrations: [new BrowserTracing()],
environment,
tunnel: '/tunnel',
tracesSampleRate,
});
...
我直接通过
<Route path='/tunnel' component={(req, res) => handle(req, res)} />
尝试了它,也通过使用组件 <Route path='/tunnel' component={Tunnel} />
和
function Tunnel(props) {
let location = useLocation();
useEffect(() => {
if(location.pathname === '/tunnel') {
handle(props.req, props.res);
}
}, [location.pathname]);
return null;
}
plugins: [
new SentryWebpackPlugin({
include: '.',
ignore: ['node_modules'],
org: 'my_org',
project: 'app',
authToken:
'myToken',
}),
],
但它也被封锁了
--- 更新--- 至少对于本地开发和测试来说,可以调整 webpack 配置。
const bodyParser = require('body-parser')
const sentryHost = '@o<orgId>.ingest.sentry.io';
// Set knownProjectIds to an array with your Sentry project IDs which you
// want to accept through this proxy.
const knownProjectIds = ['12345'];
app.use(bodyParser.text());
app?.post('/tunnel', async (req, res) => {
try {
const envelope = req.body;
const pieces = envelope.split('\n');
const header = JSON.parse(pieces[0]);
// DSNs are of the form `https://<key>@o<orgId>.ingest.sentry.io/<projectId>`
const { host, pathname } = new URL(header.dsn);
// Remove leading slash
const projectId = pathname.substring(1);
if (host !== sentryHost) {
throw new Error(`invalid host: ${host}`);
}
if (!knownProjectIds.includes(projectId)) {
throw new Error(`invalid project id: $. {projectId}`);
}
const sentryIngestURL = `https://${sentryHost}/api/${projectId}/envelope/`;
const sentryResponse = await fetch(sentryIngestURL, {
method: 'POST',
body: envelope,
});
sentryResponse.headers.forEach(([key, value]) => res.setHeader(key, value));
res.status(sentryResponse.status).send(sentryResponse.body);
} catch (e) {
captureException(e);
return res.status(400).json({ status: 'invalid request' });
}
res.send("POST res sent from webpack dev server")
})
但仅适用于本地测试。在生产中我想我们会使用代理。
当您使用 Sentry CDN 时,广告拦截或脚本拦截扩展可能会阻止 Sentry SDK 正确获取和初始化。因此,对 SDK API 的任何调用都将失败,并可能导致您的应用程序出现意外行为。
此外,即使正确下载并初始化了 SDK,需要接收捕获数据的 Sentry 端点也可能被阻止。这可以防止传送任何错误报告、会话运行状况或性能数据,使其在sentry.io 中实际上不可用。
此外,某些浏览器(例如Brave)具有内置广告拦截器,可能会阻止发送到我们端点的请求。即使用户停用您的域的阻止功能,Brave 也可能会继续阻止服务工作人员发出的请求。
tunnel
选项隧道是一个 HTTP 端点,充当 Sentry 和您的应用程序之间的代理。由于您控制该服务器,因此不存在发送到该服务器的任何请求被阻止的风险。当端点位于同一源下时(尽管隧道不必如此),浏览器不会将对端点的任何请求视为第三方请求。因此,这些请求将应用不同的安全措施,默认情况下不会触发广告拦截器。下面是流程的快速摘要。
您可以使用后端节点服务器设置
tunnel
路由或选择您喜欢的后端语言。
import axios from 'axios';
import express from 'express';
import bodyParser from 'body-parser';
const app = express();
const port = 3005;
app.use(bodyParser.text({ type: ['text/*', '*/json'], limit: '50mb' }))
app.get('/', (req, res) => {
res.send('Hello World!');
});
app.post('/tunnel', async (req, res) => {
try {
const envelope = req.body;
const pieces = envelope.split('\n');
const header = JSON.parse(pieces[0]);
const { host, pathname, username } = new URL(header.dsn);
const projectId = pathname.slice(1);
const url = `https://${host}/api/${projectId}/envelope/?sentry_key=${username}`;
const options = {
'headers': {
'Content-Type': 'application/x-sentry-envelope'
}
};
const response = await axios.post(url, envelope, options);
res.status(201).json({ message: "Success", data: response?.data })
} catch (e) {
const error = e?.response || e?.message;
res.status(400).json({ message: 'invalid request', error: error });
}
});
app.listen(port, () => {
console.log(`Example app listening on port ${port}`);
});
您可以在此处
找到完整的 NodeJS 服务器代码设置后,后端服务器会对
front-end
React 应用程序进行一些更改。
您需要在
frontend
应用程序上设置代理。如果您正在使用 CRA
,则只需按照以下步骤操作即可。
了解更多详细信息https://create-react-app.dev/docs/proxying-api-requests-in-development/
首先,使用 npm 或 Yarn 安装
http-proxy-middleware
:
$ npm install http-proxy-middleware --save
$ # or
$ yarn add http-proxy-middleware
接下来,创建
src/setupProxy.js
并将以下内容放入其中:
const { createProxyMiddleware } = require('http-proxy-middleware');
module.exports = function(app) {
// ...
};
您现在可以根据需要注册代理!这是使用上面的示例
http-proxy-middleware
:
const { createProxyMiddleware } = require('http-proxy-middleware');
module.exports = function(app) {
app.use(
'/tunnel',
createProxyMiddleware({
target: 'http://localhost:5000', // Update based your server URL
changeOrigin: true,
})
);
};
完成
proxy
设置后,在初始化 sentry
配置时进行一些更改
Sentry.init({
dsn:"your sentry DSN URL", // Example: https://[email protected]/mine
// https://docs.sentry.io/platforms/javascript/troubleshooting/
tunnel: '/tunnel',
environment: 'production',
integrations: [
// https://docs.sentry.io/platforms/javascript/guides/react/session-replay/configuration/?original_referrer=https%3A%2F%2Fwww.google.com%2F
new Sentry.Replay({
// necessary since Replays currently don't work with tunneling
useCompression: false,
}),
// https://docs.sentry.io/platforms/javascript/guides/nextjs/performance/instrumentation/automatic-instrumentation/
new Sentry.BrowserTracing(),
// defaults to ['log', 'info', 'warn', 'error', 'debug', 'assert']
new CaptureConsole({ levels: ['error', 'warn'] }),
],
attachStacktrace: true,
// Set tracesSampleRate to 1.0 to capture 100% of transactions for performance monitoring.
tracesSampleRate: 1.0,
// Capture Replay for 10% of all sessions, plus for 100% of sessions with an error
replaysSessionSampleRate: 0.1,
replaysOnErrorSampleRate: 1.0,
});
完成设置后,只需重新启动您的
react
应用程序即可。您将能够通过隧道捕获错误。转到 sentry
仪表板并检查它。