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 问题?的主要内容,如果未能解决你的问题,请参考以下文章
如何将firebase存储下载URL保存到firestore集合?