深入浅出Nginx——rewrite
最近项目中部分页面需要做前后端分离,考虑到单独部署前端会涉及到新增域名,目前项目中的域名已经太多了,并且没有充分的理由要独立部署前端,所以还是考虑将前端vue页面部署到服务端项目中。
基于之前对Vue略知一二,一直觉得它跟React很相似,都是组件化开发,包括页面渲染和组合,而之前自己也做过React开发,所以基本确定了方案,还是利用TP的模板,在模板中赋值变量,引入React组件进行渲染,这样就不会涉及到直接访问前端页面的问题。
然鹅,事实证明了我的自以为是,跟前端同事沟通时发现,Vue跟React还是有很大不同,都是通过入口文件index.html来访问,并不能将单独组件嵌入到TP模板中。。。好吧,这样问题就来了,为了兼容App端,活动分享页的接口还是不能更改,只能从接口中做跳转,这很简单,直接这样就可以:
$this->display('./Public/h5/dist/index.html');
比较棘手的问题来了,进入index.html后,Vue会根据路由进行跳转,比如我们会跳转到一个新的页面,如:
http://zydev.fzsf.com/courseActivity?reg_from=7&activity_id=56
当我对上述页面进行后,就会报:403 Forbidden.....
为什么呢? 肯定是因为Nginx,但是为什么是403呢?文件找不到不应该是404吗?
因为当前域名的nginx配置文件最后有这句:
location ~ / {
deny all;
}
好吧,太出乎意料了,还一直以为是try_files文件最后的路径写的不对,这里可以增加一个调试nginx的测试小技巧:
看看是否执行某个地方,可以在那里:return 999;
location中增加root,root必须为绝对路径,如果需要给在当前location中增加try_files去重写,需要如下:
try_files $uri $uri/ /dist/index.html
这里的最后一个文件路径必须是:基于root的相对路径:
当location中配置了root,就是相对于当前location中root的路径;
否则,就使用server中配置的root,需要配置相对于该root的路径;
例如:
# location ^~ /dist/ {
# root /home/zhangyan/v4_2/Public/h5; (root需要绝对路径)
# try_files $uri $uri/ /dist/index.html; (是相对于当前root的相对路径)
# }
location中不配置root的解决方案:
# location ^~ /dist/ {
# try_files $uri $uri/ /Public/h5/dist/index.html; (相对于www根目录的路径)
# }
使用@Router的解决方案:
location ^~ /dist/ {
try_files $uri $uri/ @router;
index index.html index.htm;
}
location @router {
rewrite ^.*$ /Public/h5/dist/index.html break; (location中rewrite后面的break,表示不再进入后面任何location)
}
当rewrite规则在location{}外,break和last作用一样,遇到break或last后,其后续的rewrite/return语句不再执行。但后续有location{}的话,还会近一步执行location{}里面的语句,当然前提是请求必须要匹配该location。(通过)
当rewrite规则在location{}里,遇到break后,本location{}与其他location{}的所有rewrite/return规则都不再执行。(通过)
当rewrite规则在location{}里,遇到last后,本location{}里后续rewrite/return规则不执行,但重写后的url再次从头开始执行所有规则,哪个匹配执行哪个。(未通过!!!!貌似location中rewrite后last,还是会继续执行本location中后面的rewrite,明天继续深究。。。。)
location中rewrite last跳转后,只会匹配执行location中的规则??(对,并且是从头开始匹配location,如果匹配,则执行)
location中多条规则时,如果第一条规则不满足,则跳出,不继续往下执行??(不是,还是会执行!)
Break 和 last 都能阻止继续执行后面的 rewrite 指令,但是 last 如果在 location 下用的话,对于重写后的 URI 会重新匹配 location ,但是 break 则不会重新匹配 location 。