UNPKG

@w0s/report-same-referrer

Version:
119 lines 3.91 kB
/** * Send referrer error information to endpoints */ export default class { #endpoint; // URL of the endpoint #options; // Information such as transmission conditions /** * @param endpoint - URL of the endpoint * @param options - Information such as transmission conditions */ constructor(endpoint, options) { this.#endpoint = endpoint; this.#options = options; if (options.condition === undefined) { this.#options.condition = 'origin'; } } /** * Referrer check & report */ async report() { const { referrer } = document; if (referrer === '') { return; } if (!this.#checkUserAgent()) { return; } const referrerUrl = new URL(referrer); switch (this.#options.condition) { case 'origin': { if (!this.#checkReferrer(referrerUrl.origin, location.origin)) { return; } break; } case 'host': { if (!this.#checkReferrer(referrerUrl.host, location.host)) { return; } break; } case 'hostname': { if (!this.#checkReferrer(referrerUrl.hostname, location.hostname)) { return; } break; } default: throw new Error('An invalid value was specified for the argument `condition`.'); } await this.#fetch(referrerUrl); } /** * ユーザーエージェントがレポートを行う対象かどうかチェックする * * @returns 対象なら true */ #checkUserAgent() { const ua = navigator.userAgent; const { denyUAs, allowUAs } = this.#options; if (denyUAs?.some((denyUA) => denyUA.test(ua))) { console.info('No referrer error report will be sent because the user agent match the deny list.'); return false; } if (allowUAs !== undefined && !allowUAs.some((allowUA) => allowUA.test(ua))) { console.info('No referrer error report will be sent because the user agent does not match the allow list.'); return false; } return true; } /** * リファラーがレポートを行う対象かどうかチェックする * * @param referrerPart - リファラーの一部分 * @param locationPart - Location の一部分 * * @returns 対象なら true */ #checkReferrer(referrerPart, locationPart) { const { same } = this.#options; if (same?.includes(referrerPart)) { return true; } return referrerPart === locationPart; } /** * レポートを送信 * * @param referrerUrl - リファラーのURL */ async #fetch(referrerUrl) { const { fetchParam, fetchContentType, fetchHeaders } = this.#options; const headers = new Headers(fetchHeaders); if (fetchContentType !== undefined) { headers.set('Content-Type', fetchContentType); } const bodyObject = { [fetchParam.documentURL]: location.toString(), [fetchParam.referrer]: referrerUrl.toString(), }; let body; if (fetchContentType === 'application/json') { body = JSON.stringify(bodyObject); } else { body = new URLSearchParams(bodyObject); } const response = await fetch(this.#endpoint, { method: 'POST', headers: headers, body: body, }); if (!response.ok) { throw new Error(`"${response.url}" is ${String(response.status)} ${response.statusText}`); } } } //# sourceMappingURL=ReportSameReferrer.js.map