Firebase 存储下载突然停止工作 - 可能是 cors 问题?
Firebase storage download suddenly stops working - possible cors issue?
我已经创建了一个 firebase 项目和关联的应用程序。我正在使用 email/password 身份验证。我还使用 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 出现以下错误。
Cross-Origin Request Blocked: The Same Origin Policy disallows reading
the remote resource at
https://firebasestorage.googleapis.com/v0/b/bucket.appspot.com/o/index.html
. (Reason: CORS request did not succeed).[Learn More]
这非常不寻常,因为 firebasestorage.googleapis.com 昨天没有要求 cors。 Google Chrome 给出了以下错误:
net::ERR_NAME_NOT_RESOLVED
这个我完全不懂
由于我的安全规则允许我的文件无需身份验证即可读取,因此我还使用 curl 发出了一个 http 请求。
curl -I https://firebasestorage.googleapis.com/v0/b/bucket.appspot.com/o/index.html
输出为:
curl: (6) Could not resolve host: firebasestorage.googleapis.com
这是怎么回事?谁能帮我?我应该怎么办?为什么.getDownloadURL 突然失效了?
这可能是连接(或 DNS)问题:
第一个 curl
是在关闭互联网的情况下执行的,但在互联网连接的情况下我收到了 200 个响应。
尝试切换到 Google DNS or Cloudflare DNS (1.1.1.1
)。也可以尝试让使用不同 ISP 的人访问您的网站。对于任何浏览器,请在切换到任何其他 DNS 后尝试清除缓存或使用隐身模式。
要了解有关 DNS 的更多信息,请查看 https://howdns.works and What is DNS?
此外,如果您的域指向某个 IP 但 Web 服务器(如 NGINX)未正确配置为指向正确的端口或类似的东西,您将在浏览器中收到 CORS 错误。所以这不是总是在 Express 应用程序中添加 allow access control origin
header ;)
简单地说,“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."
。因此,如果您希望远程服务器允许跨源请求,您可以假设 TypeError
的消息中包含 fetch
一词,这意味着 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 项目和关联的应用程序。我正在使用 email/password 身份验证。我还使用 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 出现以下错误。
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://firebasestorage.googleapis.com/v0/b/bucket.appspot.com/o/index.html . (Reason: CORS request did not succeed).[Learn More]
这非常不寻常,因为 firebasestorage.googleapis.com 昨天没有要求 cors。 Google Chrome 给出了以下错误:
net::ERR_NAME_NOT_RESOLVED
这个我完全不懂
由于我的安全规则允许我的文件无需身份验证即可读取,因此我还使用 curl 发出了一个 http 请求。
curl -I https://firebasestorage.googleapis.com/v0/b/bucket.appspot.com/o/index.html
输出为:
curl: (6) Could not resolve host: firebasestorage.googleapis.com
这是怎么回事?谁能帮我?我应该怎么办?为什么.getDownloadURL 突然失效了?
这可能是连接(或 DNS)问题:
第一个 curl
是在关闭互联网的情况下执行的,但在互联网连接的情况下我收到了 200 个响应。
尝试切换到 Google DNS or Cloudflare DNS (1.1.1.1
)。也可以尝试让使用不同 ISP 的人访问您的网站。对于任何浏览器,请在切换到任何其他 DNS 后尝试清除缓存或使用隐身模式。
要了解有关 DNS 的更多信息,请查看 https://howdns.works and What is DNS?
此外,如果您的域指向某个 IP 但 Web 服务器(如 NGINX)未正确配置为指向正确的端口或类似的东西,您将在浏览器中收到 CORS 错误。所以这不是总是在 Express 应用程序中添加 allow access control origin
header ;)
简单地说,“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."
。因此,如果您希望远程服务器允许跨源请求,您可以假设 TypeError
的消息中包含 fetch
一词,这意味着 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
)并且不会对您的用例有用,因为您打算将响应正文解析到当前文档中。