如何让react-router以 404 状态代码响应?

IT技术 javascript reactjs http-status-code-404 frontend react-router
2021-04-11 02:00:55

我以 root 身份使用 react router,“/”下的所有请求都指向 react router。当 react router 发现 url 与任何定义的组件都不匹配时,它会使用 NoMatch 组件进行渲染。问题来了,NoMatch 被渲染,这就是我想要的,但状态代码仍然是 200 而不是 404。当我的 css 或 js 文件被放置在错误的 url 响应路由器做同样的事情时,它响应 200 !然后页面告诉我我的资源内容类型有问题!

那么,我如何使用 react router 来处理“/”中的所有内容并仍然正确处理 404 错误(以 404 状态代码响应)?

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'));

服务器端

  router.use('/', function(req, res, next) {
    res.render('index-react', {
      title: 'some title'
    });
  });
4个回答

使用 react-router 2.0.0,您可以执行以下操作:

<Route path="*" component={NoMatch} status={404}/>

编辑:

你需要做的是在你的路由定义上创建一个自定义属性,就像你在上面看到的(状态)。

当您要在服务器端呈现组件时,请检查此属性并使用此属性的代码发送响应:

路由.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>
  );
};

服务器.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)捕获要渲染的组件并进行渲染。

干杯

此参数自动设置请求对象的状态。
2021-05-26 02:00:55
如果您要包含一个答案,则包含整个答案是合适的。这个答案完全忽略了让这个工作完全正常的任何真正参考。
2021-05-30 02:00:55
我也从未在文档中找到它。我猜这是 2.x 文档中未完成的“高级用法”部分。但它有效,所以它一定是从那里丢失的,我一定是在我不记得的地方找到了这个解决方案......
2021-06-08 02:00:55
什么是status对的参数?我在文档中找不到任何对它的引用。
2021-06-19 02:00:55
路由器对响应对象一无所知!它如何能够设置状态?在我的服务器端代码中,我必须自己设置状态。如何确定路由器是否进入 404 页面?
2021-06-21 02:00:55

我做了一些挖掘,这就是我们在 v4 版本中做事的方式。

<Route
  render={({ staticContext }) => {
    if (staticContext) {
      staticContext.statusCode = 404
    }
    return <NotFound />
  }}
/>

如果您使用该组件在服务器上进行渲染,则Route组件用于访问staticContext具有statusCode您可以设置propStaticRouter的 。

服务器代码看起来像这样(带有一些 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来自StaticContext界面props可能是打字错误。不过这工作得很好。

如何处理renderToNodeStream这个解决方案?
2021-06-14 02:00:55

Zen:静默网络的错误代码是什么?

这个问题我也很疑惑。奇怪的情况是,您没有更改 HTTP 错误代码。我们认为应该这样做,因为调用了一个随机 URL,但为什么呢?

在 SPA(单页应用程序)中,没有网络流量,只有窗格的切换。HTTP 错误代码位于提供新页面的标头中,而所有内容都位于<div>不重新加载新页面的命名中。一个人需要扔掉页面,传输并渲染一个新页面以获得 404 返回码,然后当用户离开时再次发送原始页面。

而且,它只是用户。404 错误代码或任何其他 HTTP 代码实际上是对浏览器或服务的提示。如果请求者是浏览器,则向人类提供比浏览器所能提供的更好的指示。如果请求者是爬虫,它可能会扫描 404 in <h1>如果请求者将您的网站用作 API,为什么这是一件好事?

所以答案是我们习惯性地设置了 HTTP 状态码。别。

并不真地。我只是不同意设置 HTTP 状态代码只是一种习惯。不是。这是过去和现在有意完成的具有特定好处的事情(在我的第一条评论中提到)。也就是说,在我的情况下,我解决这个问题的方法是我让我的 Rails 应用程序专门指向 React 能够处理的路由。这样,其他所有内容都是具有 404 状态的常规 HTTP 响应。
2021-05-25 02:00:55
对不起我不理解你的意思。对于 SEO,您确实需要经历不同的过程,但永远不要更改错误代码。与接收此类错误代码相关的带有 h1 文本“404”的文章将不会被查看。
2021-05-29 02:00:55
即使在 SPA 中,也可能有对 React 路由器将处理的不存在的 URL 的初始直接请求。取代已有数十年历史的表示 URL 是否存在(状态代码)的标准方式,并希望网站设计者能够有效地传达它,这听起来不是一个好主意。每个网站设计师都会以不同的方式传达这一点,这会导致与任何试图理解(人类)或解析它(爬虫)的不一致。
2021-06-07 02:00:55
“如果请求者是爬虫,它可能会扫描 <h1> 中的 404”——Google 主要依赖 404 响应代码,或者当他们看到 000 条路由的相同模板时,他们会标记为软 404。想象一下写一篇文章大约 404 个响应,您的 h1 包含“404”,Google 会自动从其索引中删除该页面。不。
2021-06-18 02:00:55
请注意,您的论点是“那是不同的;因此它很糟糕”。您可以证明 404 是支持深层链接但不支持用于深层链接的合理 URL 的 SPA 的正确响应,以及何时可以跟踪其进入的深层链接并且您希望将正确答案发送给爬虫。
2021-06-22 02:00:55

为此,您还需要在服务器上运行匹配,以查看路由是否匹配。当然,如果您打算这样做,您也可以进行成熟的服务器端渲染!请参阅服务器渲染指南

2021-05-24 02:00:55
我确实喜欢这个链接到 404 页面的讽刺意味:-)
2021-05-26 02:00:55