对一个WEB请求的理解

随着写的WEB程序越来越多,项目的部署也越来越繁琐,对于一些线上问题总是搞不清楚是哪个环节出的问题,归根结底是对整个流程的不熟悉导致,所以分析下一个WEB请求从用户输入地址到页面出来到底经历过多少东西.

URL解析

首先把URL分割为几个部分,以地址http://mrdear.cn/2017/04/15/动漫推荐/为例
协议: http
网址: mrdear.cn
资源路径: 2017/04/15/动漫推荐/

浏览器拿到地址后会对其中非ASCII码的Unicode字符解析,比如空格会变成%20,汉字也会变成其16进制对应的编码值,如下例子:

1
2
上面链接等价于
http://mrdear.cn/2017/04/15/%E5%8A%A8%E6%BC%AB/%E5%8A%A8%E6%BC%AB%E6%8E%A8%E8%8D%90/

中间还有其他很复杂的流程,比如参数,协议,请求头,请求体等建立.

DNS域名解析

对于网址mrdear.cn,浏览器并不知道他所处的服务器位置,因此需要解析出其服务器ip,这个过程就是DNS域名解析.

  • 浏览器首先检查自身缓存dns解析,以chrome为例,输入chrome://net-internals/#dns即可看到缓存列表.该缓存通常几分钟到几小时不等,存在的话就直接返回,否则下一步
  • 和浏览器同样策略,OS对每一次解析结果也会做缓存,浏览器中不存在则在OS的缓存中查找.这个过成功也包括在本地hosts中查找.找到则返回,找不到则向本机的dns服务器发送查找请求.
  • DNS服务器和本机在一个子网内,则APR解析到具体设备的mac地址,然后向其查找.如果不在一个子网,则直接ARP解析当前主机网关地址,网关一般是上一个路由节点,也就是把查询转交给上一层服务器,那么上一层服务器找不到还会转交给它的上一层,如此形成一个递归查询过程,直到查找到根服务器.找不到则返回失败.找到则返回ip地址和其TTL时间.
    linux和unix下的dns配置在/etc/resolv.conf中,可以使用nslookup或者dig查看解析过程.

  • 解析成功后,浏览器创建与服务器的socket连接,构造请求信息,进行TCP三次握手,开始向服务器传输消息,并等服务器回复信息,这也是TPC可靠的一个原因.

服务器响应

服务器以nginx+tomcat为例,经过以上步骤后请求到达了nginx,nginx对URL进行分析,验证其所在机器上有所需要的服务,并且用户是有权限调用的,决定该URL由哪一个tomcat服务处理,捕获处理结果,返回给请求者,最后四次挥手结束请求.到此完成浏览器,服务端的通信.

浏览器渲染

浏览器拿到了服务器的返回信息后会对内容进行解析,展现成用户所需要的内容,如html,pdf等.


那么整个过程总结来看就是 用户输入URL -> 浏览器解析地址 -> DNS查找域名对应ip -> 服务器响应 ->浏览器拿到响应渲染.

附录

1.CDN网络

CDN又叫内容分布网络,一般用于静态资源如html,css,js的存储,简单的理解为一张大网,网上每一个节点都有着很多资源.那么每一个用户想要访问的时候就会去找离他最近的节点上面获取需要的内容.从而加快了网站整体访问速度.
举个例子:用户访问taobao的某css文件,首先浏览器会发送请求 -> DNS解析域名,这里一般会有一个DNS负载均衡服务器,其得到最适合用户的CDN节点ip -> 用户拿到CDN节点ip得到资源.

2.DNS劫持

了解了DNS的解析是一个递归过程,找到域名对应的ip就返回,如果有人手动修改了该条映射信息,那么就会返回到错误的ip地址,这种行为也叫DNS劫持,对于客户端来说,没有很好地方式能认为服务器返回的信息是可靠的,也就是不可靠的HTTP通信,所以也就导致了这一层的攻击漏洞,而这种事一般是天朝的电信运营商能干得出来,所以选择一个靠谱的DNS是非常重要,推荐114.114.114.114

3.HTTPS

应对HTTP的不可靠通信,所以诞生了HTTPS,即HTTP over SSL,使用SSL/TLS对HTTP的内容进行加密解密.整个流程如下图:

  • 在SSL握手阶段,客户端浏览器会认证服务器的身份,这是通过“证书”来实现的,证书由证书权威(CA)为某个域名签发,可以理解为网站的身份证件,客户端需要对这个证件进行认证,需要确定该证书是否属于目标网站并确认证书本身是否有效。最后在握手阶段,通信的双方还会协商出一个用于加密和解密的会话密钥。
  • SSL握手阶段结束之后,服务器和客户端使用协商出的会话密钥对交互的数据进行加密/解密操作,对于HTTP协议来说,就是将HTTP请求和应答经过加密之后再发送到网络上。
    HTTPS协议对服务器进行了一次身份验证,所以即使DNS被劫持,定向到的服务器也会因为没证书而无法通过身份验证.

4.乱码问题

流程清晰后乱码问题就很好解决了,把浏览器,Nginx,Tomcat等都当成水池的话,数据的乱码只能在每一个的入口端和出口端.如果发生了乱码,那么首先定位到是哪一个口产生了乱码,然后再去找原因,一般都能解决.
以JavaWEB应用为例,乱码主要发生在IO交互的过程中.其一浏览器与服务器建立socket连接,浏览器对URL以及request转换编码.请求到达tomcat,tomcat会对其进行解码,这个解码可在tomcat目录下的conf/server.xml中配置URIEncoding

1
2
<connector port=”8080″ protocol=”HTTP/1.1″ maxThreads=”150″   connectionTimeout=”200000″
redirecPort=”8443″ URIEncoding=”utf-8″/>

这里要保证不乱码,下一步tomcat建立了ServletRequest和ServletResponse,那么这里也有编码,一般是post表单或者request body乱码,那么就需要指定ServletRequest和ServletResponse的编码格式

1
2
request.setCharacterEncoding(encoding);//设置请求信息编码
response.setCharacterEncoding(encoding);//设置返回信息编码

Java程序在处理请求时和操作系统会有IO通信,和数据库会有IO通信,整个过程也会涉及编码,这种一般代码中会自动控制,出问题几率不大.
浏览器拿到返回信息后对页面进行渲染,这一步也会有编码,这个一般手动指定下浏览器的渲染编码,比如Content-Type: text/html;charset=UTF-8,指定以UTF-8渲染该text/html返回.

5.几种域名解析

域名解析记录主要分为:A 记录、MX记录、CNAME 记录、NS记录和 TXT记录

  • A记录:A 代表的是Address,用来指定域名对应的IP地址。域名可以多对一但是不能一对多。
  • MX记录:Mail Exchange,就是讲某个域名下的邮件服务器指向自己的Mail Server。
  • CNAME记录:别名解析。将一个域名设置一个或者多个别名。
  • NS记录:为某个域名指定DNS解析服务器。
  • TXT记录:为某个主机名或者域名设置文字说明。
    本站是托管于github的,主域名mrdear.cn是使用CNAME解析到nl101531.github.io的,二级域名oj.mrdear.cnmd.mrdear.cn都是使用A记录解析到对应主机的ip地址,到达主机后再使用Nginx进行不同的服务器转发.

后记

个人总结,如有错误请指出,以免误人子弟.

Angular2学习记录-给后端程序员的经验分享
Java--序列化知识点