学习了好一段时间的web开发了,从一开始接触近几年流行起来的angular.js,到node.js。几乎都把注意力放在了代码如何写才能达到怎么样的效果,特别是在node.js中感觉花了大多数时间去理解程序代码的结构,如何实现相应的功能,当用到session的时候无法保存想要缓存的变量,就很迷茫。。打印出整个session的内容也是让人瞬间就醉了。。实际上就是因为对web应用所依赖的这一套网络传输协议的不够熟悉,很多东西都是一知半解的,这样的状况显然会让开发变得很痛苦。。。
于是在一些压力下,我也好好研究了一下页面的背后到底发生了些什么。下面写下我在参考了一些大神的博文之后的个人的理解。
1、url的完整结构
schema://host/path/.../query_string/#anchor
如上所示,schema是表示用的什么协议,如http ,https等
host是要请求的主机名或者ip地址,如www.baidu.com或115.239.211.92
path是主机上的资源路径,就是某特定页面
query_string就是发送给服务器的数据,用于对页面的渲染等,比如请求商品详情页面对应哪一个商品的详情就由这里的数据确定
anchor表示锚,用于快速定位某页面的某锚元素,细节请参考google。。
2、在请求一个页面之后,浏览器如何将一个加载好的页面呈现给我们的
首先我们在url栏输入对应的url地址,格式如上。·按下回车之后,浏览器首先会查看本地缓存有没有对应资源的信息,并且向缓存中的该资源的主机发送一个请求确认是否有过改动,主机返回304表示没有改动,直接加载,否则重新从服务器请求页面。然后检查hosts文件,如果找到对应的主机地址就向该主机发送http request请求,如果hosts里边也没有的话就使用域名解析系统,向DNS服务器发送请求找到该主机的ip地址。然后浏览器就可以向服务器发送请求了,一般会受到请求的是代理服务器,在代理服务器上如果有缓存的对应资源就直接将该html页面回发给客户端,如果没有就通过一些负载均衡的算法来在服务器集群上寻找合适的服务器来处理该请求,这里负载均衡的一些算法以及服务器如何共享资源信息的问题就暂不讨论。这样从服务器就会通过给客户端发送一个http response信息回应客户端的请求,这个response信息里边就是这个请求对应的html页面。客户浏览器接收到这个response信息的时候,会对这个文件进行渲染,当发现页面当中有包括图片,css,javascript等资源文件时,就会再次向服务器发送http请求以获取页面需要的资源文件,一次请求请求一个文件,在http1.0中http协议的connection属性没有keep-alive,因此每次都会再次建立连接,在http1.1中连接默认都有一个属性是keep-alive的,因此在再次请求资源的时候不需要再次建立连接(当然这里再次请求资源文件的时候,每一个请求是没有先后顺序的可以同时发起,但是会有限制在6个左右,根据chrome团队的实验,连接数达到10效率就会有很大的下降)。好了,当所有资源加载完了,一个完整的页面也就呈现在我们的浏览器中了。
3、http request结构
上图是我用wireshark抓取的一条request信息,这个应该是在加载页面之后再次发送的请求一个资源文件的请求信息。
第一行是 request line 包含了http方法 GET ; 资源路径和参数 ; 然后是http协议的版本 1.1
接下来是request header信息 host是主机名就是要请求的服务器主机 connection :keep-alive 默认值就是保持连接 Accept表示了客户端要接受的资源文件类型 User-agent显示的是客户端的浏览器信息,系统信息等
然后是Accept-Encoding 是告诉服务器客户端的解压方法 最后还有一个accept-language则是说明客户端接受的语言有哪些
然后request信息应该还包括request body,body和header之间会有一个空行,但是因为是GET方法,所以body中的内容为空。
下面是一个POST方法的request信息截图
可以看到下面多了一个FORM,这里面就是post给服务器传输的数据
4、到这里就说一说GET和POST方法的区别吧
(1)、GET和POST都可以向服务器发送数据,但是他们所发送的数据是在http request的不同部位的,GET方法发送的数据是在URL里边,作为query string的方式传给服务器的,而POST方法中的数据是在request body中发送的。
(2)、因为url中的数据是很容易获取的,所以显然使用POST传输的数据安全性要高很多,对于用户名密码这种数据就需要选择POST方法传输
(3)、因为url可以传输的数据是有限制的,所以GET方法传输的数据也就是有限制的,而requestbody内的数据理论上是没有限制的,因为如果数据过多,就可以分包发送,也就没有限制。
(4)、还有获取GET方法传输的数据使用Request.QueryString,而获取POST中的数据用Request.Form。
5、http response消息结构
如上所示是抓取的一个response信息
第一行是 Response line 包含了http版本号 1.1 然后是状态码 200 (表示响应成功) 响应消息 OK
然后是response header connection: close就是说不要保持连接 接着是服务器信息 Date : 生成消息的具体时间
Cache-control : 后面几个参数 private 只缓存到私有缓存 no-cache 就是不要缓存 。。。
Content-Length :117 是正文的长度
Content-Type :text/html 是正文的文件类型
在往下面Line=based text 是body的内容 就是服务器返回个客户端的html文件 当然这里也可以是js css等资源文件, 这里的文件是 text/html.。