4、如何做到前端路由和后端路由同步;
说到前后端路由同步,有个问题就又抛出来了,什么是前后端路由同步?为什么要前后端路由同步?
让我们看看react-router
中的hashhistory
和browserHistory
;
hashHistory:
http://noah.dabanma.com/#/index
browserHistory:
http://noah.dabanma.com/index
这里我们选择browserHistory来做前端路由;这样更容易跟后端路由匹配;
好了,言归正传,那么什么是前后端路由同步,为什么要前后端路由同步?我总结下来就是:
意思是让前后端路由保持一致或存在某一对应关系,访问一个地址之后,前端路由和后端路由能够相对应上,保证渲染的组件一致,保证数据一致。
详细的说一下:
这就是打开一个网页的路由流程图。
前后端路由的匹配方法react-router
已经给出,match
方法。
import React from 'react';
import { match, RouterContext } from 'react-router';
function clientRouter(ctx, next) {
let _renderProps;
match({routes:Root(), location:ctx.url}, (err, redirectLocation, renderProps) => {
_renderProps = renderProps
})
if(_renderProps) {
ctx.render = (props, router) => {
return stringToHtml(<Provider store={props}><RouterContext {..._renderProps} /></Provider>, props, router);
}
}
next();
}
这是一个中间件,每次对后端的请求都会走这个中间件,那么每次都会走match
方法来匹配路由,渲染相应的组件。
5、如何拆分js和css,并且在切换页面的时候加载相对应的js和css;
我用webpack
拆分了js和css,将公用的js代码打包到vendor.js
中,然后以页面为单位拆分相应的js文件和css文件,根据页面的路由命名。
这样做的目的是减轻首屏加载的负担,页面只需要加载自己的js和css就可以。切换页面的时候,再根据路由请求相应的js和css文件即可。
这里抛出个问题,如何在切换页面的时候,异步请求响应的js和css文件?
我的思路是:
- 首先用
webpack
的pluginassets-webpack-plugin
是可以生成一个json文件的,这个json文件中包含打包的情况:
{
"index": {
"js": "/js/index-d4727d0c.js",
"css": "/css/index.css"
},
"test": {
"js": "/js/test-d4727d0c.js"
},
"vendor": {
"js": "/js/vendor-d4727d0c.js"
}
···
}
- 既然webpack生成了这个json文件,那么在后端我们可以用fs模块读取这个json内容,就可以在后端路由中找到对应的js和css文件,添加到字符串模板中,让浏览器去渲染;
这里有个点可以优化,每次切换页面的时候,我们不一定非得去请求后端,请求后端只是为了SEO,那么不需要做SEO的页面我们可以不请求后端,只要加载对应页面的js和css就好,然后用浏览器去解析js文件中的react代码,做到存前端渲染。这样提升了速度。
这样的优化,又抛出两个问题:
1.前面介绍过,数据是从后端通过字符串模板传给前端的,那么纯前端渲染就拿不到数据;
2.js和css也是通过后端路由匹配,获取到相应的js和css,通过字符串模板传给前端的,纯前端渲染也是拿不到对应页面的js和css文件的;
问题1的解决方案是在react生命周期componentDidMount
中发起与在后端路由中同样的请求,这样由前端发起请求得到数据。
问题2的解决方案是将webpack生成的json也写入字符串模板中,可在前端获取。
6、如何做到服务端渲染和前端渲染随意切换
服务端渲染和前端渲染的切换,归根结底在路由上的切换;
前端渲染跳转的方式:
import {Link, browserHistory} from 'react-router';
browserHistory.push('/index')
或者
<Link to='/index' >跳转</Link>
后端渲染跳转方式:
location.href = '/index';
7、做到服务端渲染和前端渲染可随意切换后,如何保证服务端和前端数据保持同步;
这个问题在上面的优化中提到过,若想做到前后端渲染随意切换,那么服务端和前端必须都具有各自独立获取数据的能力,并且两端数据要求统一。
我的思路是:
- 既然前后端的请求是一样的,数据会一致,数据接口也相同,那么将首屏渲染的请求提取出来是一个可行的办法;
- 根据webpack生成的json数据,查找组件和后端路由的对应关系,可将组件的请求同步到后端路由中;
- 这样,就可以实现跳转页面的时候,前后端渲染随意切换;
到这里将react服务端渲染基本介绍完了,当然还有很多细节没有写进来,如果有更好的方案和意见建议,请在评论区留言。