我正在使用 React-router,当我单击链接按钮时它工作正常,但是当我刷新我的网页时,它不会加载我想要的内容。
例如,我进去了localhost/joblist,一切都很好,因为我按链接到达这里。但是如果我刷新网页,我会得到:
localhost/joblist
Cannot GET /joblist
默认情况下,它不是这样工作的。最初我有我的 URLlocalhost/#/并且localhost/#/joblist它们工作得非常好。但我不喜欢这种 URL,所以试图删除它#,我写道:
localhost/#/
localhost/#/joblist
#
Router.run(routes, Router.HistoryLocation, function (Handler) { React.render(<Handler/>, document.body); });
这个问题不会发生localhost/,这个总是返回我想要的。
localhost/
编辑: 这个应用程序是单页的,所以/joblist不需要向任何服务器询问任何内容。
/joblist
EDIT2: 我的整个路由器。
var routes = ( <Route name="app" path="/" handler={App}> <Route name="joblist" path="/joblist" handler={JobList}/> <DefaultRoute handler={Dashboard}/> <NotFoundRoute handler={NotFound}/> </Route> ); Router.run(routes, Router.HistoryLocation, function (Handler) { React.render(<Handler/>, document.body); });
查看对已接受答案的评论和这个问题的一般性质(“不工作”),我认为这可能是对这里涉及的问题进行一些一般性解释的好地方。因此,此答案旨在作为 OP 特定用例的背景信息/详细说明。请多多包涵。
首先要了解的是,现在有 2 个地方可以解释 URL,而过去只有 1 个。过去,当生活很简单时,一些用户向http://example.com/about服务器发送请求,服务器检查 URL 的路径部分,确定用户正在请求 about 页面,然后发回该页面。
http://example.com/about
使用 React-Router 提供的客户端路由,事情就不那么简单了。起初,客户端还没有加载任何 JS 代码。所以第一个请求将永远是服务器。然后将返回一个页面,其中包含加载 React 和 React Router 等所需的脚本标签。只有当这些脚本加载后,阶段 2 才会开始。例如,在第 2 阶段,当用户单击“关于我们”导航链接时,URL 仅在本地 更改为http://example.com/about(由History API实现),但 不会向服务器发出请求. 相反,React Router 在客户端做它的事情,决定渲染哪个 React 视图,然后渲染它。假设您的关于页面不需要进行任何 REST 调用,它已经完成了。您已从主页转换到关于我们,而没有触发任何服务器请求。
所以基本上当你点击一个链接时,一些 Javascript 会运行来操纵地址栏中的 URL, 而不会导致页面刷新 ,这反过来会导致 React Router 在客户端 执行页面转换。
但是现在考虑如果您将 URL 复制粘贴到地址栏中并将其通过电子邮件发送给朋友会发生什么。您的朋友尚未加载您的网站。也就是说,她还处于 第一阶段 。她的机器上还没有运行 React Router。所以她的浏览器会 向http://example.com/about.
这就是你的麻烦开始的地方。到目前为止,您只需在服务器的 webroot 中放置一个静态 HTML 即可。 但是,当从服务器请求时 ,这会给404所有其他 URL 带来错误。这些相同的 URL 在客户端 工作正常,因为 React Router 正在为你做路由,但它们 在服务器端 失败,除非你让你的服务器理解它们。 __
404
如果您希望http://example.com/aboutURL 同时在服务器端和客户端工作,您需要在服务器端和客户端为其设置路由。有道理吗?
这就是您的选择开始的地方。解决方案的范围从完全绕过问题,通过返回引导 HTML 的包罗万象的路线,到服务器和客户端都运行相同 JS 代码的全面同构方法。
使用Hash History而不是Browser History,关于页面的 URL 将如下所示: http://example.com/#/about 哈希 ( #) 符号后面的部分不会发送到服务器。所以服务器只能http://example.com/按预期看到并发送索引页。React-Router 将拾取该#/about部分并显示正确的页面。
http://example.com/#/about
http://example.com/
#/about
缺点 :
/*使用这种方法,您确实使用了浏览器历史记录,但只是在发送到的服务器上设置了一个包罗万象的功能index.html,从而有效地为您提供与哈希历史记录大致相同的情况。但是,您确实有干净的 URL,您可以稍后改进此方案,而不必使所有用户的收藏夹无效。
/*
index.html
在混合方法中,您通过为特定路线添加特定脚本来扩展包罗万象的方案。您可以制作一些简单的 PHP 脚本来返回包含内容的网站最重要的页面,这样 Googlebot 至少可以看到您页面上的内容。
如果我们使用 Node JS 作为我们的服务器,那么我们可以在两端运行 相同的JS 代码呢? 现在,我们在一个 react-router 配置中定义了所有路由,我们不需要复制渲染代码。这就是所谓的“圣杯”。如果页面转换发生在客户端,服务器会发送与我们最终发送的完全相同的标记。该解决方案在 SEO 方面是最佳的。
window
选择一个你可以逃脱的。就个人而言,我认为包罗万象很容易设置,所以这将是我的最低要求。此设置允许您随着时间的推移改进事物。如果您已经在使用 Node JS 作为服务器平台,我肯定会研究做一个同构应用程序。是的,一开始很难,但是一旦你掌握了窍门,它实际上是解决问题的一个非常优雅的解决方案。
所以基本上,对我来说,这将是决定因素。如果我的服务器在 Node JS 上运行,我会采用同构的;否则,我会选择 Catch-all 解决方案,并随着时间的推移和 SEO 需求的需要对其进行扩展(混合解决方案)。
如果您想了解更多关于使用 React 进行同构(也称为“通用”)渲染的信息,这里有一些很好的教程:
另外,为了让您入门,我建议您查看一些入门工具包。选择一个与你的技术栈选择相匹配的技术栈(记住,React 只是 MVC 中的 V,你需要更多的东西来构建一个完整的应用程序)。首先查看 Facebook 自己发布的内容:
或者从社区中选择一个。现在有一个不错的网站试图索引所有这些:
我从这些开始:
目前,我正在使用受上述两个入门工具包启发的通用渲染的自制版本,但它们现在已经过时了。
祝你的任务好运!