(下面更新了更多信息)
我们有一个基于 React 的单页 Web 应用程序,它存在于 Firebase 托管上。到目前为止,我们一直在使用基于散列的路由(例如mysite.com/#/path/to/content
)。我们引入了 React Router,它允许我们拥有更漂亮的 URL(例如mysite.com/path/to/content
),但是现在当我们直接导航到深层路由时应用程序不会加载。详情如下:
使用 React Router 需要我们在 Firebase 托管中使用 URL 重写。方向非常简单——看起来你需要做的就是:
"rewrites": [
{
"source": "**",
"destination": "/index.html"
}
]
...在firebase.json
文件中。其实我们完整的firebase.json
文件如下:
{
"firebase": "",
"public": "dist",
"rules": "rules.json",
"ignore": [
"firebase.json",
"**/.*",
"**/*.map",
"**/node_modules/**"
],
"rewrites": [
{
"source": "**",
"destination": "/index.html"
}
]
}
那里没什么太复杂的(firebase deploy -f
如果您想知道为什么firebase
参数为空,我们正在构建脚本中执行此操作)。链接到的rules.json
文件更简单:
{
"rules":{
".write":"true",
".read":"true"
}
}
当我通过转到基本 URL 来加载应用程序并开始四处导航时,一切都很好。如果我直接进入一层深的路线(例如mysite.com/path
),那也可以。
然而
mysite.com/path/
如果我直接进入更深层次的路线,或者甚至是带有尾部斜杠(例如或)的顶级路线mysite.com/path/to/content
,则应用程序不会加载。
具体来说,发生的是index.html
页面加载,然后浏览器去加载我们在 中引用的 webpack 创建的 bundle.js 文件index.html
,但是 Firebase Hosting 为该 JS 文件返回的是index.html 文件的内容。那么,可以预见的是,我们在浏览器控制台中看到的是这个错误:
Uncaught SyntaxError: Unexpected token <
...在“捆绑文件”的第 1 行。如果我在 Chrome 的开发工具中查看包文件的内容,包文件的第 1 行实际上是这样的:
<!doctype html>
...然后是index.html
文件中的其余 HTML。
似乎发生了什么是 Firebase URL 重写规则说“哦,你正在尝试引用一个 JS 文件——我知道我应该返回所有内容的index.html
内容,所以你去吧”。但情况并非一直如此,否则该网站在任何情况下都无法正常工作。那么,如果我从站点根目录开始,为什么它会起作用,但如果我将深层 URL 粘贴到应用程序,它会中断?我的想法为零。
如果有帮助,这是我的index.html
文件引用捆绑文件的方式:
<script src="bundle.ce843ef7a2ae68e9e319.js"></script></body>
所以这似乎是 Firebase 托管的一个问题,但我也可以看到,也许我在某种程度上不理解 React Router,所以我以某种方式把客户端代码搞砸了,以至于它强迫服务器返回错误的东西。
我希望这是我们缺少的一些愚蠢的配置。任何帮助表示赞赏!
谢谢!
更新:我剥离了我们的应用程序,使它只返回“hello,world”,它绕过了所有基于 React 的东西,包括 React Router,问题仍然存在,所以我不再认为这与 React 有任何关系-路由器,尽管我认为这与 React 有关的可能性仍然很小。