前端路由的原理是根据当前页面路由渲染不同的组件,这一过程由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', '*/*']
之一。