POST 请求失败,并在选项卡开关上出现“未捕获(承诺)类型错误:无法获取”

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

我正在将大量事件以 20 个事件为一组发送到 BigQuery 中的分析表。最初,我使用

sendBeacon
,但后来改用常规
POST
请求。下面是我用来处理发送事件的类:

import { createControllablePromise, delay } from '../utils/generalUtils';

class EventReporterWorker {
  #requestQueue = Promise.resolve();
  #activeRequest;
  #isPageVisible = true;

  #handleSendEvents = async eventsPayload => {
    if (this.#isPageVisible) {
      await this.#activeRequest;
    }

    const currentRequestPromise = createControllablePromise();
    const cancelTimeout = setTimeout(() => currentRequestPromise.resolve(), 30000);
    currentRequestPromise.finally(() => clearTimeout(cancelTimeout));

    this.#activeRequest = currentRequestPromise;

    const requestPromise = fetch('*MY_URL*, {
      method: 'POST',
      headers: {
        accept: '*/*',
        'cache-control': 'no-cache',
        'content-type': 'text/plain;charset=UTF-8',
      },
      body: eventsPayload,
      keepalive: true,
      mode: 'no-cors', // Matches sendBeacon's behavior
    });

    requestPromise.finally(() => {
      currentRequestPromise.resolve();
    });

    if (this.#isPageVisible) {
      try {
        await delay(300);
        await requestPromise;
      } catch (e) { }
    }
  };

  sendEvents = async eventsPayload => {
    const newRequestsQueue = this.#requestQueue.then(() => this.#handleSendEvents(eventsPayload));
    this.#requestQueue = newRequestsQueue;
    return newRequestsQueue;
  };

  setPageVisible = isPageVisible => {
    this.#isPageVisible = isPageVisible;
    if (!isPageVisible) {
      this.#activeRequest.resolve();
    }
  };
}

export const eventReporterWorker = new EventReporterWorker();

我使用 Promise 是因为我从多个地方接收事件并希望它们按顺序执行。我唯一希望立即发送所有事件的是当我切换选项卡时。

但是,切换选项卡时,某些

POST
调用失败并停留在
Pending
状态。

错误信息是:

Uncaught (in promise) TypeError: Failed to fetch

此失败之前和之后的事件成功,如图所示。

有人遇到过这个问题或者有解决办法吗?

我尝试过批量发送事件,增加延迟,检查服务器(问题不在服务器端),并确认互联网连接正常。调用似乎在浏览器级别失败。

参考图

post events google-bigquery fetch analytics
1个回答
0
投票

似乎你也有类似的案例这里。 “

TypeError: Failed to fetch
错误通常有多种原因发生:

  • 错误或不完整的 URL 已传递给 fetch() 方法。

  • 您发出请求的服务器未发回正确的 CORS 标头。

  • 网址中指定了错误的协议。

  • 错误的方法或标头已传递给 fetch() 方法。

虽然 keepalive 旨在帮助解决此问题,但它并不能保证请求会完成。您的模式:“no-cors”会加剧问题,因为 no-cors 请求可返回的信息有限,因此很难检测实际失败与浏览器终止的请求。

除非绝对必要,否则请避免 no-cors。它严重限制了错误处理,并且可能隐藏有关请求失败的重要信息。建议在服务器上正确配置 CORS。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.