HTTP协议详解以及URL具体访问过程

一、简介

  1.一、HTTP协议是什么?html

  即超文本传输协议(HTTP,HyperText Transfer Protocol)是互联网上应用最为普遍的一种网络协议,全部的WWW文件都必须遵照这个标准。从网络参考模型来看,它是属于应用层。它规定了计算机通讯网络中两台计算机之间进行通讯所必须共同遵照的规定或规则,它容许将超文本标记语言(HTML)文档从Web服务器传送到客户端的浏览器。java

  简单的来讲,它就是基于应用层一个规范一个标准!通信双发都须要遵照这一准则,这就是http协议!node

  1.二、http简史linux

  设计HTTP最初的目的是为了提供一种发布和接收HTML页面的方法。1960年美国人Ted Nelson构思了一种经过计算机处理文本信息的方法,并称之为超文本(hypertext),这成为了HTTP超文本传输协议标准架构的发展根基。Ted Nelson组织协调万维网协会(World Wide Web Consortium)和互联网工程工做小组(Internet Engineering Task Force )共同合做研究,最终发布了一系列的RFC,其中著名的RFC 2616定义了HTTP 1.1,这也是咱们如今最经常使用的版本,在此以前还存在HTTP 1.0版本以及HTTP 0.9版本nginx

二、URI与URL

  问: 为何要区别URI与URL呢?web

  答:由于我看书看博客资料都遇到过着两个名词,第一次遇到是在学习API的时候,那时候我是一脸懵逼,不是怎么区分,感受看过去都是一串网址呀!事实并不是如此。面试

  URI:统一资源标示符,只是标识资源在哪里,这意味着存在多个URI能够指向该资源(例如:绝对与相对)【URI包含URL】正则表达式

  URI通常由三部分组成:
    1. 访问资源的命名机制。 
    2. 存放资源的主机名。 
    3. 资源自身的名称,由路径表示。 chrome

  语法:[scheme:] scheme-specific-part 

  URI以scheme和冒号开头。Scheme用大写/小写字母开头,后面为空或者跟着更多的大写/小写字母、数字、加号、减号和点号。冒号把 scheme与scheme-specific-part分开了,而且scheme-specific-part的语法和语义(意思)由URI的名字空间决定。以下面的例子:
  http://www.cnn.com,其中http是scheme,//www.cnn.com是 scheme-specific-part,而且它的scheme与scheme-specific-part被冒号分开了。

  绝对与相对:

  绝对的URI指以scheme(后面跟着冒号)开头的URI。(例如:mailto:jeff@javajeff.com、news:comp.lang.java.help和xyz: //whatever);绝对的URI看做是以某种方式引用某种资源,而这种方式对标识符出现的环境没有依赖。

  相对的URI不是以scheme(后面跟着冒号)开始的URI。(例如:articles/articles.html、img/aa.jpg)你能够把相对的URI看做是以某种方式引用某种资源,而这种方式依赖于标识符出现的环境。(即你在html中引用图片:./img/aa.jpg,那么它依赖的就是http)

  URL:统一资源定位符,是URI的子集;它除了标识资源的位置,还提供一种定位该资源的主要访问机制(如其网络“位置”)。【即提供具体方式找到该资源(位置+方式)】

  URL的格式由下列三部分组成: 
    1. 第一部分,是协议或称为服务方式 (指定低层使用的协议,例如:http, https, ftp);
    2. 第二部分,是存有该资源的主机IP地址(有时也包括端口号); 
        3. 第三部分,是主机资源的具体地址。如目录和文件名等。 

  第一部分和第二部分之间用"://"符号隔开,第二部分和第三部分用"/"符号隔开。第一部分和第二部分是不可缺乏的,第三部分有时能够省略。 

三、TCP握手链接以及断开(扩展)

  TCP通讯过程包括三个步骤:创建TCP链接通道,传输数据,断开TCP链接通道。引用oneSong所画的一张金典TCP通信图片

  上图中主要分为三部分:创建链接、传输数据、断开链接。

  创建链接:

  三次握手便可创建TCP链接

  一、第一次握手:客户端发送syn包(seq=x)到服务器,并进入SYN_SEND状态,等待服务器确认;

  二、第二次握手:服务器收到syn包,必须确认客户的SYN(ack=x+1),同时本身也发送一个SYN包(seq=y),即SYN+ACK包,此时服务器进入SYN_RECV状态;

  三、第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=y+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。

  握手过程当中传送的包里不包含数据,三次握手完毕后,客户端与服务器才正式开始传送数据。理想状态下,TCP链接一旦创建,在通讯双方中的任何一方主动关闭链接以前,TCP 链接都将被一直保持下去。

  为何须要三次握手呢?

  相互确认!(网上有不少解释,这里就很少讲了)

  数据传输:

  创建好链接后,开始传输数据。TCP数据传输牵涉到的概念不少:超时重传、快速重传、流量控制、拥塞控制等等。(这一切都是为了提供可靠的字节流服务)

  断开链接:

  四次握手便可断开TCP链接

  一、第一次握手:主动关闭方发送一个FIN,用来关闭主动方到被动关闭方的数据传送,也就是主动关闭方告诉被动关闭方:我已经不会再给你发数据了(固然,在fin包以前发送出去的数据,若是没有收到对应的ack确认报文,主动关闭方依然会重发这些数据),但此时主动关闭方还能够接受数据。

  二、第二次握手:被动关闭方收到FIN包后,发送一个ACK给对方,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号)。

  三、第三次握手:被动关闭方发送一个FIN,用来关闭被动关闭方到主动关闭方的数据传送,也就是告诉主动关闭方,个人数据也发送完了,不会再给你发数据了。

  四、第四次握手:主动关闭方收到FIN后,发送一个ACK给被动关闭方,确认序号为收到序号+1,至此,完成四次挥手。

  白话文:

  一、第一次握手,浏览器对服务器说:“煞笔,我再也不给你发数据啦,但能够接受数据。”

  二、第二次握手,服务器对浏览器说:“骚货,我知道啦!”

  三、第三次握手,服务器对浏览器说:“骚货,我也再也不给你发数据啦!”

  四、第四次握手,浏览器对服务器说:“煞笔,我知道啦!”

四、特色

HTTP协议永远都是客户端发起请求,服务器回送响应。这样就限制了使用HTTP协议,没法实如今客户端没有发起请求的时候,服务器将消息推送给客户端。、

主要特色:

  一、支持客户/服务器模式。一旦创建了运输链接(这经常称为创建了会话),浏览器端就向万维网服务器端发送HTTP请求,服务器收到请求后给出HTTP响应。
  二、简单快速:客户向服务器请求服务时,只需传送请求方法和路径。请求方法经常使用的有GET、HEAD、POST。每种方法规定了客户与服务器联系的类型不一样。因为HTTP协议简单,使得HTTP服务器的程序规模小,于是通讯速度很快。
  三、灵活:HTTP容许传输任意类型的数据对象。正在传输的类型由Content-Type加以标记。
  四、HTTP 0.9和1.0使用非持续链接:限制每次链接只处理一个请求,服务器处理完客户的请求,并收到客户的应答后,即断开链接。HTTP 1.1使用持续链接:没必要为每一个web对象建立一个新的链接,一个链接能够传送多个对象,采用这种方式能够节省传输时间。
  五、无状态:HTTP协议是无状态协议。即每个HTTP请求都是独立的。万维网服务器不保存过去的请求和过去的会话记录。这就是说,同一个用户再次访问同一个服务器时,只要服务器没有进行内容的更新,服务器的响应就给出和之前被访问时相同的响应。服务器不记录曾经访问过的用户,也不记录某个用户访问过多少次。

五、HTTP请求

  5.一、Request 消息的结构

  请求消息的结构由三部分组成,请求行、请求头、请求主体(即:请求行、消息报头、请求正文。)

【请  求 行】请求方法 空格 请求资源地址(URI、无域名) 空格 HTTP版本 空格 CRLF(换行符)

【请  求 头】标识:内容 CRLF(换行符)

【空  一 行】(表示请求头结束)

【请求主体】(即请求正文,用户的主要数据。POST方式时使用,GET无请求主体)

  在HTTP/1.1 协议中,全部的请求头,除Host外,都是可选的。  

  例:

复制代码
GET /phpstudy2015-6/ HTTP/1.1
Host: www.cnblogs.com
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.0.10) Gecko/2009042316 Firefox/3.0.10
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
If-Modified-Since: Sat, 06 May 2017 12:05:41 GMT
复制代码

  5.二、请求方法

  HTTP/1.1协议中共定义了八种方法(有时也叫“动做”)来代表Request-URI指定的资源的不一样操做方式,最基本的有4种,分别是GET,POST,PUT,DELETE。一个URL地址用于描述一个网络上的资源,而HTTP中的GET, POST, PUT, DELETE就对应着对这个资源的查,改,增,删4个操做。 咱们最多见的就是GET和POST了。GET通常用于获取/查询资源信息,而POST通常用于更新资源信息。

  【咱们在浏览器地址栏直接输入地址的时候,采用的就是GET方法】

各方法以下:

  一、GET:向特定的资源发出请求

  二、POST:向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST请求可能会致使新的资源的创建和/或已有资源的修改。

  三、PUT:向指定资源位置上传其最新内容。

  四、DELETE:请求服务器删除Request-URI所标识的资源。

  五、HEAD: 向服务器索要与GET请求相一致的响应,只不过响应体将不会被返回。这一方法能够在没必要传输整个响应内容的状况下,就能够获取包含在响应消息头中的元信息。该方法经常使用于测试超连接的有效性,是否能够访问,以及最近是否更新。

  六、TRACE:请求服务器会送收到的请求信息,主要用于测试或诊断。

  七、OPTIONS:请求查询服务器的性能,或者查询与资源相关的选项和需求

  八、CONNECT: HTTP/1.1协议中预留给可以将链接改成管道方式的代理服务器。(即留为未来使用)

  【注意:请求方法区分大小写;所示请求方法应为大写】

GET与POST的区别:

  一、GET提交的数据会放在URL以后,以?分割URL和传输数据,参数之间以&相连,如EditPosts.aspx?postid=6810130&update=1 ;POST方法是把提交的数据放在HTTP包的Body中。

  二、GET提交的数据大小有限制(由于浏览器对URL的长度有限制),而POST方法提交的数据没有限制。

  三、GET方式须要使用Request.QueryString来取得变量的值,而POST方式经过Request.Form来获取变量的值。

  四、GET方式提交数据,会带来安全问题,好比一个登陆页面,经过GET方式提交数据时,用户名和密码将出如今URL上,若是页面能够被缓存或者其余人能够访问这台机器,就能够从历史记录得到该用户的帐号和密码。

  5.三、http的无状态以及创建链接方式

  无状态:

  http协议为了保证服务器的内存,不会维持客户端发过来的请求,即同一个客户端的此次请求和上次请求是没有对应关系,对http服务器来讲,它并不知道这两个请求来自同一个客户端。例如:一个浏览器在短短几秒以内两次访问同一对象时,服务器进程不会由于已经给它发过应答报文而不接受第二期服务请求。

  为了解决这个问题, Web程序引入了Cookie机制来维护状态。

  创建链接方式:

  HTTP中支持两种链接方式:非持久链接和持久链接(HTTP1.1默认的链接方式为持久链接)。

  一、非持久链接方式(采用访问例子来讲明)

  让咱们查看一下非持久链接状况下从服务器到客户传送一个Web页面的步骤。假设该贝面由1个基本HTML文件和10个JPEG图像构成,并且全部这些对象都存放在同一台服务器主机中。再假设该基本HTML文件的URL为:cnblogs.com/phpstudy2015-6/index.html。

  下面是具体步骡:

  1. HTTP客户初始化一个与服务器主机cnblogs.com中的HTTP服务器的TCP链接。HTTP服务器使用默认端口号80监听来自HTTP客户的链接创建请求。

  2. HTTP客户经由与TCP链接相关联的本地套接字发出—个HTTP请求消息。这个消息中包含路径名/somepath/index.html。

  3. HTTP服务器经由与TCP链接相关联的本地套接字接收这个请求消息,再从服务器主机的内存或硬盘中取出对象/somepath/index.html,经由同一个套接字发出包含该对象的响应消息。

  4. HTTP服务器告知TCP关闭这个TCP链接(不过TCP要到客户收到刚才这个响应消息以后才会真正终止这个链接)。

  5. HTTP客户经由同一个套接字接收这个响应消息。TCP链接随后终止。该消息标明所封装的对象是一个HTML文件。客户从中取出这个文件,加以分析后发现其中有10个JPEG对象的引用。

  6.给每个引用到的JPEG对象重复步骡1-4。

  上述步骤之因此称为使用非持久链接,缘由是每次服务器发出一个对象后,相应的TCP链接就被关闭,也就是说每一个链接都没有持续到可用于传送其余对象。每一个TCP链接只用于传输一个请求消息和一个响应消息。就上述例子而言,用户每请求一次那个web页面,就产生11个TCP链接。

  二、持久链接

  非持久链接有一个很大的缺点就是,每个http请求都须要创建一个TCP链接,就上面的例子而言,get一个html页面就要创建十一次TCP链接,这是严重浪费资源行为!

  首先,客户得为每一个待请求的对象创建并维护一个新的链接。对于每一个这样的链接,TCP得在客户端和服务器端分配TCP缓冲区,并维持TCP变量。对于有可能同时为来自数百个不一样客户的请求提供服务的web服务器来讲,这会严重增长其负担。其次,如前所述,每一个对象都有2个RTT的响应延长——一个RTT用于创建TCP链接另—个RTT用于请求和接收对象。最后,每一个对象都遭受TCP缓启动,由于每一个TCP链接都起始于缓启动阶段。不过并行TCP链接的使用可以部分减轻RTT延迟和缓启动延迟的影响。

【RTT(Round-Trip Time): 往返时延。在计算机网络中它是一个重要的性能指标,表示从发送端发送数据开始,到发送端收到来自接收端的确认(接收端收到数据后便当即发送确认),总共经历的时延。】

  持久链接就可以很好解决这一缺点,在持久链接状况下,服务器在发出响应后让TCP链接继续打开着。同一对客户/服务器之间的后续请求和响应能够经过这个链接发送。整个Web页面(上例中为包含一个基本HTMLL文件和10个图像的页面)自不用说能够经过单个持久TCP链接发送:甚至存放在同一个服务器中的多个web页面也能够经过单个持久TCP链接发送。

  一般,HTTP服务器在某个链接闲置一段特定时间后关闭它,而这段时间一般是能够配置的。

  持久链接分为不带流水线(without pipelining)和带流水线(with pipelining)两个版本。

  不带流水线的版本:

  客户只在收到前一个请求的响应后才发出新的请求。这种状况下,web页面所引用的每一个对象(上例中的10个图像)都经历1个RTT的延迟,用于请求和接收该对象。与非持久链接2个RTT的延迟相比,不带流水线的持久链接已有所改善,不过带流水线的持久链接还能进一步下降响应延迟。不带流水线版本的另外一个缺点是,服务器送出一个对象后开始等待下一个请求,而这个新请求却不能立刻到达。这段时间服务器资源便闲置了。

  带流水线的持久链接:

  HTTP/1.1的默认模式使用带流水线的持久链接。这种状况下,HTTP客户每碰到一个引用就当即发出一个请求,于是HTTP客户能够一个接一个紧挨着发出各个引用对象的请求。服务器收到这些请求后,也能够一个接一个紧挨着发出各个对象。若是全部的请求和响应都是紧挨着发送的,那么全部引用到的对象一共只经历1个RTT的延迟(而不是像不带流水线的版本那样,每一个引用到的对象都各有1个RTT的延迟)。另外,带流水线的持久链接中服务器空等请求的时间比较少。与非持久链接相比,持久链接(不管是否带流水线)除下降了1个RTT的响应延迟外,缓启动延迟也比较小。其缘由在于既然各个对象使用同一个TCP链接,服务器发出第一个对象后就没必要再以一开始的缓慢速率发送后续对象。相反,服务器能够按照第一个对象发送完毕时的速率开始发送下一个对象。 

  5.四、请求行

  正如上面所讲的,请求行以一个方法符号开头,空格以后,一个请求URI,再空格,而后一个HTTP版本,最后一个回车换行。

  它的做用是用来讲明当前请求的最基本信息。

  5.五、请求头

  (注:在HTTP/1.1 协议中,全部的请求头,除Host外,都是可选的)

  #请求头的书写形式为:Host:coblogs.com \r\n【标识符:内容 换行】

  常见的请求头:

  一、Host:(发送请求时,该头域是必需的)主要用于指定被请求资源的Internet主机和端口号,它一般从HTTP URL中提取出来的。HTTP/1.1请求必须包含主机头域,不然系统会以400状态码返回。
  例如: 咱们在浏览器中输入:http://www.guet.edu.cn/index.html,浏览器发送的请求消息中,就会包含Host请求头域:Host:http://www.guet.edu.cn,此处使用缺省端口号80,若指定了端口号,则变成:Host:指定端口号。

  二、User-Agent:告诉HTTP服务器,客户端使用的操做系统和浏览器的名称和版本。
  例如: User-Agent: Mozilla/5.0 (Windows NT 6.3; Win64; x64; rv:53.0) Gecko/20100101 Firefox/53.0

  三、Content-Type:例如:Content-Type: application/x-www-form-urlencoded

  四、Accept-Language:浏览器申明本身接收的语言。语言跟字符集的区别:中文是语言,中文有多种字符集,好比big5,gb2312,gbk等等;例如:Accept-Language: en-us。若是请求消息中没有设置这个报头域,服务器假定客户端对各类语言均可以接受。

  五、Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

  六、Accept-Encoding:浏览器申明本身可接收的编码方法,一般指定压缩方法,是否支持压缩,支持什么压缩方法(gzip,deflate);Servlet可以向支持gzip的浏览器返回经gzip编码的HTML页面。许多情形下这能够减小5到10倍的下载时间。

  例如: Accept-Encoding: gzip, deflate。若是请求消息中没有设置这个域,服务器假定客户端对各类内容编码均可以接受。

  七、Cookie:最重要的请求头之一, 将cookie的值发送给HTTP服务器。

  八、Connection:HTTP 1.1默认进行持久链接keep-alive。
  例如:Connection: keep-alive 当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的TCP链接不会关闭,若是客户端再次访问这个服务器上的网页,会继续使用这一条已经创建的链接。

  利用持久链接的优势,当页面包含多个元素时(例如Applet,图片),显著地减小下载所须要的时间。要实现这一点,Servlet须要在应答中发送一个Content-Length头,最简单的实现方法是:先把内容写入ByteArrayOutputStream,而后在正式写出内容以前计算它的大小。
  Connection: close 表明一个Request完成后,客户端和服务器之间用于传输HTTP数据的TCP链接会关闭,当客户端再次发送Request,须要从新创建TCP链接。

  九、Keep-Alive:30保持持久链接30s

  十、If-Modified-Since:把浏览器端缓存页面的最后修改时间发送到服务器去,服务器会把这个时间与服务器上实际文件的最后修改时间进行对比。若是时间一致,那么返回304,客户端就直接使用本地缓存文件。若是时间不一致,就会返回200和新的文件内容。客户端接到以后,会丢弃旧文件,把新文件缓存起来,并显示在浏览器中。

  例如:If-Modified-Since: Sat, 06 May 2017 12:05:41 GMT

  十一、If-None-Match:If-None-Match和ETag一块儿工做,工做原理是在HTTP Response中添加ETag信息。 当用户再次请求该资源时,将在HTTP Request 中加入If-None-Match信息(ETag的值)。若是服务器验证资源的ETag没有改变(该资源没有更新),将返回一个304状态告诉客户端使用本地缓存文件。不然将返回200状态和新的资源和Etag.  使用这样的机制将提升网站的性能。

  例如: If-None-Match: "03f2b33c0bfcc1:0"。

  十二、Pragma:指定“no-cache”值表示服务器必须返回一个刷新后的文档,即便它是代理服务器并且已经有了页面的本地拷贝;在HTTP/1.1版本中,它和Cache-Control:no-cache做用如出一辙。Pargma只有一个用法, 例如: Pragma: no-cache

  1三、Cache-Control:指定请求和响应遵循的缓存机制。缓存指令是单向的(响应中出现的缓存指令在请求中未必会出现),且是独立的(在请求消息或响应消息中设置Cache-Control并不会修改另外一个消息处理过程当中的缓存处理过程)。请求时的缓存指令包括no-cache、no-store、max-age、max-stale、min-fresh、only-if-cached,响应消息中的指令包括public、private、no-cache、no-store、no-transform、must-revalidate、proxy-revalidate、max-age、s-maxage。

  注意: 在HTTP/1.0版本中,只实现了Pragema:no-cache, 没有实现Cache-Control

  Cache-Control:Public 能够被任何缓存所缓存
  Cache-Control:Private 内容只缓存到私有缓存中
  Cache-Control:no-cache 全部内容都不会被缓存
  Cache-Control:no-store 用于防止重要的信息被无心的发布。在请求消息中发送将使得请求和响应消息都不使用缓存。
  Cache-Control:max-age 指示客户机能够接收生存期不大于指定时间(以秒为单位)的响应。
  Cache-Control:min-fresh 指示客户机能够接收响应时间小于当前时间加上指定时间的响应。
  Cache-Control:max-stale 指示客户机能够接收超出超时期间的响应消息。若是指定max-stale消息的值,那么客户机能够接收超出超时期指定值以内的响应消息。

  1四、Accept-Charset:浏览器可接受的字符集。若是在请求消息中没有设置这个域,缺省表示任何字符集均可以接受。

  1五、Referer:包含一个URL,用户从该URL表明的页面出发访问当前请求的页面。提供了Request的上下文信息的服务器,告诉服务器我是从哪一个连接过来的,好比从我主页上连接到一个朋友那里,他的服务器就可以从HTTP Referer中统计出天天有多少用户点击我主页上的连接访问他的网站。

  例如: Referer:http://translate.google.cn/?hl=zh-cn&tab=wT

  1六、Content-Length:表示请求消息正文的长度。例如:Content-Length: 38。

  1七、From:请求发送者的email地址,由一些特殊的Web客户程序使用,浏览器不会用到它。

  1八、Range:能够请求实体的一个或者多个子范围。

  例如:
  表示头500个字节:bytes=0-499
  表示第二个500字节:bytes=500-999
  表示最后500个字节:bytes=-500
  表示500字节之后的范围:bytes=500-
  第一个和最后一个字节:bytes=0-0,-1
  同时指定几个范围:bytes=500-600,601-999
  可是服务器能够忽略此请求头,若是无条件GET包含Range请求头,响应会以状态码206(PartialContent)返回而不是以200(OK)。 

  5.六、请求主体

  请求的主要用户数据,就是POST数据。

  若是方式为POST,则须要请求主体部分;GET则没有请求主体

  数据形式:相似name=XXX&pwd=XXXX的内容 

六、HTTP响应

  6.一、Response 消息的结构

  响应消息的结构由三部分组成,响应行、相应头、相应主体(即:状态行、消息报头、响应正文。)

【响  应 行】HTTP版本 空格 状态码 空格 状态码的文本描述 空格 CRLF(换行符)

【响  应 头】:内容 CRLF(换行符)

【空  一 行】(表示响应头结束)

【响应主体】所谓响应主体,就是服务器返回的资源的内容。即整个HTML文件。

  6.二、响应行

  响应数据的第一行,响应结果的概述。

  状态码:

  状态代码有3位数字组成,状态描述给出了状态代码简短的描述。状态码第一个数字定义了响应的类别,有五种可能取值:
  1xx  :  指示信息--表示请求已接收,继续处理
  2xx  :  成功--表示请求已被成功接收、理解、接受
  3xx  :  重定向--要完成请求必须进行更进一步的操做
  4xx  :  客户端错误--请求有语法错误或请求没法实现
  5xx  :  服务器端错误--服务器未能实现合法的请求

  全部状态码以下(已折叠):

  100——客户必须继续发出请求
  101——客户要求服务器根据请求转换HTTP协议版本

  200——交易成功
  201——提示知道新文件的URL
  202——接受和处理、但处理未完成
  203——返回信息不肯定或不完整
  204——请求收到,但返回信息为空
  205——服务器完成了请求,用户代理必须复位当前已经浏览过的文件
  206——服务器已经完成了部分用户的GET请求

  300——请求的资源可在多处获得
  301——删除请求数据
  302——在其余地址发现了请求数据
  303——建议客户访问其余URL或访问方式
  304——客户端已经执行了GET,但文件未变化
  305——请求的资源必须从服务器指定的地址获得
  306——前一版本HTTP中使用的代码,现行版本中再也不使用
  307——申明请求的资源临时性删除

  400——错误请求,如语法错误
  401——请求受权失败
  402——保留有效ChargeTo头响应
  403——请求不容许
  404——没有发现文件、查询或URl
  405——用户在Request-Line字段定义的方法不容许
  406——根据用户发送的Accept拖,请求资源不可访问
  407——相似401,用户必须首先在代理服务器上获得受权
  408——客户端没有在用户指定的饿时间内完成请求
  409——对当前资源状态,请求不能完成
  410——服务器上再也不有此资源且无进一步的参考地址
  411——服务器拒绝用户定义的Content-Length属性请求
  412——一个或多个请求头字段在当前请求中错误
  413——请求的资源大于服务器容许的大小
  414——请求的资源URL长于服务器容许的长度
  415——请求资源不支持请求项目格式
  416——请求中包含Range请求头字段,在当前请求资源范围内没有range指示值,请求也不包含If-Range请求头字段
  417——服务器不知足请求Expect头字段指定的指望值,若是是代理服务器,多是下一级服务器不能知足请求

  500——服务器产生内部错误
  501——服务器不支持请求的函数
  502——服务器暂时不可用,有时是为了防止发生系统过载
  503——服务器过载或暂停维修
  504——关口过载,服务器使用另外一个关口或服务来响应用户,等待时间设定值较长
  505——服务器不支持或拒绝支请求头中指定的HTTP版本
View Code

  6.三、响应头

  同理,请求头!

  HTTP常见的响应头:

  一、Date:表示消息发送的时间,时间的描述格式由rfc822定义。例如,Date:Sat, 06 May 2017 12:16:56 GMT。Date描述的时间表示世界标准时,换算成本地时间,须要知道用户所在的时区。你能够用setDateHeader来设置这个头以免转换时间格式的麻烦  

  二、Content-Type:WEB服务器告诉浏览器本身响应的对象的类型和字符集。Servlet默认为text/plain,但一般须要显式地指定为text/html。因为常常要设置Content-Type,所以HttpServletResponse提供了一个专用的方法setContentType。可在web.xml文件中配置扩展名和MIME类型的对应关系。

  例如:

  Content-Type: text/html;charset=utf-8
  Content-Type:text/html;charset=GB2312
  Content-Type: image/jpeg

  媒体类型的格式为:大类/小类,好比text/html。
  IANA(The Internet Assigned Numbers Authority,互联网数字分配机构)定义了8个大类的媒体类型,分别是:
  application— (好比: application/vnd.ms-excel.)
  audio (好比: audio/mpeg.)
  image (好比: image/png.)
  message (好比,:message/http.)
  model(好比:model/vrml.)
  multipart (好比:multipart/form-data.)
  text(好比:text/html.)
  video(好比:video/quicktime.)

  三、Expires:指明应该在何时认为文档已通过期,从而再也不缓存它,从新从服务器获取,会更新缓存。过时以前使用本地缓存。HTTP1.1的客户端和缓存会将非法的日期格式(包括0)看做已通过期。

  eg:为了让浏览器不要缓存页面,咱们也能够将Expires实体报头域,设置为0。
  例如: Expires: Tue, 08 Feb 2022 11:35:14 GMT

  四、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:很是重要的header, 用于把cookie发送到客户端浏览器,每个写入cookie都会生成一个Set-Cookie。
  例如: Set-Cookie: sc=4c31523a; path=/; domain=.acookie.taobao.com

  六、ETag:和If-None-Match 配合使用。

  七、Last-Modified:用于指示资源的最后修改日期和时间。Last-Modified也可用setDateHeader方法来设置。

  八、Content-Range:用于指定整个实体中的一部分的插入位置,他也指示了整个实体的长度。在服务器向客户返回一个部分响应,它必须描述响应覆盖的范围和整个实体长度。通常格式:Content-Range:bytes-unitSPfirst-byte-pos-last-byte-pos/entity-length。
  例如,传送头500个字节次字段的形式:Content-Range:bytes0-499/1234若是一个http消息包含此节(例如,对范围请求的响 应或对一系列范围的重叠请求),Content-Range表示传送的范围。

  九、Content-Length:指明实体正文的长度,以字节方式存储的十进制数字来表示。在数据下行的过程当中,Content-Length的方式要预先在服务器中缓存全部数据,而后全部数据再一古脑儿地发给客户端。只有当浏览器使用持久HTTP链接时才须要这个数据。若是你想要利用持久链接的优点,能够把输出文档写入ByteArrayOutputStram,完成后查看其大小,而后把该值放入Content-Length头,最后经过byteArrayStream.writeTo(response.getOutputStream()发送内容。

  例如: Content-Length: 19847

  十、Content-Encoding:WEB服务器代表本身使用了什么压缩方法(gzip,deflate)压缩响应中的对象。只有在解码以后才能够获得Content-Type头指定的内容类型。利用gzip压缩文档可以显著地减小HTML文档的下载时间。Java的GZIPOutputStream能够很方便地进行gzip压缩,但只有Unix上的Netscape和Windows上的IE 四、IE 5才支持它。所以,Servlet应该经过查看Accept-Encoding头(即request.getHeader("Accept-Encoding"))检查浏览器是否支持gzip,为支持gzip的浏览器返回经gzip压缩的HTML页面,为其余浏览器返回普通页面。
  例如:Content-Encoding:gzip

  十一、Content-Language:WEB服务器告诉浏览器本身响应的对象所用的天然语言。

  例如: Content-Language:da。没有设置该域则认为实体内容将提供给全部的语言阅读。

  十二、Server:指明HTTP服务器用来处理请求的软件信息。例如:Server: Microsoft-IIS/7.五、Server:Apache-Coyote/1.1。此域能包含多个产品标识和注释,产品标识通常按照重要性排序

  1三、X-AspNet-Version:若是网站是用ASP.NET开发的,这个header用来表示ASP.NET的版本。
  例如: X-AspNet-Version: 4.0.30319

  1四、X-Powered-By:表示网站是用什么技术开发的。
  例如: X-Powered-By: ASP.NET

  1五、Connection:keep-alive /close
  1六、Location:用于重定向一个新的位置,包含新的URL地址。表示客户应当到哪里去提取文档。Location一般不是直接设置的,而是经过HttpServletResponse的sendRedirect方法,该方法同时设置状态代码为302。Location响应报头域经常使用在更换域名的时候。

  1七、Refresh:表示浏览器应该在多少时间以后刷新文档,以秒计。除了刷新当前文档以外,你还能够经过setHeader("Refresh", "5; URL=http://host/path")让浏览器读取指定的页面。注意这种功能一般是经过设置HTML页面HEAD区的<META HTTP-EQUIV="Refresh" CONTENT="5;URL=http://host/path">实现,这是由于,自动刷新或重定向对于那些不能使用CGI或Servlet的HTML编写者十分重要。可是,对于Servlet来讲,直接设置Refresh头更加方便。注意Refresh的意义是“N秒以后刷新本页面或访问指定页面”,而不是“每隔N秒刷新本页面或访问指定页面”。所以,连续刷新要求每次都发送一个Refresh头,而发送204状态代码则能够阻止浏览器继续刷新,无论是使用Refresh头仍是<META HTTP-EQUIV="Refresh" ...>。注意Refresh头不属于HTTP 1.1正式规范的一部分,而是一个扩展,但Netscape和IE都支持它。

  6.四、响应主体

   就是服务器返回的资源的内容。即整个HTML文件

七、HTTP请求详细过程

  从前面讲解中咱们大概对HTTP有了一个基本的认识,那么接下来咱们就详细研究了解HTTP请求的具体过程。

  引用咸鱼老弟的博客文章

  7.一、 输入地址

  当咱们开始在浏览器中输入网址的时候,浏览器其实就已经在智能的匹配可能得 url 了,他会从历史记录,书签等地方,找到已经输入的字符串可能对应的 url,而后给出智能提示,让你能够补全url地址。对于 google的chrome 的浏览器,他甚至会直接从缓存中把网页展现出来,就是说,你尚未按下 enter,页面就出来了。

  7.二、浏览器查找域名的IP

  一、请求一旦发起,浏览器首先要作的事情就是解析这个域名,通常来讲,浏览器会首先查看本地硬盘的 hosts 文件,看看其中有没有和这个域名对应的规则,若是有的话就直接使用 hosts 文件里面的 ip 地址。

      二、若是在本地的 hosts 文件没有可以找到对应的 ip 地址,浏览器会发出一个 DNS请求到本地DNS服务器 。本地DNS服务器通常都是你的网络接入服务器商提供,好比中国电信,中国移动。

    三、查询你输入的网址的DNS请求到达本地DNS服务器以后,本地DNS服务器会首先查询它的缓存记录,若是缓存中有此条记录,就能够直接返回结果,此过程是递归的方式进行查询。若是没有,本地DNS服务器还要向DNS根服务器进行查询。

  四、根DNS服务器没有记录具体的域名和IP地址的对应关系,而是告诉本地DNS服务器,你能够到域服务器上去继续查询,并给出域服务器的地址。这种过程是迭代的过程。

  五、本地DNS服务器继续向域服务器发出请求,在这个例子中,请求的对象是.com域服务器。.com域服务器收到请求以后,也不会直接返回域名和IP地址的对应关系,而是告诉本地DNS服务器,你的域名的解析服务器的地址。

  六、最后,本地DNS服务器向域名的解析服务器发出请求,这时就能收到一个域名和IP地址对应关系,本地DNS服务器不只要把IP地址返回给用户电脑,还要把这个对应关系保存在缓存中,以备下次别的用户查询时,能够直接返回结果,加快网络访问。

下面这张图很完美的解释了这一过程:

知识扩展:

1)什么是DNS?

  DNS(Domain Name System,域名系统),因特网上做为域名和IP地址相互映射的一个分布式数据库,可以使用户更方便的访问互联网,而不用去记住可以被机器直接读取的IP数串。经过主机名,最终获得该主机名对应的IP地址的过程叫作域名解析(或主机名解析)。

  通俗的讲,咱们更习惯于记住一个网站的名字,好比www.baidu.com,而不是记住它的ip地址,好比:167.23.10.2。而计算机更擅长记住网站的ip地址,而不是像www.baidu.com等连接。由于,DNS就至关于一个电话本,好比你要找www.baidu.com这个域名,那我翻一翻个人电话本,我就知道,哦,它的电话(ip)是167.23.10.2。

2)DNS查询的两种方式:递归查询和迭代查询

一、递归解析

    当局部DNS服务器本身不能回答客户机的DNS查询时,它就须要向其余DNS服务器进行查询。此时有两种方式,如图所示的是递归方式。局部DNS服务器本身负责向其余DNS服务器进行查询,通常是先向该域名的根域服务器查询,再由根域名服务器一级级向下查询。最后获得的查询结果返回给局部DNS服务器,再由局部DNS服务器返回给客户端。

  简单来说,就是参与这次寻找IP的全部服务器,最后都可以获得该域名对应的IP信息(将信息进行往返传送!)

二、迭代解析

  当局部DNS服务器本身不能回答客户机的DNS查询时,也能够经过迭代查询的方式进行解析,如图所示。局部DNS服务器不是本身向其余DNS服务器进行查询,而是把能解析该域名的其余DNS服务器的IP地址返回给客户端DNS程序,客户端DNS程序再继续向这些DNS服务器进行查询,直到获得查询结果为止。也就是说,迭代解析只是帮你找到相关的服务器而已,而不会帮你去查。好比说:baidu.com的服务器ip地址在192.168.4.5这里,你本身去查吧,本人比较忙,只能帮你到这里了。

  简单的来说,就是只有最后一台服务器与最初的服务器进行该域名/IP信息的传送!

3)DNS域名称空间的组织方式

   咱们在前面有说到根DNS服务器,域DNS服务器,这些都是DNS域名称空间的组织方式。按其功能命名空间中用来描述 DNS 域名称的五个类别的介绍详见下表中,以及与每一个名称类型的示例

4)DNS负载均衡

  当一个网站有足够多的用户的时候,假如每次请求的资源都位于同一台机器上面,那么这台机器随时可能会蹦掉。处理办法就是用DNS负载均衡技术,它的原理是在DNS服务器中为同一个主机名配置多个IP地址,在应答DNS查询时,DNS服务器对每一个查询将以DNS文件中主机记录的IP地址按顺序返回不一样的解析结果,将客户端的访问引导到不一样的机器上去,使得不一样的客户端访问不一样的服务器,从而达到负载均衡的目的。例如能够根据每台机器的负载量,该机器离用户地理位置的距离等等。

  7.三、浏览器携带IP地址向Web服务器发起HTTP请求

  拿到域名对应的IP地址以后,浏览器会以一个随机端口(1024<端口<65535)向服务器的WEB程序(经常使用的有httpd,nginx等)80端口发起TCP的链接请求这个链接请求到达服务器端后(这中间经过各类路由设备,局域网内除外),进入到网卡,而后是进入到内核的TCP/IP协议栈(用于识别该链接请求,解封包,一层一层的剥开),还有可能要通过Netfilter防火墙(属于内核的模块)的过滤,最终到达WEB程序,最终创建了TCP/IP的链接。

TCP链接参考上面

  创建了TCP链接以后,发起一个http请求。一个典型的 http request header 通常须要包括请求的方法,例如 GET 或者 POST 等,不经常使用的还有 PUT 和 DELETE 、HEAD、OPTION以及 TRACE 方法,通常的浏览器只能发起 GET 或者 POST 请求。

  7.四、服务器的永久重定向响应 

  服务器给浏览器响应一个301永久重定向响应,这样浏览器就会访问“http://www.google.com/” 而非“http://google.com/”。

  为何服务器必定要重定向而不是直接发送用户想看的网页内容呢?其中一个缘由跟搜索引擎排名有关。若是一个页面有两个地址,就像http://www.yy.com/和http://yy.com/,搜索引擎会认为它们是两个网站,结果形成每一个搜索连接都减小从而下降排名。而搜索引擎知道301永久重定向是什么意思,这样就会把访问带www的和不带www的地址归到同一个网站排名下。还有就是用不一样的地址会形成缓存友好性变差,当一个页面有好几个名字时,它可能会在缓存里出现好几回。

扩展知识

1)301和302的区别。

  301和302状态码都表示重定向,就是说浏览器在拿到服务器返回的这个状态码后会自动跳转到一个新的URL地址,这个地址能够从响应的Location首部中获取(用户看到的效果就是他输入的地址A瞬间变成了另外一个地址B)——这是它们的共同点。

  他们的不一样在于。301表示旧地址A的资源已经被永久地移除了(这个资源不可访问了),搜索引擎在抓取新内容的同时也将旧的网址交换为重定向以后的网址

  302表示旧地址A的资源还在(仍然能够访问),这个重定向只是临时地从旧地址A跳转到地址B,搜索引擎会抓取新的内容而保存旧的网址。 SEO302好于301

2)重定向缘由:

(1)网站调整(如改变网页目录结构);
(2)网页被移到一个新地址;
(3)网页扩展名改变(如应用须要把.php改为.Html或.shtml)。
        这种状况下,若是不作重定向,则用户收藏夹或搜索引擎数据库中旧地址只能让访问客户获得一个404页面错误信息,访问流量白白丧失;再者某些注册了多个域名的网站,也须要经过重定向让访问这些域名的用户自动跳转到主站点等。

3)何时进行301或者302跳转呢?

        当一个网站或者网页24—48小时内临时移动到一个新的位置,这时候就要进行302跳转,而使用301跳转的场景就是以前的网站由于某种缘由须要移除掉,而后要到新的地址访问,是永久性的。
清晰明确而言:使用301跳转的大概场景以下:
一、域名到期不想续费(或者发现了更适合网站的域名),想换个域名。
二、在搜索引擎的搜索结果中出现了不带www的域名,而带www的域名却没有收录,这个时候能够用301重定向来告诉搜索引擎咱们目标的域名是哪个。
三、空间服务器不稳定,换空间的时候。

  7.五、发出新的请求(重定向)

  如今浏览器知道了 "http://www.google.com/"才是要访问的正确地址,因此它会发送另外一个http请求。重复上面的http请求步骤

  7.六、服务器主机处理

  通过前面的重重步骤,咱们终于将咱们的http请求发送到了服务器这里,其实前面的重定向已是到达服务器了,那么,服务器是如何处理咱们的请求的呢?

  后端从在固定的端口接收到TCP报文开始,它会对TCP链接进行处理,对HTTP协议进行解析,并按照报文格式进一步封装成HTTP Request对象,供上层使用。

  【一些大一点的网站会将你的请求到反向代理服务器中,由于当网站访问量很是大,网站愈来愈慢,一台服务器已经不够用了。因而将同一个应用部署在多台服务器上,将大量用户的请求分配给多台机器处理。此时,客户端不是直接经过HTTP协议访问某网站应用服务器,而是先请求到Nginx,Nginx再请求应用服务器,而后将结果返回给客户端,这里Nginx的做用是反向代理服务器。同时也带来了一个好处,其中一台服务器万一挂了,只要还有其余服务器正常运行,就不会影响用户使用。】

  7.七、Web应用服务器处理http请求

   【假设服务器端使用nginx+php(fastcgi)架构提供服务】

  假设我此时输入的URL为http://www.mecnblogs.com/

  ① nginx读取配置文件,并寻找文件

  当服务器主机将浏览器发送过来的全部数据经过各个网络层的相应协议的规定进行了解密以及封装,最后将数据包送达应用层使用。(可参考TCP/IP网络模型)

  当Nginx在收到浏览器 GET / 请求时,会读取http请求里面的头部信息,根据Host来匹配 本身的全部的虚拟主机的配置文件的server_name,看看有没有匹配的,有匹配那么就读取该虚拟主机的配置,发现以下配置: 

root /web/echo

 

   经过这个就知道全部网页文件的就在这个目录下 这个目录就是/ 当咱们http://www.mecnblogs.com/时就是访问这个目录下面的文件,例如访问http://www.mecnblogs.com/index.html,那么表明/web/echo下面有个文件叫index.html

index index.html index.htm index.php

 

  经过这个就能得知网站的首页文件是那个文件,也就是咱们在入http://www.mecnblogs.com/ ,nginx就会自动帮咱们把index.html(假设首页是index.php 固然是会尝试的去找到该文件,若是没有找到该文件就依次往下找,若是这3个文件都没有找到,那么就抛出一个404错误)加到后面,那么添加以后的URL是/index.php,而后根据后面的配置进行处理

复制代码
location ~ .*\.php(\/.*)*$ {
   root /web/echo;
   fastcgi_pass   127.0.0.1:9000;
   fastcgi_index  index.php;
   astcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
   include        fastcgi_params;
}
复制代码

  这一段配置指明凡是请求的URL中匹配(这里是启用了正则表达式进行匹配) *.php后缀的(后面跟的参数)都交给后端的fastcgi进程进行处理。

  ② 把php文件交给fastcgi进程去处理

   因而nginx把/index.php这个URL交给了后端的fastcgi进程处理,等待fastcgi处理完成后(结合数据库查询出数据,填充模板生成html文件)返回给nginx一个index.html文档,Nginx再把这个index.html返回给浏览器(经过HTTP协议返回,即HTTP响应【响应消息结构能够参考上面】),因而乎浏览器就拿到了首页的html代码,同时nginx写一条访问日志到日志文件中去。

【扩展:】

nginx是怎么找index.php文件的?

  当nginx发现须要/web/echo/index.php文件时,就会向内核发起IO系统调用(由于要跟硬件打交道,这里的硬件是指硬盘,一般须要靠内核来操做,而内核提供的这些功能是经过系统调用来实现的),告诉内核,我须要这个文件,内核从/开始找到web目录,再在web目录下找到echo目录,最后在echo目录下找到index.php文件,因而把这个index.php从硬盘上读取到内核自身的内存空间,而后再把这个文件复制到nginx进程所在的内存空间,因而乎nginx就获得了本身想要的文件了。

寻找文件在文件系统层面是怎么操做的?

  好比nginx须要获得/web/echo/index.php这个文件

  每一个分区(像ext3 ext3等文件系统,block块是文件存储的最小单元 默认是4096字节)都是包含元数据区和数据区,每个文件在元数据区都有元数据条目(通常是128字节大小),每个条目都有一个编号,咱们称之为inode(index node 索引节点),这个inode里面包含 文件类型、权限、链接次数、属主和数组的ID、时间戳、这个文件占据了那些磁盘块也就是块的编号(block,每一个文件能够占用多个block,而且block不必定是连续的,每一个block是有编号的),以下图所示:

  还有一个要点:目录其实也普通是文件,也须要占用磁盘块,目录不是一个容器。你看默认建立的目录就是4096字节,也就说只须要占用一个磁盘块,但这是不肯定的。因此要找到目录也是须要到元数据区里面找到对应的条目,只有找到对应的inode就可找到目录所占用的磁盘块。

那到底目录里面存放着什么,难道不是文件或者其余目录吗?

  其实目录存着这么一张表(姑且这么理解),里面放着 目录或者文件的名称和对应的inode号(暂时称之为映射表),以下图:

wKiom1LSX3KATYWYAAAx2GkMEO4103.jpg

假设

/           在数据区占据 一、2号block ,/其实也是一个目录 里面有3个目录  web 111

web         占据 5号block  是目录 里面有2个目录 echo data

echo        占据 11号 block  是目录  里面有1个文件 index.php

index.php   占据 15 16号 block  是文件

其在文件系统中分布以下图所示:

那么内核到底是怎么找到index.php这个文件的呢?

  内核拿到nginx的IO系统调用要获取/web/echo/index.php这个文件请求以后

  ① 内核读取元数据区 / 的inode,从inode里面读取/所对应的数据块的编号,而后在数据区找到其对应的块(1 2号块),读取1号块上的映射表找到web这个名称在元数据区对应的inode号

  ② 内核读取web对应的inode(3号),从中得知web在数据区对应的块是5号块,因而到数据区找到5号块,从中读取映射表,知道echo对应的inode是5号,因而到元数据区找到5号inode

  ③ 内核读取5号inode,获得echo在数据区对应的是11号块,因而到数据区读取11号块获得映射表,获得index.php对应的inode是9号

  ④ 内核到元数据区读取9号inode,获得index.php对应的是15和16号数据块,因而就到数据区域找到15 16号块,读取其中的内容,获得index.php的完整内容

  7.八、浏览器处理并显示html文件

  在浏览器没有完整接受所有HTML文档时,它就已经开始显示这个页面了,浏览器是如何把页面呈如今屏幕上的呢?不一样浏览器可能解析的过程不太同样,这里咱们只介绍webkit的渲染过程,下图对应的就是WebKit渲染的过程,这个过程包括:

  解析html以构建dom树 -> 构建render树 -> 布局render树 -> 绘制render树

  在浏览器显示的时候,当遇到要获取外图片,CSS,JS文件等等时,浏览器将会发起不断发起异步的http请求来获取这些资源。

八、总结

  站在巨人的肩膀上来学习确实可以让本身的眼界更加开阔,同时深刻学习与巩固HTTP这方面的知识,可以让本身深刻了解Web的B/S结构、Web通信的具体过程,有助于本身往后的Web开发。同时也为接下来的面试作准备。在此固然是要感谢各位前辈大牛啦。

九、参考文献

1. 《图解TCP-IP协议》 

2. 《一次完整的HTTP事务是怎样一个过程?

3. 《【原】老生常谈-从输入url到页面展现到底发生了什么

4. 《浅析HTTP协议

5. 《HTTP协议详解

 

(以上是本身的一些看法,如有不足或者错误的地方请各位指出)

 做者:那一叶随风   http://www.cnblogs.com/phpstudy2015-6/

 原文地址:http://www.cnblogs.com/phpstudy2015-6/p/6810130.html 

 声明:只表明本人在工做学习中某一时间内总结的观点或结论。转载时请在文章页面明显位置给出原文连接

相关文章
相关标签/搜索