使用反应路由器表达状态 404 [英] Express status 404 with react-router
问题描述
我有一个快速服务器,可以处理: 1 个 API 路由并呈现我的初始 index.html
以包含包含我的 React/React-Router/Redux 应用程序的 bundle.js
.
I have an express server that handles: 1 API route and rendering my initial index.html
to include bundle.js
holding my React/React-Router/Redux application.
就目前而言,我的网页上不可能出现 404,因为我掌握了一切:
As it stands, it is impossible to 404 on my web page as I have a catch all:
app.use(function (req, res) {
return res.render('index')
})
为了让 react-router
的 NoMatch
工作,我需要发送 404 代码.
In order for react-router
's NoMatch
to work I need to send a 404 code.
我的路线如下:
Express — /api/test/:x/:y
React 路由器 — :x/
, :x/:y
React Router — :x/
, :x/:y
我基本上想要实现的是,如果用户曾经访问过以下 URL::x/:y/z/and/further
然后返回 404,除非 他们去的是 /api/test/:x/:y
What I am essentially trying to achieve is, if the user ever goes to a URL of: :x/:y/z/and/further
then return a 404, unless what they've gone to is /api/test/:x/:y
问题:
- 如何匹配路由(不包括 API 路由),最好以可扩展的方式返回适当的状态代码?
- 对于如此简单的事情,在子域上进行设置是否有很大的开销?这甚至能缓解这个问题吗?随着应用的发展,我会遇到问题吗?
推荐答案
查看 react-router 服务器端渲染文档:reacttraining.com/react-router/web/guides/server-rendering
Take a look at react-router server side rendering docs: reacttraining.com/react-router/web/guides/server-rendering
解决方案:
- 将路由提取到单独的文件并在 express 应用程序中要求它
- 在 express 应用中添加一个中间件,使用
react-router
中的match
函数检查 express 中的 url.应该写在负责 API 路由的中间件之后. - 如果请求 url 没有合适的路由,则响应 404.
- Extract routes to separate files and require it in express app
- Add a middleware in express app that check url in express using
match
function fromreact-router
. It should be written after middlewares that responsible for API routes. - In case there is no appropriate routes for request url, response with 404.
所以,中间件应该是这样的:
So, middleware should be similar to this:
// 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 应用程序上执行任何操作,因为您在前端和后端使用相同的代码.
If any routes change, you don't need to do something on express app, because you're using same code for frontend and backend.
这篇关于使用反应路由器表达状态 404的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!