diff --git a/packages/browser/src/client.ts b/packages/browser/src/client.ts index dae905672af1..04c5b580aa83 100644 --- a/packages/browser/src/client.ts +++ b/packages/browser/src/client.ts @@ -13,7 +13,6 @@ import { eventFromException, eventFromMessage } from './eventbuilder'; import { Breadcrumbs } from './integrations'; import { BREADCRUMB_INTEGRATION_ID } from './integrations/breadcrumbs'; import { BrowserTransportOptions } from './transports/types'; -import { sendReport } from './transports/utils'; const globalObject = getGlobalObject(); @@ -165,7 +164,19 @@ export class BrowserClient extends BaseClient { const envelope = createClientReportEnvelope(outcomes, this._options.tunnel && dsnToString(this._dsn)); try { - sendReport(url, serializeEnvelope(envelope)); + const global = getGlobalObject(); + const isRealNavigator = Object.prototype.toString.call(global && global.navigator) === '[object Navigator]'; + const hasSendBeacon = isRealNavigator && typeof global.navigator.sendBeacon === 'function'; + // Make sure beacon is not used if user configures custom transport options + if (hasSendBeacon && !this._options.transportOptions) { + // Prevent illegal invocations - https://xgwang.me/posts/you-may-not-know-beacon/#it-may-throw-error%2C-be-sure-to-catch + const sendBeacon = global.navigator.sendBeacon.bind(global.navigator); + sendBeacon(url, serializeEnvelope(envelope)); + } else { + // If beacon is not supported or if they are using the tunnel option + // use our regular transport to send client reports to Sentry. + this._sendEnvelope(envelope); + } } catch (e) { __DEBUG_BUILD__ && logger.error(e); } diff --git a/packages/browser/src/transports/utils.ts b/packages/browser/src/transports/utils.ts index a38f817691e4..405f35e400ff 100644 --- a/packages/browser/src/transports/utils.ts +++ b/packages/browser/src/transports/utils.ts @@ -1,4 +1,4 @@ -import { getGlobalObject, isNativeFetch, logger, supportsFetch } from '@sentry/utils'; +import { getGlobalObject, isNativeFetch, logger } from '@sentry/utils'; const global = getGlobalObject(); let cachedFetchImpl: FetchImpl; @@ -77,30 +77,3 @@ export function getNativeFetchImplementation(): FetchImpl { return (cachedFetchImpl = fetchImpl.bind(global)); /* eslint-enable @typescript-eslint/unbound-method */ } - -/** - * Sends sdk client report using sendBeacon or fetch as a fallback if available - * - * @param url report endpoint - * @param body report payload - */ -export function sendReport(url: string, body: string | Uint8Array): void { - const isRealNavigator = Object.prototype.toString.call(global && global.navigator) === '[object Navigator]'; - const hasSendBeacon = isRealNavigator && typeof global.navigator.sendBeacon === 'function'; - - if (hasSendBeacon) { - // Prevent illegal invocations - https://xgwang.me/posts/you-may-not-know-beacon/#it-may-throw-error%2C-be-sure-to-catch - const sendBeacon = global.navigator.sendBeacon.bind(global.navigator); - sendBeacon(url, body); - } else if (supportsFetch()) { - const fetch = getNativeFetchImplementation(); - fetch(url, { - body, - method: 'POST', - credentials: 'omit', - keepalive: true, - }).then(null, error => { - __DEBUG_BUILD__ && logger.error(error); - }); - } -}