查看有关已接受答案的评论以及该问题的一般性质(“不起作用”),我认为这可能是对此处涉及的问题进行一些一般性解释的好地方。因此,此答案旨在作为OP特定用例的背景信息/阐述。请多多包涵。
服务器端与客户端
首先要了解的是,现在有2个地方可以解释URL,而在“过去”中,以前只有1个地方。过去,当生活很简单时,一些用户向
http://example.com/about服务器发送了一个请求,服务器检查了URL的路径部分,确定该用户正在请求about页面,然后将该页面发回。
使用客户端路由(这是React-
Router提供的功能),事情就变得不那么简单了。首先,客户端尚未加载任何JS代码。因此,第一个请求将始终是服务器。然后将返回一个页面,其中包含加载React和React
Router等所需的脚本标签。仅在加载了这些脚本后,阶段2才会启动。在第2阶段中,例如,当用户单击“关于我们”导航链接时,URL 仅 在 本地
更改为
http://example.com/about(由History API实现),但未向服务器发出请求。相反,ReactRouter在客户端执行其操作,确定要渲染的React视图并进行渲染。假设您的about页面不需要进行任何REST调用,那么它已经完成了。您已从首页转换为关于我们,而没有触发任何服务器请求。
因此,基本上,当您单击链接时,将运行一些Javascript来操纵地址栏中的URL, 而不会导致页面刷新 ,这又导致React Router
在客户端 执行页面转换。
但是,现在考虑如果将URL复制粘贴到地址栏中并将其通过电子邮件发送给朋友,会发生什么情况。您的朋友尚未加载您的网站。换句话说,她仍处于 阶段1
。她的机器上还没有运行React Router。所以,她的浏览器将使 服务器的请求 来
http://example.com/about。
这就是您麻烦的开始。到现在为止,您只需将静态HTML放置在服务器的webroot上就可以摆脱困境。但是, 当从服务器请求时
,这将给
404所有其他URL 带来错误。这些相同的URL 在客户端 可以正常工作,因为那里的React
Router正在为您进行路由,但是除非您使服务器理解它们,否则它们 在服务器端 将失败。 __
结合服务器端和客户端路由
如果您希望
http://example.com/aboutURL在服务器端和客户端上都可以使用,则需要在服务器端和客户端上为其设置路由。有道理吧?
这就是您开始选择的地方。解决方案的范围从完全绕过问题(通过返回引导HTML的包罗万象的路线)到完全同构的方法(服务器和客户端都运行相同的JS代码)。
。
完全绕开该问题:Hash History
使用Hash History而不是浏览器历史记录,“关于”页面的URL如下所示:
http://example.com/#/about
hash(
#)符号后面的部分不会发送到服务器。因此,服务器仅
http://example.com/按预期方式看到并发送索引页。React-
Router将拾取
#/about零件并显示正确的页面。
缺点 :
- ‘ugly’ URLs
- 使用这种方法无法进行服务器端渲染。就搜索引擎优化(SEO)而言,您的网站只包含一个页面,几乎没有任何内容。
。
Catch-all
通过这种方法,您确实使用了浏览器历史记录,但是只是在发送
/*到的服务器上设置了一个包罗万象
index.html,有效地为您提供了与哈希历史记录相同的情况。但是,您确实拥有干净的URL,以后可以改进此方案而不必使所有用户的收藏夹均无效。
缺点 :
- 设置更复杂
- 仍然没有好的SEO
。
Hybrid
在混合方法中,您可以通过为特定路由添加特定脚本来扩展包罗万象的方案。您可以制作一些简单的PHP脚本来返回包含内容的网站最重要页面,以便Googlebot至少可以看到页面上的内容。
*Downsides: :
- 设置起来更加复杂
- 对于那些给予特殊待遇的路线,只有好的SEO
- 复制代码以在服务器和客户端上呈现内容
。
Isomorphic
如果我们使用Node JS作为我们的服务器,以便我们可以在两端运行 相同的 JS代码怎么办?现在,我们所有的路由都在一个react-
router配置中定义,我们不需要复制渲染代码。可以这么说,这是“圣杯”。如果客户端发生页面转换,服务器将发送与最终相同的标记。就SEO而言,此解决方案是最佳的。
缺点 :
- 服务器 必须 (能够)运行JS。我已经尝试过Java icw Nashorn,但是它对我不起作用。实际上,这主要意味着您必须使用基于Node JS的服务器。
- 许多棘手的环境问题(
window
在服务器端使用) - 陡峭的学习曲线
。
我应该使用哪个?
选择一个您可以摆脱的。就我个人而言,我认为综合起来很简单,所以这是我的最低要求。通过此设置,您可以随着时间的流逝改善情况。如果您已经在使用Node
JS作为服务器平台,那么我肯定会研究使用同构应用程序。是的,一开始很难,但是一旦掌握了它,它实际上是解决问题的一种非常优雅的方法。
因此,对我而言,基本上,这就是决定性因素。如果我的服务器在Node
JS上运行,我将同构。否则,我会选择全包解决方案,并随着时间的推移和SEO要求对其进行扩展(混合解决方案)。



