使用反应路由器表达状态 404

新手上路,请多包涵

我有一个快速服务器处理:1 API 路由和渲染我的初始 index.html 包括 bundle.js 持有我的 React/React-Router/Redux 应用程序。

就目前而言,不可能在我的网页上显示 404,因为我掌握了所有内容:

 app.use(function (req, res) {
  return res.render('index')
})

为了让 react-routerNoMatch 正常工作,我需要发送 404 代码。

我的路线如下:

快递 — /api/test/:x/:y

反应路由器 — :x/ , :x/:y

我基本上想要实现的是,如果用户访问了以下 URL: :x/:y/z/and/further 然后返回 404, 除非 他们访问的是 /api/test/:x/:y

问题:

  1. 我如何匹配路由,不包括我的 API 路由,最好以可扩展的方式返回适当的状态代码?
  2. 对于如此简单的事情,在子域上进行设置是否有很大的开销?这甚至可以缓解这个问题吗?当应用程序增长时,我会遇到问题吗?

原文由 speak 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 326
2 个回答

查看 react-router 服务器端渲染文档: reacttraining.com/react-router/web/guides/server-rendering

解决方案:

  1. 提取路由以分离文件并在 Express 应用程序中要求它
  2. 在 express 应用程序中添加一个中间件,使用 match 函数从 react-router 检查 express 中的 url。它应该写在负责API路由的中间件之后。
  3. 如果请求 url 没有合适的路由,则返回 404。

所以,中间件应该类似于这样:

 // origin code from https://github.com/reactjs/react-router/blob/master/docs/guides/ServerRendering.md
// this is ES6, but easily can be written on a ES5.

import { match, RouterContext } from 'react-router'
import routes from './routes'

var app = express();

// ...

app.use((req, res, next) => {
  match({ routes, location: req.url }, (error, redirectLocation, renderProps) => {
    if (error) {
      res.status(500).send(error.message)
    } else if (redirectLocation) {
      res.redirect(302, redirectLocation.pathname + redirectLocation.search)
    } else if (renderProps) {
         // You can also check renderProps.components or renderProps.routes for
        // your "not found" component or route respectively, and send a 404 as
        // below, if you're using a catch-all route.

        // Here you can prerender component or just send index.html
        // For prependering see "renderToString(<RouterContext {...renderProps} />)"
        res.status(200).send(...)
    } else {
      res.status(404).send('Not found')
    }
  })
});

如果任何路线发生变化,您无需在 express 应用程序上执行任何操作,因为您在前端和后端使用相同的代码。

原文由 Timur Bilalov 发布,翻译遵循 CC BY-SA 4.0 许可协议

我设法让我的 React 应用程序与 React Router v4 一起工作,并与运行 liquid.js 的快速服务器一起工作,类似于 handlebars 该解决方案对任何其他模板引擎的工作方式相同。

在你的 React App.js 中,确保你已经安装了 React Router v4 并像这样设置:

 import React, { Component } from 'react';
import { TransitionGroup, CSSTransition } from "react-transition-group";
import 'foundation-sites';
import {
  BrowserRouter as Router,
  Route,
  Switch
} from "react-router-dom";
import './assets/css/foundation.min.css';
import './assets/css/settings.scss';
import './assets/css/structure.css';
import './assets/css/owl-slider.css';
import './assets/fonts/fontawesome/all.css';

// ## COMPONENTS
import Header from './components/Header/header';
import Footer from './components/Footer/footer';

// ## PAGES
import HomePage from './components/Pages/Home/homePage';
import AboutPage from './components/Pages/About/aboutPage';
import ServicesPage from './components/Pages/Services/services';
import ContactPage from './components/Pages/Contact/contact';

class App extends Component {

  render() {
    return (
      <Router>
        <div className="App page-a blur" id="page" data-toggler=".blur" >
          <Header/>
          <div className="pageWrapper">
          <Route render={({ location }) => (
              <TransitionGroup>
                <CSSTransition key={location.key} classNames="pageTransition" timeout={500}>
                  <Switch location={location}>
                    <Route exact path="/" exact component={HomePage} />
                    <Route path="/services" render={props => <ServicesPage {...props}/>} />
                    <Route path="/about" component={AboutPage} />
                    <Route path="/contact" component={ContactPage} />
                    <Route render={() => <div>Not Found</div>} />
                  </Switch>
                </CSSTransition>
            </TransitionGroup>
          )}/>
          </div>
          <Footer footerMessage="Liliana Alves // Sport &amp; Soft Tissue Therapist"/>
        </div>
      </Router>
    );
  }
}

export default App;

上面的代码将确保当用户导航您的 React 应用程序时,路由正在完成他们的工作,将用户发送到他们导航、刷新或手动输入 URL 的页面。

在您的快速服务器 app.js 中,您要为您的 React 应用程序定义主要访问根目录“/”“不要使用通配符 *(星号)这将不起作用!” :

 app.get('/', (req, res) => {

        res.status(200).sendFile(path.join(__dirname+'/react-site/build/index.html'));

}); //THE REQUEST CONTENT

然后,如果您的 express 中有 404,它会将您的用户重定向回 React 以使用 React Router 处理 404,此方法是使用 express 错误处理程序完成的:

 app.use((req, res, next) => {
    const error = new Error('Not Found'); //Error object
    error.status = 404;

    //res.render('./404'); by default in express applications you would render a 404 page

    res.status(200).sendFile(path.join(__dirname+'/react-site/build/index.html'));

    next(error);

});

我花了很多时间研究让它工作如果有人认为这应该改进或者它可能需要更多的错误功能支持请告诉我。

原文由 Ricardo Alves 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
logo
Stack Overflow 翻译
子站问答
访问
宣传栏