Sentry ReactJS:如何设置隧道来绕过广告拦截器?

问题描述 投票:0回答:1

我在 React 应用程序中设置了 Sentry cloud,但它被广告拦截器拦截了(当关闭广告拦截器时,它会起作用)。

有人在 React 应用程序中成功设置了隧道吗?

  1. 我尝试过 CORS,但没有成功
  2. 使用 https://github.com/getsentry/examples/blob/master/tunneling/nextjs/pages/api/tunnel.js 中的 nextjs 示例中的 Sentry.init 中的隧道属性会抛出
    /tunnel 404 (Not Found) 
    console error in react app 虽然我在我的应用程序中添加了一条到此路径的路由,其中包含 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;
}

  1. 我什至尝试过 Webpack 插件
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")
        })

但仅适用于本地测试。在生产中,我想我们会使用代理。

reactjs sentry tunnel adblock
1个回答
2
投票

处理广告拦截器

当您使用 Sentry CDN 时,广告拦截或脚本拦截扩展可能会阻止 Sentry SDK 正确获取和初始化。因此,对 SDK API 的任何调用都将失败,并可能导致您的应用程序出现意外行为。

此外,即使正确下载并初始化了 SDK,需要接收捕获数据的 Sentry 端点也可能被阻止。这可以防止传送任何错误报告、会话运行状况或性能数据,使其在sentry.io 中实际上不可用。

此外,某些浏览器(例如Brave)具有内置广告拦截器,可能会阻止发送到我们端点的请求。即使用户停用您的域的阻止功能,Brave 也可能会继续阻止服务工作人员发出的请求。

使用
tunnel
选项

隧道是一个 HTTP 端点,充当 Sentry 和您的应用程序之间的代理。由于您控制该服务器,因此不存在发送到该服务器的任何请求被阻止的风险。当端点位于同一源下时(尽管隧道不必如此),浏览器不会将对端点的任何请求视为第三方请求。因此,这些请求将应用不同的安全措施,默认情况下不会触发广告拦截器。下面是流程的快速摘要。

您可以使用后端节点服务器设置

tunnel
路由或选择您喜欢的后端语言。

NodeJS - 服务器.js

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
仪表板并检查它。

© www.soinside.com 2019 - 2024. All rights reserved.