使用 Django + react-router 找不到 404 页面
Posted
技术标签:
【中文标题】使用 Django + react-router 找不到 404 页面【英文标题】:404 page not found using Django + react-router 【发布时间】:2016-01-18 05:12:00 【问题描述】:我正在尝试在我的 Django 应用程序中使用 reactjs
和 react-router
(1.x
),但我很难将所有这些放在一起。这是 github 项目,以防我在这个问题中没有提供足够的信息。
https://github.com/liondancer/django-cherngloong
我在我的routes.js
中创建了一个path="about"
var routes = (
<Router>
<Route path="/" component= Views.Layout >
<IndexRoute component= Views.Index />
<Route path="about" component= Views.About />
</Route>
<Route path="*" component= Views.RouteNotFound />
</Router>
);
export default routes;
我的layout.js
class Layout extends React.Component
constructor(props)
super(props);
render()
return (
<div id="review-web">
<header className="header">
<LogoElement />
<CenterPiece />
</header>
<div>
React.cloneElement(this.props.children, path: this.props.path )
</div>
<Footer />
</div>
);
export default Layout;
当我输入localhost.8000/about
时,我收到404
Django 错误
我的目标是保持前端和后端分开,所以我相信我应该能够将 Django 用作数据的端点,而不是呈现视图。
【问题讨论】:
当您转到“/”时,它是否成功地服务于 Views.Layout 页面?在我看来,您的应用程序似乎不知道服务器或查看 routes.js。您是否将应用配置为使用 routes.js? @user2719875 现在我的应用程序使用this 来使用route.js
。如果我输入localhost:8000/
,它将显示this组件]
如果你这样做,它会起作用吗: /api/*
为前缀的任何内容,以及为/path/to/your/index.html
提供任何其他(通配符) - 这是您的 React 应用程序。否则 Django 将 /about
路由解释为它自己的 - 它不会与 React 应用程序对话(它不能)。
@elithrar 好主意!但如果是通配符 * 服务器将为每个请求返回 http status_code 200,但是对于不存在的 url 返回 http status_code 404 很好。
【参考方案1】:
我的应用为所有有效路由提供相同的客户端 JS。请原谅 Flask 代码。
@blueprint.route('/stuff/<path:path>', methods=["get"])
@blueprint.route('/', methods=["get"])
def index(path=None):
return render_template('app.html')
【讨论】:
【参考方案2】:我遇到了同样的问题,最终得到了这个解决方案。
settings.py:
REACT_ROUTES = [
'login',
'signup',
'password-reset',
'password-change',
'about',
...
]
urls.py:
routes = getattr(settings, 'REACT_ROUTES', [])
urlpatterns = [
...
url(r'^(%s)?$' % '|'.join(routes), TemplateView.as_view(template_name='index.html')),
]
我不喜欢在 django 设置中复制所有 react-routes,但是如果我们将所有内容都放在那里 url(r'^.*$')
,服务器将始终返回 HTTP status_code 200。这只是能够返回有效 HTTP status_code 404 的一种方法对于不存在的网址。
【讨论】:
有人可以将“url”行翻译成 Django 2(+)“路径”吗?我的理解目前太有限,无法做到。虽然我现在会看它,并在我解决它时更新答案。 嗨,感谢您的帖子,我只想问一下,react-router 端是否可以处理 404 错误?据我了解,django 仍然拥有无与伦比的路线.. 在 Django 2+ 中,现在不推荐使用 url,您可以使用 re_path【参考方案3】:根据 ramusus 的回答,这就是我现在修复它的方式。
由于 url 不再适用于 Django 2 及更高版本。 ramuses 的答案似乎也在使用 Python 2,查看字符串格式。这是使用 Python 3(.6)。
(虽然我确信有一种更优雅的方法可以做到这一点,但它确实有效,并帮助我在启动和运行项目方面更进一步。)
settings.py:(正如 ramusus 建议的那样)
REACT_ROUTES = [
'login',
'signup',
'password-reset',
'password-change',
'about',
...
]
在主 urls.py 中:(部分按照 ramusus 的建议)
from django.conf import settings
react_routes = getattr(settings, 'REACT_ROUTES', [])
for route in react_routes:
urlpatterns += [
path(''.format(route), TemplateView.as_view(template_name='index.html'))
]
【讨论】:
您可以在 Django 2 中使用django.urls.re_path
来替代 django.conf.urls.url
: docs.djangoproject.com/en/2.1/ref/urls/#re-path【参考方案4】:
我的灵感来自ramusus' answer。我正在使用(我认为)较新的django.urls.re_path
。我对this comment 有点怀疑,如果 404 由前端处理会更好或更糟。这就是我实现它的方式:
前端/views.py
from django.shortcuts import render
def index(request):
return render(request, 'frontend/index.html')
前端/urls.py
from django.urls import re_path
# Catch all pattern
urlpatterns = [
re_path('.*/', views.index, name='index'),
]
main/urls.py
from django.contrib import admin
from django.urls import path, include
from rest_framework.authtoken import views
urlpatterns = [
path('admin/', admin.site.urls),
...,
path('api-auth/', include('rest_framework.urls')),
path('', include('some_apps.urls')),
...,
# Put this at the end! This way, Django tries all
# its API URLs and if it doesn't find anything it
# redirects to the frontend
path('', include('frontend.urls'))
]
反应前端
// stuff ...
const Page404 = () =>
return (
<h3>404 - Not found</h3>
);
;
class App extends Component
render()
return (
<Router>
<Navbar />
<Switch>
// React handles any paths you specify, e.g. within the switch
<Route exact path='/some_paths/' component=SomeComponents />
// If nothing matches...
<Route component=Page404 />
</Switch>
</Router>
)
// stuff...
【讨论】:
【参考方案5】:我可以通过在 React 应用程序中使用 HashRouter
来解决这个问题。这会在 url 的开头添加一个 #
,您可以在 Django urls.py
中使用空路径(您的路径将如下所示:example.com/#/about/
)
Here is a good explanation(别忘了点赞)。
您的文件将如下所示:
App.tsx
<Router>
<Switch>
<Route path="/article/:articleID">
<Article />
</Route>
/* your routes */
</Switch>
</Router>
然后只是一条空路径。 urls.py
urlpatterns = [
path("", TemplateView.as_view(template_name='index.html'))
]
【讨论】:
以上是关于使用 Django + react-router 找不到 404 页面的主要内容,如果未能解决你的问题,请参考以下文章
如何在 django 项目中使用 react-router 处理 404 错误