书接上文,就算一个服务器配置了多个站点的虚拟主机,但当服务器上的 http 监听进程监听得到这个请求后,一般情况下(某个虚拟主机)都会启动一个子进程去处理这个请求,同时父进程继续监听。http服务器会首先查看重写规则,如果文件是真实存在,例如一些图片,或者 css js 等的静态文件,就会直接把这个文件返回,如果是一个动态的请求,那么会根据 url 重写模块的规则,把这个请求重写到一个 rest 风格的 url 上,然后根据动态语言的脚本,来决定调用什么类型的动态文件脚本解释器来处理这个请求。。。。好,暂定存档。
那么问题来了,“根据URL重写模块的规则,把这个请求写到一个rest风格的url上。。。”什么是URL重写模块?rest风格(听起来很有格调的样子~~)的URL又是神马意思?
断点1: URL重写(伪静态)
URL重写,顾名思义,就是服务器端将请求的URL根据规则定向到指定URL的过程。Apache的重定向有mod_rewrite模块,nginx有ngx_http_rewrite_module模块的支持,当然相信还有很多其他开源的url重写模块。。。本想展开细究并加以实践Apache和nginx的URL重写模块(感觉还算实用)。。。但并未找到系统性的学究验证。。。这里先贴几片看到的还算有参考价值的文章,吾将一一加以实践。
Rewrite重写规则可参考文章:
https://segmentfault.com/a/1190000002797606
http://www.cnblogs.com/pycode/p/6588896.html
此处,谈到URL重写,难免会提及URL重定向,二者似乎都是服务器指定请求跳转的过程,但还是有些区别的:
1. URL重写是服务器端截取URL请求后,获取原URL响应内容,状态码:200.;URL重定向是服务器端将URL请求指定到跳转页,并告知客户端重新访问定向地址,状态码:301/302;
2. 临时重定向(R=302)和永久重定向(R=301)是常见的URL重定向方法,都是亲搜索引擎的,是SEO的重要技术。
3. 通过重定向,浏览器知道页面发生变化,从而改变地址栏显示的地址【301重定向可以改写浏览器缓存?】;搜索引擎意识到页面被移动了,从而更新搜索引擎索引,将原来失效的连接从搜索结果中移除【所以,能获取到重定向后的URL,怎么更新引擎索引,把URL换掉?既然要访问的服务器.htaccess已经有了重写规则,坐等他跳,为什么还要更新引擎索引呢?】
4. URL重写用于将页面映射到本站另一页面,若重写到另一网络主机(域名),则按重定向处理
.htaccess关于URL重写和URL重定向的使用技巧:
http://lesca.me/archives/htaccess-rewrite.html
https://yq.aliyun.com/ziliao/120014
断点11: URL静态化和URL伪静态
涉及到SEO,搜索引擎喜欢静态的网站页面,故而,投其所好。。。。。。
URL静态化。URL静态化 就是在你的网站服务器上现实存在的HTML页面,每个HTML页面对应着你网站上的一个URL。常见的可以生成URL静态化页面的网站开源程序有DEDECMS和其它一些CMS内容管理系统,WordPress在安装插件后也可以实现URL静态化【交互不多时可以做成静态并更新,文件太多时,其实也挺歇菜的】。
URL伪静态。URL伪态是最常见的网页存在形式,URL伪静态看起来和URL静态化完全一样,但实际上URL对应的文件是不存在的,是用技术手段实现的,比如URL重写技术。伪静态的优点很多,比如不生成现实的HTML文件,就不会占用网站空间,管理方便,维护方便,和URL静态化一样有利于SEO。
断点12: nginx、apache以及.htaccess文件的关系
Apache与.htaccess规则的关系应该是屡见不鲜的,那nginx跟.htaccess规则有什么必要关系吗?答案是:毫无关系!
但有些人深受apache的影响觉得nginx应该也要支持.htaccess功能,可以在nginx的配置中直接include .htaccess文件,虽说这也是不难实现的:1、新建一个.htaccess文件,在里面输入规则:
# nginx rewrite rule
rewrite ^(.*?)/article/.*?-(\d+)-(\d+)\.html$ $1/show.html?id=$2&page=$3 break;
rewrite ^(.*?)/category/.*?-(\d+)-(\d+)\.html$ $1/list.html?id=$2&page=$3 break;
。。。。。。
2、修改虚拟主机配置:即在你需要添加伪静态的虚拟机中的server块中引入.htaccess文件
include /usr/www/.htaccess #请把这个改成你.htaccess文件的位置,
保存、退出重启nginx
但是nginx的rewrite规则完全可以放在主机配置中。其实nginx这样引用.htaccess跟apache还是有区别的:1、nginx是启动引入,因为nginx特别注重效率,所以启动的时候会把所有的配置文件读入内存,然后启动。如果发现有语法错误,则启动失败[修改后需要重载nginx]。而apache则是动态引入,每次访问站点都会重新载入配置[修改后即时生效]。2、nginx中的include是手动添加,指定目录。apache已经把.htaccess作为它的一种特色机制,并且支持站所有子目录都可以有.htaccess文件【作用域覆盖】。
断点2: 什么是RESTFUL风格URL
国外的听起来高大上的名词,一般都是见明知意的。RESTFUL(Representational State Transfer,即表现层状态转移),这里缺省了主语“资源”,真实的表达意是:“资源表现层状态转移”。
所谓"资源",就是网络上的一个实体,或者说是网络上的一个具体信息。你可以用一个URL指向它,故URL就成了每一个资源地址或独一无二的标志符。
表现层,顾名思义,就是资源(信息实体)的外在表现形式,比如文本可以用txt,HTML,XML,JSON格式表现。它的具体表现形式,应该在HTTP请求的头信息中用Accept和Content-Type字段指定。
状态转移,由于HTTP协议是一种无状态协议,即所有状态都保存在服务器端,如果客户端想要操作服务器,必须通过某种手段,让服务器端发生“状态转移”,而这种转化是建立在(针对)表现层之上的,故而叫“表象层状态转移”。客户端能用的手段,只能是HTTP请求,具体来讲:
常用的5个HTTP动词以及其所对应的操作方式如下:
截止至此,RESTFUL字面意思算是解释完了:客户端和服务器间,传递某种资源的表象层;客户端通过请求方法,对服务器资源进行操作,实现"表现层状态转化"。
那么RESTFUL风格的URL应该长什么样子呢?
可参见http://www.ruanyifeng.com/blog/2014/05/restful_api.html,据大牛们的经验之谈,典型的应该是这样的:既然每个网址代表一种资源,那么网址中一般都是名词,没有动词,而且所用的名词往往与数据库的表格名对应。以某动物园的API为例,其中包含动物及饲养员的某些信息:
虽说RESTFUL URL是一种良好的架构风格,但从上面的典型🌰中可以存在某些问题,可辩证的看下这篇文章:http://www.sohu.com/a/123454288_487103中提出的这些问题:
1.如果URL中资源数超过两个或者更多:/ResourceA/<ResourceA ID>/ResourceB/<ResourceB ID>/ResourceC/<ResourceC ID>,对资源进行操作前要检查资源的从属关系,以确保当前请求具有相关访问、操作权限。【资源请求的嵌套是会发生,但嵌套太多层的逻辑设计也不太合理吧?】
2.HTTP响应中缺失必要的Security Headers,比如X-Frame-Options,X-Content-Type-Options,X-XSS-Protection,Strict-Transport-Security。【看起来是不错,但这对浏览器版本有没有要求呢?】
3. 不经意间泄露的业务信息:使用随机、唯一、不可预测值作为UUID;返回了多余数据。
4. API缺乏速率限制的保护。
详可参见:https://www.kancloud.cn/kancloud/rest-api-design-safety/78111
好,断点回滚,书接上文,http服务器首先查看重写规则,如果文件真实存在就会直接把这个文件返回;如果是一个动态请求,则根据URL重写模块的规则,把请求重写到一个rest风格的URL上,然后根据动态语言的脚本,决定调用什么类型的动态脚本解释器来处理这个请求。
我们以PHP语言为例来说的话,请求到达一个PHP的MVC框架后,框架首先应该会初始化一些环境参数,例如远端IP,请求参数等等,然后根据请求的URL送到一个路由器类里面去匹配路由,路由由上到下逐条匹配,一旦遇到URL能够匹配上的,而且请求方法也能够命中的话,那么请求就会由这个路由所定义的处理方法去处理。
请求进入处理函数后,如果客户端所所请求需要浏览的内容是一个动态内容,那么处理函数会相应的从数据源中取出数据,这个地方一般会有一个缓存,例如memcached来减少db的压力,如果引入了orm框架的话,处理函数直接向orm框架索要数据就可以了,由orm框架来决定使用缓存还是从db取数据,一般缓存都会有一个过期时间,而orm框架也会在取到数据回来后,把数据存一分在内存缓存中。
ORM[object Relation Mapping], 对象-关系映射,顾名思义实现程序对象到关系数据的映射,一般以中间件形式存在。【断点ORM】