【问题标题】:404 page not found using Django + react-router使用 Django + react-router 找不到 404 页面
【发布时间】:2016-01-18 05:12:00
【问题描述】:

我正在尝试在我的 Django 应用程序中使用 reactjsreact-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组件]
  • 如果你这样做,它会起作用吗: (请参阅我在路径开头使用的斜杠)。编辑:另外,你确定你不想单独包含这一行“”吗?它目前嵌套在另一条路线内。
  • 您需要在 Django 应用程序中拆分您的路线处理 - 例如直接为 Django 提供以/api/* 为前缀的任何内容,以及为/path/to/your/index.html 提供任何其他(通配符) - 这是您的 React 应用程序。否则 Django 将 /about 路由解释为它自己的 - 它不会与 React 应用程序对话(它不能)。
  • @elithrar 好主意!但如果是通配符 * 服务器将为每个请求返回 http status_code 200,但是对于不存在的 url 返回 http status_code 404 很好。

标签: javascript python django reactjs react-router


【解决方案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'))
        ]
    

    【讨论】:

    【解决方案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'))
      ]
      

      【讨论】:

        猜你喜欢
        • 2017-09-22
        • 2017-02-03
        • 1970-01-01
        • 2016-08-01
        • 2016-08-01
        • 2015-10-22
        • 2014-03-20
        • 2020-10-27
        • 2019-07-21
        相关资源
        最近更新 更多