我使用反应路由器作为root用户,所有请求都在" /"被指示反应路由器。当react路由器发现url与任何已定义的组件不匹配时,它会使用NoMatch组件进行渲染。这就是问题所在,NoMatch被渲染,这就是我想要的,但状态代码仍然是200而不是404.当我的css或js文件被放置错误的url react路由器做同样的事情,它响应200!然后该页面告诉我,我的资源内容类型存在一些问题!
那么,我怎样才能使用反应路由器来处理" /"并且仍然可以正确处理404错误(用404状态代码回复)?
反应路由器中的代码
render((
<Router history={browserHistory}>
<Route path="/" component={App}>
<IndexRoute component={Index}/>
<Route path="archived" component={App}>
<IndexRoute component={ArchivedPage}/>
<Route path="project/:projectId" component={ArchivedDetailPage}/>
</Route>
<Route path="*" component={NoMatch}/>
</Route>
</Router>
), document.getElementById('app'));
服务方
router.use('/', function(req, res, next) {
res.render('index-react', {
title: 'some title'
});
});
答案 0 :(得分:13)
使用react-router 2.0.0,您可以:
<Route path="*" component={NoMatch} status={404}/>
修改强>
您需要做的是在路线定义上创建自定义属性,就像您在上面看到的那样(状态)。
当您要在服务器端渲染组件时,请检查此属性并发送包含此属性代码的响应:
routes.js
import React from 'react';
import {IndexRoute, Route} from 'react-router';
import {
App,
Home,
Post,
NotFound,
} from 'containerComponents';
export default () => {
return (
<Route path="/" component={App}>
<IndexRoute component={Home} />
<Route path='post/' component={Post} />
{ /* Catch all route */ }
<Route path="*" component={NotFound} status={404} />
</Route>
);
};
server.js:
import { match } from 'react-router';
import getRoutes from './routes';
....
app.use((req, res) => {
match({ history, routes: getRoutes(), location: req.originalUrl }, (error,
redirectLocation, renderProps) => {
if (redirectLocation) {
res.redirect(redirectLocation.pathname + redirectLocation.search);
} else if (error) {
console.error('ROUTER ERROR:', error);
res.status(500);
} else if (renderProps) {
const is404 = renderProps.routes.find(r => r.status === 404) !== undefined;
}
if (is404) {
res.status(404).send('Not found');
} else {
//Go on and render the freaking component...
}
});
});
很抱歉......当然我的解决方案本身并不工作,而且我错过了正确检查此属性并进行相应渲染的正确代码。
正如您所看到的,我只是发送了“未找到”字样。但是,如果你从renderProps(在这种情况下是NoMatch)中捕获要渲染的组件并渲染它,那么最好是给客户端发送文本。
干杯
答案 1 :(得分:5)
Zen:静默网络的错误代码是什么?
我也对这个问题感到困惑。奇怪的是,您不会更改HTTP错误代码。我们认为应该这样,因为调用了随机URL,但为什么呢?
在SPA(单页应用程序)中,没有网络流量,只是切换窗格。 HTTP错误代码位于用于提供新页面的标头中,而所有内容都位于未重新加载新页面的已命名<div>
中。人们需要抛出页面,传输并渲染新页面以获得404返回代码,然后在用户离开时再次发送原始页面。
而且,它只是用户。 404错误代码或任何其他HTTP代码实际上是对浏览器或服务的暗示。如果请求者是浏览器,则给予人类比浏览器提供的更好的指示。如果请求者是爬虫,它可能会在<h1>
中扫描404。如果请求者使用您的网站作为API,为什么这是一件好事?
所以答案是我们设置HTTP状态代码不习惯。不。
答案 2 :(得分:3)
为此,您还需要在服务器上运行匹配,以查看路由是否匹配。当然,如果您打算这样做,您也可以完成全面的服务器端渲染!咨询server rendering guide。
答案 3 :(得分:1)
我做了一些挖掘,这就是我们在v4版本中的工作方式。
<Route
render={({ staticContext }) => {
if (staticContext) {
staticContext.statusCode = 404
}
return <NotFound />
}}
/>
Route
组件用于访问具有staticContext
道具的statusCode
道具,如果您使用StaticRouter
组件在服务器上渲染,则可以设置该道具。 / p>
服务器代码看起来像这样(键入一些TypeScript)
const currentLocation: Location = {
pathname: req.pathname,
search: req.search,
hash: '',
state: undefined
}
const staticRouterContext: StaticContext & StaticRouterContext = {}
ReactDOMServer.renderToString(
<StaticRouter location={currentLocation} context={staticRouterContext}>
...
</StaticRouter>
)
if (staticRouterContext.statusCode) {
res.status(staticRouterContext.statusCode)
}
注意:我认为打字有点古怪,因为
StaticRouterContext
接口没有statusCode
道具。可能是打字错误。但这很好。