在Firebase托管的单页应用上遇到深度路由问题 [英] Trouble with deep routes on a single-page app on Firebase hosting

查看:133
本文介绍了在Firebase托管的单页应用上遇到深度路由问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

(更新下面有更多信息)



我们有一个基于反应的单页网页应用程序,位于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托管为该JS文件返回的内容是。那么,可以预见的是,我们在浏览器控制台中看到的是这个错误:
$ b

未捕获的SyntaxError:意外的标记<



...在捆绑文件的第1行。如果我在Chrome的开发工具中查看包文件的内容,那么捆绑文件的第一行就是这样的:
$ b

<!doctype html> ;



...接下来是 index.html file。



Firebase网址重写规则似乎在说哦,您正在尝试引用JS文件 - 我看到我应该返回的内容 index.html 的一切,所以在这里你去。但是,情况总是不一样,或者这个网站在任何情况下都不会工作。那么,为什么如果我开始在网站的根目录,但如果我粘贴到应用程序的深层网址中断呢?我没有主意。



如果有帮助,以下是我的 index.html 文件引用包文件的方式:



< /><

所以Firebase托管似乎有问题,但我也可以看到,也许我不在某种程度上理解React Router,所以我以某种方式搞砸了客户端代码,使得服务器返回错误的东西。



我希望这是我们错过的一些愚蠢的配置。任何帮助表示赞赏!

谢谢!



更新:我剥离了我们的应用程序,你好,世界,绕过所有的基于React的东西,包括React路由器,问题依然存在,所以我不再认为这与React-Router有什么关系,尽管我认为还有一个小小的机会与React有关。

解决方案

我从Firebase托管服务处收到回复。显然,我们索引文件中引用的bundle.js文件在它前面需要一个斜杠,使其成为一个绝对路径。所以这个:

 < script src =/ bundle.js>< / script> 

...而不是这个:

 < script src =bundle.js>< / script> 

如果有其他人犯这个愚蠢的错误,我希望这是有用的。 b $ b

(Updated below with a little more info)

We have a react-based single-page web app that lives on Firebase Hosting. We've been using hash-based routing up to this point (e.g. mysite.com/#/path/to/content). We introduced React Router, which allows us to have prettier URLs (e.g. mysite.com/path/to/content), but now the app doesn't load when we navigate directly to a deep route. Details below:

Using React Router required us to use URL Rewriting in Firebase Hosting. The directions are pretty straightforward--it seems like all you need to do is this:

"rewrites": [ 
    {
    "source": "**",
    "destination": "/index.html"
    }
]

...inside the firebase.json file. In fact, our complete firebase.json file is as follows:

{
"firebase": "",
"public": "dist",
"rules": "rules.json",
"ignore": [
    "firebase.json",
    "**/.*",
    "**/*.map",
    "**/node_modules/**"
],
"rewrites": [ 
    {
    "source": "**",
    "destination": "/index.html"
    }
]
}

Nothing too complicated there (we're doing firebase deploy -f in our build script, if you're wondering why the firebase argument is empty). The linked-to rules.json file is even simpler:

{
   "rules":{
   ".write":"true",
   ".read":"true"
 }
}

When I load the app by going to the base URL and start navigating around, everything is fine. If I go directly to a route at one level deep (e.g. mysite.com/path), that works too.

HOWEVER

If I go directly to a route at a deep level, or even to a top-level route with a trailing slash (e.g. mysite.com/path/ or mysite.com/path/to/content), then the app doesn't load.

Specifically, what happens is the index.html page loads, and then browser goes to load our webpack-created bundle.js file that is referenced in index.html, but what Firebase Hosting returns for that JS file is the content of the index.html file. So then, predictably, what we see in the browser console is this error:

Uncaught SyntaxError: Unexpected token <

...on line 1 of the "bundle file". If I view the content of the bundle file in Chrome's dev tools, line 1 of the bundle file is literally this:

<!doctype html>

...which is then followed by the rest of the HTML from the index.html file.

It seems like what's going on is the Firebase URL rewrite rule is saying "oh, you're trying to reference a JS file--I see I'm supposed to return the content of index.html for everything, so here you go". But that can't be the case all the time, or the site would never work under any circumstances. So why does it work if I start at the site root, but breaks if I paste in a deep URL to the app? I have zero idea.

If it helps, here's how my index.html file references the bundle file:

<script src="bundle.ce843ef7a2ae68e9e319.js"></script></body>

So it seems like a problem with Firebase hosting, but I could also see that maybe I don't understand React Router at some level, and so I've somehow screwed things up with the client-side code in such a way that it's forcing the server to return the wrong thing.

Here's me hoping it's some stupid configuration thing we're missing. Any help is appreciated!

Thanks!

UPDATE: I stripped down our app so that it only returns "hello, world", which bypasses all of the React-based stuff, including React Router, and the problem persists, so I no longer think this has anything to do with React-Router, though I suppose there's still a small chance this could have something to do with React.

解决方案

I heard back from Firebase Hosting. Apparently, the referenced bundle.js file in our index file needed a slash in front of it, to make it an absolute path. So this:

<script src="/bundle.js"></script>

...instead of this:

<script src="bundle.js"></script>

In case anybody else makes this same silly mistake, I hope this is useful.

这篇关于在Firebase托管的单页应用上遇到深度路由问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆