Javascript 如何让反应路由器以 404 状态代码响应?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/36052604/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to let react router respond with 404 status code?
提问by Liang
I'm using react router as root and all requests under "/" are directed to react router. And when react router found that the url is not matched with any of the defined components, it renders with NoMatch component. And here goes the problem, NoMatch is rendered and that's what I want, but the status code is still 200 instead of 404. And when my css or js files are placed with a wrong url react router does the same thing, it responds with 200! And then the page tells me that there's some problem with my resources content type!
我以 root 身份使用 react router,“/”下的所有请求都指向 react router。当 react router 发现 url 与任何定义的组件都不匹配时,它会使用 NoMatch 组件进行渲染。问题来了,NoMatch 被渲染,这就是我想要的,但状态代码仍然是 200 而不是 404。当我的 css 或 js 文件被放置在错误的 url 中时,反应路由器做同样的事情,它以 200 响应!然后页面告诉我我的资源内容类型有问题!
So, how can I use react router to handle everything in the "/" and still get it to treat 404 errors right(to respond with 404 status code)?
那么,我如何使用反应路由器来处理“/”中的所有内容,并仍然正确处理 404 错误(以 404 状态代码响应)?
code in react router
反应路由器中的代码
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'));
the servre side
服务器端
router.use('/', function(req, res, next) {
res.render('index-react', {
title: 'some title'
});
});
回答by rmartrenado
With react-router 2.0.0 you can do:
使用 react-router 2.0.0,您可以执行以下操作:
<Route path="*" component={NoMatch} status={404}/>
EDIT:
编辑:
What you would need to do, is to create a custom attribute on your route definition, like you can see above (status).
你需要做的是在你的路由定义上创建一个自定义属性,就像你在上面看到的(状态)。
When you are about rendering you component on server side, check on this attribute and send a response with a the code of this attribute:
当您要在服务器端渲染组件时,请检查此属性并使用此属性的代码发送响应:
routes.js
路由.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:
服务器.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...
}
});
});
Sorry about that... certainly my solution wasn't working by itself, and I missed the proper piece of code where you actually check on this attribute and render accordingly.
抱歉……当然,我的解决方案本身并没有起作用,而且我错过了您实际检查此属性并相应地呈现的正确代码段。
As you can see, I just send the 'Not found' text to the client, however, it would be best if you catch the component to render from renderProps (NoMatch in this case) and render it.
如您所见,我只是将“未找到”文本发送给客户端,但是,最好是从 renderProps(在本例中为 NoMatch)捕获要渲染的组件并进行渲染。
Cheers
干杯
回答by taion
To do this, you need to run the match on the server as well, to see if a route matches. Of course, if you're going to do this, you may well do full-fledged server-side rendering as well! Consult the server rendering guide.
为此,您还需要在服务器上运行匹配,以查看路由是否匹配。当然,如果您打算这样做,您也可以进行成熟的服务器端渲染!请参阅服务器渲染指南。
回答by John Leidegren
I did some digging, this is how we do things in the v4 release.
我做了一些挖掘,这就是我们在 v4 版本中做事的方式。
<Route
render={({ staticContext }) => {
if (staticContext) {
staticContext.statusCode = 404
}
return <NotFound />
}}
/>
The Route
component is used to access the staticContext
which has a statusCode
prop that you can set if you use the StaticRouter
component to render on the server.
如果您使用该组件在服务器上进行渲染,则该Route
组件用于访问staticContext
具有statusCode
您可以设置的propStaticRouter
的 。
Server code looks something like this (with some TypeScript typing)
服务器代码看起来像这样(带有一些 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)
}
Note: I think the typings are a bit wonky because the
StaticRouterContext
doesn't have thestatusCode
prop from theStaticContext
interface. Probably a mistake in the typings. This works just fine though.
注意:我认为打字有点不稳定,因为
StaticRouterContext
没有statusCode
来自StaticContext
界面的道具。可能是打字错误。不过这工作得很好。
回答by Charles Merriam
Zen: What is the error code of a silent network?
Zen:静默网络的错误代码是什么?
I puzzled on this question as well. The odd case, you don't change the HTTP error code. We think we should, because a random URL was called, but why?
这个问题我也很疑惑。奇怪的情况是,您没有更改 HTTP 错误代码。我们认为应该这样做,因为调用了一个随机 URL,但为什么呢?
In a SPA (Single Page Application), there isn't network traffic but just switching of panes. The HTTP error code is in the headers for serving a new page, while all the content is in a named <div>
that doesn't reload a new page. One would need to toss out page, transmit and render a new page to have the 404 return code, and then send the original page again when the user moves away.
在 SPA(单页应用程序)中,没有网络流量,只有窗格的切换。HTTP 错误代码位于提供新页面的标头中,而所有内容都位于<div>
不重新加载新页面的命名中。需要抛出页面,传输并呈现新页面以获得 404 返回码,然后在用户离开时再次发送原始页面。
And, its only the user. The 404 error code, or any other HTTP code, is really a hint to the browser or service. If the requester is a browser, the human is given a better indication than the browser could provide. If the requestor is a crawler, it probably scans for 404 in <h1>
's. If the requester is using your website as an API, why is that a good thing?
而且,它只是用户。404 错误代码或任何其他 HTTP 代码实际上是对浏览器或服务的提示。如果请求者是浏览器,则向人类提供比浏览器所能提供的更好的指示。如果请求者是爬虫,它可能会扫描 404 in <h1>
。如果请求者将您的网站用作 API,为什么这是一件好事?
So the answer is that we set the HTTP status codes out of habit. Don't.
所以答案是我们习惯性地设置了 HTTP 状态码。别。