Firestore 长获取请求

Firestore long get request

我正在使用 Firebase 和 ReactJS 创建一个使用 Firestore 的网站。当我使用以下 Javascript 代码从 Firestore 读取时,它是成功的,但是,在刷新页面后一分钟内发生了一个额外的 GET 请求。

firestore
  .collection("users")
  .doc(uid)
  .get()
  .then(doc => {
    if (!doc.exists) {
      console.error("User " + uid + " does not exist. Cannot retrieve document");
    } else {
      const { avatar, displayName } = doc.data();
      this.setState({ avatar: avatar, displayName: displayName });
    }
  })
  .catch(err => {
    console.error("Error getting document", err);
  });

如果我在最后一次 GET 之前刷新页面,我会在控制台中收到警告跨域请求被阻止。我从 Firestore 获取数据仍然没有问题。

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://firestore.googleapis.com/google.firestore.v1beta1.Firestore/Listen/channel?database=projects%2Fsword-pear%2Fdatabases%2F(default)&gsessionid=QbGcouT4k6BUq5C33CSi25Ih6UQR6QI2&VER=8&RID=rpc&SID=wLKF3u5yBNBdMKhPjNHJwQ&CI=0&AID=6&TYPE=xmlhttp&zx=7mjvphigpy5i&t=2. (Reason: CORS request did not succeed)

我假设服务器仍在尝试在刷新之前将数据发送到原始网页,但我不知道如果我在第一毫秒内获取数据,为什么 GET 会花费这么长时间。

一开始是localhost,然后是跨域GET请求,好像超时了。 运行 来自 Firebase Hosting 的脚本将使它成为一个合法的非跨域请求。问题是混淆了开发环境和实时环境,而不是使用在 localhost.

上运行的模拟器

之前更新 Google Cloud SDK(别名 gcloud 命令)时,我看到了这个:

Cloud Firestore Emulator
▪ Release Cloud Firestore Emulator version 1.2.1
  ◆ This is the first beta release of the emulator.

这将是一种在不允许的情况下规避跨域请求的方法。

查看 Web Origin Concept

这听起来很符合预期。 Firestore 针对与后端的实时通信进行了优化,并通过使用一种涉及长期 GET 请求的长轮询形式来实现。因此,即使您只调用 get(),SDK 也会在内部启动到后端的长轮询连接,以防您执行后续的 get()onSnapshot() 调用。我相信如果您在 ~1 分钟内不再执行任何请求,那么连接将被清理并且您不会再看到任何 GET 请求,除非您执行另一个操作。

我无法准确解释为什么浏览器会在页面重新加载时记录 "Cross-Origin Request Blocked" 消息,但这应该是良性的,可以忽略。