(以下内容稍作更新)
我们有一个基于React的单页Web应用程序,托管在Firebase Hosting上。到目前为止,我们一直使用哈希路由(例如mysite.com/#/path/to/content
)。我们引入了React Router,这使我们可以拥有更美观的URL(例如mysite.com/path/to/content
),但现在当我们直接导航到深层路径时,应用程序不会加载。详细信息如下:
使用React Router需要在Firebase Hosting中使用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
参数为空,我们正在构建脚本中执行firebase deploy -f
)。链接到rules.json
文件甚至更简单:
{
"rules":{
".write":"true",
".read":"true"
}
}
当我通过访问基本URL加载应用并开始导航时,一切正常。如果我直接进入一个一级路由(例如mysite.com/path
),那也没问题。
然而
如果我直接进入深层级的路由,甚至是带有尾随斜杠的顶级路由(例如mysite.com/path/
或mysite.com/path/to/content
),则该应用程序不会加载。
具体来说,发生了以下情况:网页首先加载index.html
页面,然后浏览器试图加载在index.html
中引用的我们webpack创建的bundle.js
文件,但Firebase Hosting返回的JS文件内容却是index.html文件的内容。因此,可预见的是,我们在浏览器控制台中看到了这个错误:
Uncaught SyntaxError: Unexpected token <
...位于“捆绑文件”的第1行。如果我在Chrome的开发工具中查看捆绑文件的内容,则捆绑文件的第1行实际上是:
<!doctype html>
...然后是index.html
文件的其余部分。
似乎Firebase URL重写规则正在说“哦,你正在尝试引用JS文件——我看到我应该为所有内容返回index.html
文件的内容,所以给你”。但如果情况总是这样,那么该站点在任何情况下都将无法正常工作。所以,为什么如果我从站点根目录开始,它能工作,但如果我粘贴一个深度URL到应用程序中,就会出现错误呢?我一点都不知道。
如果有帮助的话,这是我index.html
文件如何引用bundle文件的方式:
<script src="bundle.ce843ef7a2ae68e9e319.js"></script></body>
看起来这是Firebase托管的问题,但我也可能在某种程度上不理解React Router,因此我已经通过某种方式在客户端代码中弄错了事情,以致它迫使服务器返回错误的内容。
我希望这只是一些我们遗漏的愚蠢配置。任何帮助都将不胜感激!
谢谢!
更新:我简化了我们的应用程序,所以它仅返回“hello, world”,这将绕过所有基于React的东西,包括React Router,并且问题仍然存在,因此我不再认为这与React-Router有关,虽然我认为还是有一小部分可能与React有关。
output: {publicPath: '/'}
。 - Priya Ranjan Singh