所有源代码、文档和图片都在 github 的仓库里,点击进入仓库
相关阅读
- React服务端渲染之路01——项目基础架构搭建
- React服务端渲染之路02——最简单的服务端渲染
- React服务端渲染之路03——路由
- React服务端渲染之路04——redux-01
- React服务端渲染之路05——redux-02
- React服务端渲染之路06——优化
- React服务端渲染之路07——添加CSS样式
- React服务端渲染之路08——404和重定向
- React服务端渲染之路09——SEO优化
1. 404 页面
- 404 页面需要客户端告诉服务端,这个页面是否匹配到了,如果没有匹配到,该如何操作,所以我们还是需要使用 StaticRouter 的 context 属性来传递数据
- 所以,我们先新建一个 404 的组件,/src/containers/NotFound/index.js
- 这里对 staticContext 的定义时添加一个 NotFound 为 true 的属性,服务端拿到这个属性,可以知道是否是进入到了 404 页面
- 新建 404 组件 /src/containers/NotFound/index.js
// /src/containers/NotFound/index.js
import React, { Component } from 'react';
class NotFound extends Component {
componentWillMount() {
const { staticContext } = this.props;
staticContext && (staticContext.NotFound = true);
}
render() {
return (
<div>404 NotFound</div>
);
}
}
export default NotFound;
- 添加路由 /src/routes.js
export default [
{
path: '/',
component: App,
key: 'app',
routes: [
{
path: '/',
component: Home,
loadData: Home.loadData,
exact: true,
key: '/'
},
{
path: '/news',
component: News,
exact: true,
key: '/news'
},
{
component: NotFound
}
]
}
];
- 因为页面是 404, 所以我们需要修改一下 HTTP 的状态码
if (context.NotFound) {
res.status(404);
}
res.send(html);
- 其实这个还是比较简单的,没有什么复杂的地方,就是在 NotFound 组件里定义一个 NotFound 的属性,在服务端校验,然后对应做处理就可以了
- 5xx 页面和 404 页面是一样的,服务端 catch 到错误,就返回 500 错误,同时渲染 500 的页面
2. 重定向页面
- 假如我们有一个需要登录才能查看的页面,但是用户没有登录,所以他不能查看,但是我们要把页面重定向到登录页面,让用户进行登录,所以我们需要进行重定向
- 假如我们现在在进入 /news 页面的时候,需要用户重定向到 / 页面,我们可以在 News 组件里这么操作
import React, { Component } from 'react';
import {Redirect } from 'react-router-dom';
class News extends Component {
render() {
return (
<Redirect to="/" />
);
}
}
export default News;
- 纯粹的客户端渲染,我们也是这个做的,直接使用 Redirect 组件,传递 to 属性就可以了
- 此时我们在服务端查看 context 的值,就可以查看到一些新的属性
{ csses: [],
action: 'REPLACE',
location: {
pathname: '/',
search: '',
hash: '',
state: undefined
},
url: '/'
}
- 这里有一个 action 的属性,值是 REPLACE,这个是 react-router-dom 帮我们做的,当页面使用 Redirect 组件进行重定向的时候,context 里会添加 action, location 和 url 属性
- 所以,我们可以使用这些属性在服务端做对应的操作,这里的 redirect 的 url 要使用 context 里的属性,因为可能会有多个重定向组件,我们不知道要重定向到哪里
- 其实这个也比较简单,没有什么难度
if (context.action === 'REPLACE') {
res.redirect(301, context.url);
}
res.send(html);
- 404和重定向写在一起
if (context.action === 'REPLACE') {
res.redirect(301, context.url);
} else if (context.notFound) {
res.statusCode = 404;
}
res.send(html);