HTTP协议详解

1.HTTP简介
  是超文本传输协议(Hyper Text Transfer Protocol)的缩写,是用于从万维网服务器传输超文本到本地浏览器的传送协议。
  是基于TCP/IP协议传送数据的的,是应用层的面向对象的协议。
  工作在客户端-服务端(CS)架构上,浏览器作为HTTP客户端通过URL向HTTP服务端即web服务器发送请求,web服务器根据接收到的需求,向客户端发送响应信息。

2.主要特点
  *简单快速:客户在想服务器发送请求时,只需传送请求方法和路径。请求常用方法GET、POST、HEAD等等,每种方法规定了客户与服务器联系的类型不同。由于HTTP协议简单,使得HTTP服务器的程序规模小,因而通信速度很快。
  *灵活:HTTP允许传输任意类型的数据对象。正在传输的类型由Content-Type标记。
  *无连接:限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户应答后,即断开连接,节省传输时间。
  *无状态:指协议对于事务的处理没有记忆能力,缺少状态意味着如果后续处理需要前面的信息,必须重传,这样可能导致每次连接传输的数据量增大。
  *支持B/S及C/S模式。

3.URL
  HTTP使用统一资源标识符(URI)来传输数据和建立连接,URL(统一资源定位符)是一种特殊类型的URI,是互联网上用来标识某一处资源的地址,包含了用于查找某个资源的足够信息。
组成部分:
  *协议:在Internet中可以使用多种协议:HTTP,HTTPS(安全超文本传输协议),FTP(文件传输协议),Telnet(远程登录服务协议)等等;
  *域名:比如www.baidu.com,也可以使用IP地址作为域名;
  *端口:端口号跟在域名之后,用:分割,端口号不是URL的必须部分,如果没有端口号,则采用默认端口号;
  *虚拟目录:是域名之后的第一个'/'到最后一个'/'为止,也是非必须部分;如https://www.cnblogs.com/ranyonsue/p/5984001.html;
  *文件名:从最后一个'/'到'?'或者'#'为文件名,若没有'?''#',则是从最后一个'/'到结束,都是文件名部分,文件名也不是必须部分,若
没有文件名,则采用默认文件。如https://www.cnblogs.com/ranyonsue/p/5984001.html;
  *锚:从'#'到最后都是锚,非必须部分。如http://www.aspxfans.com:8080/news/index.asp?boardID=5&ID=24618&page=1#name中name;
  *参数:从'?'到'#'部分都是参数,用于搜索或查询,可以有多个参数,用'&'分割;如上一条中的boardID=5&ID=24618&page=1;

4.URI & URL & URN
  URI——统一资源标识符,用来唯一的标识一个资源,URI由三个部分组成:访问资源的命名机制、存放资源的主机名、资源自身的名称,有路径标识。
  URL——统一资源定位器,一种具体的URI,标识一个资源,并指明了如何定位这个资源。
  URN——统一资源命名,通过名字来标识资源,也是URI的一种,URN命名资源,但不指定如何定位资源。

5.HTTP工作原理
  HTTP协议定义客户端如何从web服务器请求web页面,以及服务器如何把web页面传送给客户端。HTTP协议采用了请求/响应模型。客户端向服务器发送一个请求报文,包括请求方法、URL、协议版本、请求头部和请求数据。服务器响应的内容包括协议的版本、成功或者错误代码、服务器信息、响应头部和响应数据。
HTTP请求/响应步骤:
  Step1——客户端连接到web服务器:
    客户端(通常是浏览器)解析域名(DNS),并创建套接字。然后发起TCP的3次握手,客户端首先发出一个SYN消息(异步建立联机),服务器使用SYN+ACK应答表示接收到了这个消息,最后客户机再以ACK消息响应。这样就建立了可靠的连接。
  Step2——发送HTTP请求:通过TCP套接字,客户端向服务器发送一个文本的请求报文,一个请求报文由请求行、请求头部、空行、请求数据组成。
    请求:在第一行,由三部分组成:请求方法(GET/POST/DELETE/PUT/HEAD)、请求资源的URL、HTTP版本号。如:GET /index.html HTTP/1.1
    HTTP头部:一般包含三种头部:一般头、请求头、实体头,由于GET请求往往不包含内容实体,因此也不会有实体头。
    a) 一般头(General Headers):请求时间、连接状态;
    b) 请求头(Request Headers):包括cache头域、client头域、cookie/login头域、entity头域、miscellaneous头域、transport头域
     cache头域:
      If-Modified-Since: Thu, 09 Feb 2012 09:07:57 GMT,把浏览器端缓存页面的最后修改时间发送到服务端,服务器会把这个时间与服务器上实际文件的最后修改时间进行对比。如果一致,则返回304,客户端直接使用本地缓存文件;如果时间不一致,则返回200和新的文件内容,客户端丢弃旧文件,将新文件缓存起来,并显示在浏览器中。
      If-None-Match:"03f2b33c0bfcc1:0",和ETag(response里的信息)一起工作。当用户再次请求该资源时,将在HTTP Request中加入If-None-Match信息(ETag的值),如果服务器验证资源的ETag没有改变,也就是资源未更新,将返回304告诉客户端使用本地缓存;否则返回200和新的资源和ETag。
      Pragma:no-cache,(HTTP/1.0)防止页面被缓存,和Cache-Control:no-cache(HTTP/1.1)的作用一样。
      Cache-Control:用来指定Response-Request遵循的缓存机制
        Cache-Control:Public 可以被任何缓存所缓存
        Cache-Control:Private 内容只缓存到私有缓存中
        Cache-Control:no-cache 所有内容都不会被缓存
     Client头域
      Accept:浏览器端可以接受的媒体类型,例如Accept: text/html ,代表浏览器可以接受服务器返回的类型为text/html,若浏览器无法返回 text/html文件,则会返回406错误。Accept: */*,代表可以接受任何类型。还有text/javascript, application/javascript, application/ecmascript, application/x-ecmascript, */*;等等。
      Accept-Encoding:浏览器申明自己接收的编码方法,通常指定压缩方法,是否支持压缩,支持申明压缩方法(gzip, deflate, br),注意:不是字符编码;
      Accept-Language:浏览器申明自己接收的语言,中文,Accept-Language: zh-CN,zh;
      User-Agent:告诉服务器,客户端使用的操作系统和浏览器的名称和版本,例如User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36,
      Accept-Charset:浏览器声明自己接收的字符集(不同于语言,中文有好几种字符集如gbk,gb2312,big5),例如:Accept-Charset: UTF-8.
      Cookie/Login头域
      Cookie:最重要的header,将cookie的值发给服务器。
     Entity头域
      Content-length:发送给服务器数据的长度。比如:Content-Length: 38 .
      Content-Type:数据的类型,比如:Content-Type: application/x-www-form-urlencoded.
     Transport头域
      Connection:连接状态,如Connection: keep-alive ,当一个网页打开完成后,客户端和服务器之间的TCP连接不会关闭,如果客户端再次访问这个服务器上的网页,会继续使用这一条已经建立的连接。又如:Connection: close 代表一个Request完成后,客户端和服务器之间用于传输HTTP数据的TCP连接会关闭, 当客户端再次发送Request,需要重新建立TCP连接。
      Host:发送请求时,该报头域是必须的,用于指定被请求资源的Internet主机和端口号,通常从URL中提取出来。
      例如:访问http://www.guet.edu.cn/index.html,发送请求消息中的Host为http://www.guet.edu.cn,缺省端口为80。
     Miscellaneous头域
      Referer:提供了Request的上下文信息的服务器,告诉服务器我是从哪个链接过来的,比如从我的主页链接到一个朋友那里,他的服务器就能从Referer里计算出每天有多少用户是通过点击我主页上的链接而访问他的网站的。
      例如:Referer:http://translate.google.cn/?hl=zh-cn&tab=wT
    空行
      请求头后面的空行是必须的,即使请求数据为空行;
    请求数据
      一般GET方法的请求数据放在URL里,所以请求数据(报文体)部分为空;若是POST方法,报文体里存放的就是客户端给服务器的参数;
  Step3——服务器接受请求并返回HTTP响应
    web服务器解析请求,定位请求资源。服务器将资源副本写到TCP套接字,由客户端读取。一个响应由状态行、响应头部、空行、相应数据4部分组成。
    a) 响应行:一般由协议版本、状态吗机器描述组成,比如HTTP/1.1 OK
    b) 响应头:描述服务器的基本信息,以及数据的描述;
      Cache头域:
        Date:生成消息的具体时间和日期;
        Expires:指定过期时间,浏览器会在这个时间内使用本地缓存;
      Cookie/Login头域:
        P3P:用于跨域设置Cookie,这样可以解决iframe跨域访问cookie的问题;例如:例如: P3P: CP=CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR;
        Set-Cookie:用于把cookie发送到客户端浏览器,每写入一个cookie都会生成一个Set-Cookie。例如: Set-Cookie: sc=4c31523a; path=/; domain=.acookie.taobao.com;
      Entity头域:
        Etag:和If-None-Match配合使用。例如: ETag: "03f2b33c0bfcc1:0";
        Last-Modified:指示资源的最后修改日期和时间。例如: Last-Modified: Wed, 21 Dec 2011 09:09:10 GMT ;
        Content-Type:服务器告诉浏览器自己响应的对象的类型和字符集,例如:
          Content-Type: text/html; charset=utf-8
          Content-Type:text/html;charset=GB2312
          Content-Type: image/jpeg
        Content-Length:指明实体正文的长度,以字节方式存储的十进制数字来表示。在数据下行的过程中(S->C),Content-Length的方式要预先在服务器中缓存所有数据,然后一股脑地发给客户端。例如: Content-Length: 19847 (字节);
        Content-Encoding:服务器表明自己用了什么压缩方法(gzip, deflate)压缩响应中的对象。例如:Content-Encoding: gzip;
        Content-Language:服务器告诉浏览器自己响应对象的语言。例如: Content-Language:da ;
      Miscellaneous头域:
        Server:指明HTTP服务器的软件信息。例如:Server: Microsoft-IIS/7.5 ;
        X-AspNet-Version:如果网站是用ASP.NET开发的,这个header用来标识ASP.NET的版本。例如: X-AspNet-Version: 4.0.30319;
        X-Powered-By:标识网站是用什么技术开发的。例如: X-Powered-By: ASP.NET;
      Transport头域:
        Connection:例如 keep-alive 当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭,如果客户端再次访问这个服务器上的网页,会继续使用这个连接;例如 close 代表一个request完成后,客户端和服务器之间用于传输HTTP数据的TCP连接会关闭,当客户端再次发送Request,需要重新建立TCP连接;
      Location头域:
        Location:用于重定向一个新的位置,服务器会给浏览器一个新的URL;
    c) 空行
      必须存在;
    d) 响应体
      响应体就是响应的消息体,如果是纯数据就是返回纯数据,如果请求的是HTML页面,那么返回的就是HTML代码,如果是JS就是JS代码,如此之类。
  Step4——释放TCP连接
    若connection模式为close,则服务器主动关闭TCP连接,客户端被动关闭连接,释放TCP连接;若connection模式为keepalive,则该保持一段时间,在该时间内可以继续接收请求;
  Step5——客户端浏览器解析HTML内容
    浏览器首先解析状态行,查看请求是否成功。然后解析每一个响应头,响应头告知一下为若干字节的HTML文档和文档的字符集。浏览器读取响应数据HTML,根据HTML的语法对齐进行格式化,并在浏览器窗口中进行显示;


6.请求方法
  HTTP1.0定义了三种请求方法:GET, POST, HEAD;
  HTTP1.1新增了五种请求方法:OPRIONS, PUT, DELETE, TRACE, CONNECT;
  GET——请求指定的页面信息,并返回实体主体;
  POST——向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST请求可能会导致新的资源的建立或已有资源的修改;
  HEAD——类似于GET请求,只不过返回的响应中没有具体的内容,用于获取报头;
  PUT——从客户端向服务器传送的数据取代指定的文档的内容;
  DELETE——请求服务器删除指定的页面;
  CONNECT——HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器;
  OPTIONS——允许客户端查看服务器性能;
  TRACE——回显服务器收到的请求,主要用于测试或诊断;


7.GET和POST区别
  GET和POST本质上都是TCP连接,并无差别。但是由于HTTP的规定和浏览器/服务器的限制,导致他们在应用过程中体现出一些不同。其实GET和POST能做的事情是一样的,甚至给GET加上request body,给POST带上URL参数,技术上是完全行的通的。那为什么会有那些“标准答案”的区别呢?因为在万维网中,TCP用来运输数据,为了使整个系统更加可靠,HTTP规定了几种服务类型,GET、POST等等,也规定了GET请求时,要将请求参数放在URL里,POST时,要将参数放在请求报文体里。
  a) 请求数据的位置
    GET请求的数据会附在URL后面(也就是在请求行里)以?分割URL和传输数据,多个参数用&连接,如果是英文字母/数字,原样发送,如果是空格,转换为+,如果是中文或其他字符,则直接把字符串用BASE64加密,得出如:%E4%BD%A0%E5%A5%BD这样的字符串;
POST请求把提交的数据放在HTTP包的包体中;
    因此,GET提交的数据会在地址栏中显示出来,而POST提交,地址栏不会改变。
  b) 传输数据的大小:HTTP协议没有对传输的数据大小和URL的长度进行限制。而是浏览器和服务器限制数据的大小,降低风险,在实际中开发中的限制主要有:
    GET:特定浏览器和服务器对URL长度有限制,如IE 对URL长度的限制是2083字节(2K左右)。其他浏览器如Netscape、Firefox等,理论上没有长度限制,其限制取决于操作系统的支持。因此,GET的传输数据就会收到URL长度的限制。大多数服务器最多处理64K大小的URL;
    POST:由于不是通过URL传值,理论上数据不受限。但实际各个WEB服务器会对post提交数据大小进行限制;
  c) 安全性
    POST的安全性要比GET的安全性高。比如:通过GET提交数据,用户名和密码将明文出现在URL上,因为(1)登录页面有可能被浏览器缓存;(2)其他人查看浏览器的历史记录,那就可以拿到你的账号和密码了,除此之外,使用GET提交数据还有可能造成Cross-site-request-forgery(CSRF,跨站点请求伪造)攻击;
  d) 回退按钮/刷新
    GET在浏览器回退时是无害的,但是POST会再次提交请求;
  e) 缓存
    GET可以主动缓存,POST不可以,除非手动设置;
  f) 参数数据类型
    GET只接受ASCII字符,而POST没有限制;
  g) 请求包
    GET产生一个TCP数据包,而POST产生两个TCP数据包;GET方式,浏览器会把http header和data一并发送出去,服务器返回200和数据;对于POST,浏览器先发送header(告诉服务器,待会要有数据要传过来),服务器响应100 continue,浏览器再发送data,服务器响应200 ok和数据。当然也并不是所有浏览器都会在POST中发两次报,Firefox就只发送一次。
  注意:并不是请求两次,而是某些浏览器比如IE/Chrome/Safari分为两次发送,分别发送了请求Header和Body,在服务器日志上查看到的请求次数都是一次。
  结论:当网络环境好的情况下,1次包跟2次包的在时间上差别基本可以无视。而在网络环境差的情况下,(2次包)TCP的验证数据包完整性上,有非常大的优点,客户端先告诉服务端即将发送的数据包大小,MD5等标识,当服务端告诉客户端收到(ACK包)的时候,客户端再次向服务端发送POST 的DATA。假如网络环境不好,网络延迟、丢包的时候,服务端会等待(延迟时),客户端重发POST的DATA数据到服务单,来确保本次请求的完整性。

posted @ 2018-07-19 17:08  Trista222  阅读(247)  评论(0编辑  收藏  举报