使用反应路由器和 s-s-r 设置正确的 HTTP 状态

Posted

技术标签:

【中文标题】使用反应路由器和 s-s-r 设置正确的 HTTP 状态【英文标题】:Set correct HTTP status with react router and s-s-r 【发布时间】:2021-04-28 04:56:42 【问题描述】:

我正在尝试为 NotFound 组件设置 HTTP 状态。我的 404 组件:

import React from 'react';
import  Route  from 'react-router-dom';

import styles from './index.module.scss';

const Status = ( code, children ) => (
  <Route
    render=( staticContext ) => 
      if (staticContext) staticContext.status = code;
      return children;
    
  />
);

const NotFoundContainer = () => (
  <Status code=404>
    <div className=styles.error>
      Oops! We can’t seem to find the page you are looking for.
    </div>
  </Status>
);

export default NotFoundContainer;

我的&lt;App /&gt; 的路由定义为:

  <Switch>
    ...
    <Route path='/about' component=About />
    <Route component=NotFound />
  </Switch>

我还有一个 s-s-r 作品:

export default (req, res) => 
  ...
  frontloadServerRender(() =>
    renderToString(
      <Loadable.Capture report=m => modules.push(m)>
        <Provider store=store>
          <StaticRouter location=req.url context=context>
            <Frontload isServer=true>
              <App />
            </Frontload>
          </StaticRouter>
        </Provider>
      </Loadable.Capture>
    )
  ).then(routeMarkup => 
    if (context.url) 
      // If context has a url property, then we need to handle a redirection in Redux Router
      res.writeHead(302, 
        Location: context.url
      );
      res.end();
     else 
      // Otherwise, we carry on...
      const extractAssets = (assets, chunks) =>
      ...

我知道这应该足够了,s-s-r 会返回正确的状态。但是,我没有看到它:

server listening on port 3000!
GET /sockjs-node 200 23.735 ms - -
GET /manifest.json 304 1.312 ms - -
GET /manifest.json 304 0.411 ms - -
GET /xxx 200 3.267 ms - -
GET /static/css/main.e6d4082b.chunk.css 304 0.689 ms - -
GET /static/js/2.90014d69.chunk.js 304 1.589 ms - -
GET /static/js/main.5d98d504.chunk.js 304 1.037 ms - -
GET /manifest.json 304 1.244 ms - -
GET /icons/favicon.ico 200 3.814 ms - -

GET /xxx 应该返回404,但我得到200。我错过了什么?

【问题讨论】:

【参考方案1】:

我错过了完成这项工作的最后一段代码,如下:

      if (context.status === 404) 
        res.status(404);
      
      // We have all the final html, let's send it to the user already!
      res.send(html);

在我们发送最终响应之前,我们需要检查上下文状态并在必要时设置响应上的状态,如上所述。

【讨论】:

以上是关于使用反应路由器和 s-s-r 设置正确的 HTTP 状态的主要内容,如果未能解决你的问题,请参考以下文章

React s-s-r路由器-导航到子路由时的redux状态丢失

在 s-s-r 上的反应组件中导入 scss

使用 cypress.io 模拟 s-s-r 反应应用程序 e2e 测试的服务器

使用 firebase-functions 部署基于反应的 s-s-r 应用程序时出错

Next Js API:使用 s-s-r 反应页面的响应

s-s-r:反应应用程序中的动态导入如何在客户端加载组件时处理html未匹配