Firebase 存储下载突然停止工作 - 可能是 cors 问题?

Posted

技术标签:

【中文标题】Firebase 存储下载突然停止工作 - 可能是 cors 问题?【英文标题】:Firebase storage download suddenly stops working - possible cors issue? 【发布时间】:2021-09-28 22:23:18 【问题描述】:

我创建了一个 firebase 项目和相关应用。我正在使用电子邮件/密码身份验证。我还使用 gsutil 来允许 cors,并验证我已经使用 gsutil cors get 成功设置了 cors。

我编写了以下代码来将资源下载到我的云存储。昨天它工作得很好。今天它不再工作了。这是我的代码:

const userConfig = 
    email: "email@gmail.com",
    password: "password",
    file: "index.html",
    elementId: "sample"
;
const firebaseConfig = 
    apiKey: "key",
    authDomain: "Domain",
    projectId: "id",
    storageBucket: "bucket.appspot.com",
    messagingSenderId: "id",
    appId: "id"
;

(async (email, password, file, elementId, firebaseConfig) => 
    try 
        const firebaseApp = firebase.initializeApp(firebaseConfig);
        await firebase.auth().signInWithEmailAndPassword(email, password);
        const storage = firebase.storage();
        const storageRef = storage.ref(file);
        const url = await storageRef.getDownloadURL();
        const response = await fetch(url);
        const data = await response.text()
        const element = document.getElementById(elementId);
        element.innerHTML += data;
     catch(error) 
        alert(error.message);
    
)(userConfig, firebaseConfig);

我确信这段代码是正确的,因为它昨天在 Firefox 和 chrome 中运行没有问题。但是,由于某种原因,它停止了工作。问题似乎是:

        const url = await storageRef.getDownloadURL();

似乎.getDownloadURL 函数正在向https://firebasestorage.googleapis.com/v0/b/bucket.appspot.com/o/index.html 发出ajax 请求,并且请求似乎失败了。 Firefox 出现以下错误。

跨域请求被阻止:同源策略不允许读取 远程资源在 https://firebasestorage.googleapis.com/v0/b/bucket.appspot.com/o/index.html . (原因:CORS 请求未成功)。[了解更多]

这非常不寻常,因为 firebasestorage.googleapis.com 昨天没有要求 cors。谷歌浏览器出现以下错误:

net::ERR_NAME_NOT_RESOLVED

我完全不明白。

由于我的安全规则允许在没有身份验证的情况下读取我的文件,我还使用 curl 发出了一个 http 请求。

curl -I https://firebasestorage.googleapis.com/v0/b/bucket.appspot.com/o/index.html                    

输出是:

curl: (6) 无法解析主机:firebasestorage.googleapis.com

发生了什么事?谁能帮我?我该怎么办?为什么.getDownloadURL 突然失效了?

【问题讨论】:

听起来更像是互联网/连接问题。 【参考方案1】:

这可能是连接(或 DNS)问题:

第一个curl 是在关闭互联网的情况下执行的,但在连接互联网的情况下我收到了 200 个响应。

尝试切换到Google DNS 或Cloudflare DNS (1.1.1.1)。还可以尝试让使用不同 ISP 的人访问您的站点。对于任何浏览器,请在切换到任何其他 DNS 后尝试清除缓存或使用隐身模式。

要了解有关 DNS 的更多信息,请查看 https://howdns.works 和 What is DNS?

此外,如果您的域指向某个 IP,但 Web 服务器(如 nginx)未正确配置为指向正确的端口或类似的东西,您将在浏览器中收到 CORS 错误。所以这不是总是在 Express 应用程序中添加 allow access control origin 标头;)

【讨论】:

嗨@Dharmaraj。您在问题中包含了一张图片。我认为这是您在 curl 上发出 http 请求的结果?我不得不问,因为我的屏幕阅读器不读取图像。谢谢。 @lightning_missile 是的,curl 工作得很好,但是当我禁用互联网时出现同样的错误 听起来像一个愚蠢的问题,但你能解释更多关于 dns 的信息吗?我正在使用 localhost:8000 在本地机器上运行脚本。 @lightning_missile 这是一个非常大的话题。现在只是谷歌:如何在 myOS 上使用谷歌 DNS.. 只需替换为您的操作系统名称.. 当您有时间阅读 DNS 时,请转到此处:howdns.works 这很容易解释 DNS :)【参考方案2】:

简单地说,“Could not resolve host: firebasestorage.googleapis.com”意味着您的计算机无法连接到服务器,特别是因为您的系统无法确定服务器的 IP 地址。

这种情况时有发生,您应该妥善处理,因为您无法保证您的客户端始终连接到互联网。

fetch 将在您的系统离线、远程站点不存在或远程站点拒绝您的 CORS 请求时抛出错误。在基于 Chromium 的浏览器(Chrome、Edge、Opera 等)中,错误将是 TypeError: "Failed to fetch",而在 Firefox 上,您将看到 TypeError: "NetworkError when attempting to fetch resource."。因此,如果您希望远程服务器允许跨域请求,您可以假设消息中带有 fetch 字样的 TypeError 表示 CORS 协商失败并且无法访问远程服务器。

try 
  const response = await fetch("https://example.com/somePage");
  return response.json();
 catch (error) 
  if (error.name === "TypeError" && /fetch/i.test(err.message)) 
    // failed CORS/offline
    // TODO: handle
    console.error("Request denied/resource offline: ", error.message);
   else 
    // TODO: handle
    console.error("Request failed: ", error.message);
  

虽然fetch 支持no-cors 模式,但此模式限制了javascript 对响应正文的访问(使其成为null),这对您的用例没有用处,因为您打算将响应正文解析为当前文档。

【讨论】:

以上是关于Firebase 存储下载突然停止工作 - 可能是 cors 问题?的主要内容,如果未能解决你的问题,请参考以下文章

开发推送通知突然停止工作,但测试飞行推送通知仍然有效

Flutter 应用程序的 Firebase 通知突然停止

如何将firebase存储下载URL保存到firestore集合?

Firebase 功能和存储已停止工作

什么可能导致已发布的Android应用程序自发停止为大量用户工作?

CocoaPods 停止安装 Firebase/Analytics 并出现错误