前端路由的原理是根据当前页面路由渲染不同的组件,这一过程由JavaScript完成,无需经过后台。传统的多页应用每个路由对应一个HTML文件,跳转到某个路径时,浏览器要向服务端请求对应的静态文件资源。采用前端路由则省去了这一过程,提升了性能。
history路由
前端如果使用history路由,在刷新页面或直接输入地址访问时浏览器会向服务端请求对应路径下的文件,如果这时服务端没有处理则会返回404。
所以,服务端对单页应用的主要处理是对返回404的情况统一返回单页应用的index.html文件。
注意:配置后需前端针对匹配不到路由的情况写一个404页面,否则会直接白屏
create-react-app前端项目配置
前端使用BrowserRouter路由,如果前端包不部署在二级域名下只需将package.json文件的homepage字段指定为/就可以了(create-react-app脚手架使用package.json文件的homepage字段作为Webpack的publicPath配置项)
如果前端包需在二级域名下访问,则需指定homepage字段为二级路由名,如/sub。还需指定前端路由的basename属性
<BrowserRouter basename="/sub">
后端
Nginx
使用Nginx做服务器,需要将前端包部署在nginx默认的静态资源路径下,一般是/usr/share/nginx/html下。
如项目部署在路径/sub下,则配置如下:
location /sub/ {
error_log /var/log/nginx/sub.log debug;
try_files $uri $uri/ /sub/index.html;
proxy_set_header Host $host:$server_port;
proxy_set_header X-real-ip $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
}
其中error_log指令用于输出调试日志,调试完成后不需要这条指令。意味将日志文件输出到/var/log/nginx/sub.log路径中。
try-files指令意为寻找文件uri,如果找到返回该目录下的同名文件,否则返回/sub/index.html文件
如图中,访问地址是/scooper-ifpc-web/lib/prompt/prompt.css,nginx会默认在自己的静态资源文件中查找
/usr/share/nginx/html/scooper-ifpc-web/lib/prompt/prompt.css如找到,就返回这个文件。
Tomcat
Tomcat只需在配置文件web.xml文件中写入如下配置即可
<error-page>
<error-code>404</error-code>
<location>/index.html</location>
</error-page>
当请求在服务端没有路由匹配时返回单页应用的index.html文件
Express
使用Node.js的Express框架只需引入connect-history-api-fallback中间件
中间件源码很简单,截取一部分
rewriteTarget = options.index || '/index.html';
logger('Rewriting', req.method, req.url, 'to', rewriteTarget);
req.url = rewriteTarget;
next();
核心代码就是一个简单的重定向,将请求url改为单页应用index.html文件所在路径。重定向需要满足请求方法是GET且请求头的accept子段是['text/html', '*/*']之一。