Http简析
HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)
的缩写,是用于从万维网(WWW:World Wide Web )服务器传输超文本到本地浏览器的传送协议。
HTTP 工作原理
HTTP协议工作于客户端-服务端架构上。浏览器作为HTTP客户端通过URL向HTTP服务端即WEB服务器发送所有请求。
Web服务器有:Apache服务器,IIS服务器(Internet Information Services)等。
Web服务器根据接收到的请求后,向客户端发送响应信息。
HTTP默认端口号为80,但是你也可以改为8080或者其他端口。
HTTP协议与TCP/IP协议的关系
HTTP的长连接和短连接本质上是TCP长连接和短连接。
HTTP属于应用层协议,在传输层使用TCP协议,在网络层使用IP协议。 IP协议主要解决网络路由和寻址问题,TCP协议主要解决如何在IP层之上可靠地传递数据包,使得网络上接收端收到发送端所发出的所有包,并且顺序与发送顺序一致。TCP协议是可靠的、面向连接的。
HTTP三点注意事项:
- HTTP是
无连接
:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。 - HTTP是
媒体独立
的:这意味着,只要客户端和服务器知道如何处理的数据内容,任何类型的数据都可以通过HTTP发送。客户端以及服务器指定使用适合的MIME-type内容类型。 - HTTP是
无状态
:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。
CGI(Common Gateway Interface)
是 HTTP 服务器与自己或其它机器上的程序进行“交谈”的一种工具,其程序须运行在网络服务器上。
绝大多数的 CGI 程序被用来解释处理来自表单的输入信息,并在服务器产生相应的处理,或将相应的信息反馈给浏览器。CGI 程序使网页具有交互功能。
浏览器显示的内容都有 HTML、XML、GIF、Flash 等,浏览器是通过 MIME Type 区分它们,决定用什么内容什么形式来显示。
注释:MIME Type
是该资源的媒体类型,MIME Type 不是个人指定的,是经过互联网(IETF)
组织协商,以 RFC
(是一系列以编号排定的文件,几乎所有的互联网标准都有收录在其中) 的形式作为建议的标准发布在网上的,大多数的 Web 服务器和用户代理都会支持这个规范 (顺便说一句,Email 附件的类型也是通过 MIME Type 指定的)。
媒体类型通常通过 HTTP 协议,由 Web 服务器告知浏览器的,更准确地说,是通过 Content-Type
来表示的。例如:Content-Type:text/HTML。
通常只有一些卓哉互联网上获得广泛应用的格式才会获得一个 MIME Type
,如果是某个客户端自己定义的格式,一般只能以 application/x-
开头。
HTTP 消息结构
HTTP是基于客户端/服务端(C/S)的架构模型,通过一个可靠的链接来交换信息,是一个无状态的请求/响应协议。
一个HTTP"客户端"是一个应用程序(Web浏览器或其他任何客户端),通过连接到服务器达到向服务器发送一个或多个HTTP的请求的目的。
一个HTTP"服务器"同样也是一个应用程序(通常是一个Web服务,如Apache Web服务器或IIS服务器等),通过接收客户端的请求并向客户端发送HTTP响应数据。
HTTP使用统一资源标识符(Uniform Resource Identifiers, URI)来传输数据和建立连接。
一旦建立连接后,数据消息就通过类似Internet邮件所使用的格式[RFC5322]和多用途Internet邮件扩展(MIME)
[RFC2045]来传送。
客户端请求消息
客户端发送一个HTTP请求到服务器的请求消息包括以下格式:请求行
(request line)、请求头部
(header)、空行
和请求数据
四个部分组成。
请求报文的一般格式
服务器响应消息
HTTP响应也由四个部分组成,分别是:状态行
、消息报头
、空行
和响应正文
。
HTTP 请求方法
HTTP1.0 定义了三种请求方法: GET
, POST
和 HEAD
方法。
HTTP1.1 新增了六种请求方法:OPTIONS
、PUT
、PATCH
、DELETE
、TRACE
和 CONNECT
方法。
OPTIONS
:允许客户端查看服务器的性能。HEAD
:类似于 GET 请求,只不过返回的响应中没有具体的内容,用于获取报头。GET
:请求指定的页面信息,并返回实体主体。POST
:向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST 请求可能会导致新的资源的建立和/或已有资源的修改。PUT
: 从客户端向服务器传送的数据取代指定的文档的内容。DELETE
:请求服务器删除指定的页面。TRACE
:回显服务器收到的请求,主要用于测试或诊断。CONNECT
:HTTP/1.1 协议中预留给能够将连接改为管道方式的代理服务器。PATCH
:是对 PUT 方法的补充,用来对已知资源进行局部更新 。
HTTP 响应头信息
应答头 | 说明 |
---|---|
Allow | 服务器支持哪些请求方法(如GET、POST等)。 |
Content-Encoding | 文档的编码(Encode)方法。只有在解码之后才可以得到Content-Type头指定的内容类型。利用gzip压缩文档能够显著地减少HTML文档的下载时间。Java的GZIPOutputStream可以很方便地进行gzip压缩,但只有Unix上的Netscape和Windows上的IE 4、IE 5才支持它。因此,Servlet应该通过查看Accept-Encoding头(即request.getHeader(“Accept-Encoding”))检查浏览器是否支持gzip,为支持gzip的浏览器返回经gzip压缩的HTML页面,为其他浏览器返回普通页面。 |
Content-Length | 表示内容长度。只有当浏览器使用持久HTTP连接时才需要这个数据。如果想要利用持久连接的优势,可以把输出文档写入 ByteArrayOutputStream,完成后查看其大小,然后把该值放入Content-Length头,最后通过byteArrayStream.writeTo(response.getOutputStream()发送内容。 |
Content-Type | 表示后面的文档属于什么MIME类型。Servlet默认为text/plain,但通常需要显式地指定为text/html。由于经常要设置Content-Type,因此HttpServletResponse提供了一个专用的方法setContentType。 |
Expires | 应该在什么时候认为文档已经过期,从而不再缓存它 |
Last-Modified | 文档的最后改动时间。客户可以通过If-Modified-Since请求头提供一个日期,该请求将被视为一个条件GET,只有改动时间迟于指定时间的文档才会返回,否则返回一个304(Not Modified)状态。Last-Modified也可用setDateHeader方法来设置。 |
Location | 表示客户应当到哪里去提取文档。Location通常不是直接设置的,而是通过HttpServletResponse的sendRedirect方法,该方法同时设置状态代码为302。 |
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都支持它。 |
Server | 服务器名字。Servlet一般不设置这个值,而是由Web服务器自己设置。 |
Set-Cookie | 设置和页面关联的Cookie。Servlet不应使用response.setHeader(“Set-Cookie”, …),而是应使用HttpServletResponse提供的专用方法addCookie。参见下文有关Cookie设置的讨论。 |
WWW-Authenticate | 客户应该在Authorization头中提供什么类型的授权信息?在包含401(Unauthorized)状态行的应答中这个头是必需的。例如,response.setHeader(“WWW-Authenticate”, “BASIC realm=\“executives\””)。注意Servlet一般不进行这方面的处理,而是让Web服务器的专门机制来控制受密码保护页面的访问(例如.htaccess)。 |
Date | 当前的GMT时间。你可以用setDateHeader来设置这个头以避免转换时间格式的麻烦。 |
HTTP Content-Type
HTTP头部字段Content-Type约定请求和响应的HTTP body内容编码类型,客户端和服务端根据HTTP头部字段Content-Type正确解码HTTP body内容。
语法格式:
Content-Type: text/html; charset=utf-8 Content-Type:
multipart/form-data; boundary=something
常见的HTTP头部Content-Type:
- application/x-www-form-urlencoded
- multipart/form-data
- application/json
- application/xml
常见的媒体格式类型如下:
- text/html : HTML格式
- text/plain :纯文本格式
- text/xml : XML格式
- image/gif :gif图片格式
- image/jpeg :jpg图片格式
- image/png:png图片格式
以application开头的媒体格式类型:
- application/xhtml+xml :XHTML格式
- application/xml: XML数据格式
- application/atom+xml :Atom XML聚合格式
- application/json: JSON数据格式
- application/pdf:pdf格式
- application/msword : Word文档格式
- application/octet-stream : 二进制流数据(如常见的文件下载)
- application/x-www-form-urlencoded : 中默认的encType,form表单数据被编码为key/value格式发送到服务器(表单默认的提交数据的格式)
另外一种常见的媒体格式是上传文件之时使用的:
- multipart/form-data : 需要在表单中进行文件上传时,就需要使用该格式
HTTP请求报文与响应报文常见的首部:
- 通用首部字段(请求报文与响应报文都会使用的首部字段)
Date:创建报文时间
Connection:连接的管理
Cache-Control:缓存的控制
Transfer-Encoding:报文主体的传输编码方式 - 请求首部字段(请求报文会使用的首部字段)
Host:请求资源所在服务器
Accept:可处理的媒体类型
Accept-Charset:可接收的字符集
Accept-Encoding:可接受的内容编码
Accept-Language:可接受的自然语言 - 响应首部字段(响应报文会使用的首部字段)
Accept-Ranges:可接受的字节范围
Location:令客户端重新定向到的URI
Server:HTTP服务器的安装信息 - 实体首部字段(请求报文与响应报文的的实体部分使用的首部字段)
Allow:资源可支持的HTTP方法
Content-Type:实体主类的类型
Content-Encoding:实体主体适用的编码方式
Content-Language:实体主体的自然语言
Content-Length:实体主体的的字节数
Content-Range:实体主体的位置范围,一般用于发出部分请求时使用
HTTP之chunk编码(分块传输编码)
当客户端向服务器请求一个静态页面或者一张图片时,服务器可以很清楚的知道内容大小,然后通过Content-Length消息首部字段告诉客户端需要接收多少数据。
但是如果是动态页面等时,服务器是不可能预先知道内容大小,这时就可以使用Transfer-Encoding:chunk模式来传输数据了。即如果要一边产生数据,一边发给客户端,服务器就需要使用"Transfer-Encoding: chunked"这样的方式来代替Content-Length。
在进行chunked
编码传输时,在回复消息的头部有Transfer-Encoding: chunked
。编码使用若干个chunk组成,由一个标明长度为0的chunk结束。每个chunk有两部分组成,第一部分是该chunk的长度,第二部分就是指定长度的内容,每个部分用CRLF隔开。在最后一个长度为0的chunk中的内容是称为footer的内容,是一些没有写的头部内容。
chunk编码格式如下:
[chunk size][\r\n][chunk data][\r\n][chunk size][\r\n][chunk data][\r\n][chunk size = 0][\r\n][\r\n]
分块传输编码
分块传输编码是超文本传输协议(HTTP)中的一种数据传输机制,允许HTTP由网页服务器发送给客户端应用( 通常是网页浏览器)的数据可以分成多个部分。分块传输编码只在HTTP协议1.1版本(HTTP/1.1)中提供。
HTTP应答消息中发送的数据是整个发送的,Content-Length消息头字段表示数据的长度。数据的长度很重要,因为客户端需要知道哪里是应答消息的结束,以及后续应答消息的开始。然而,使用分块传输编码,数据分解成一系列数据块,并以一个或多个块发送,这样服务器可以发送数据而不需要预先知道发送内容的总大小。通常数据块的大小是一致的,但也不总是这种情况。
HTTP 1.1引入分块传输编码提供了以下几点好处:
-
HTTP分块传输编码允许服务器为动态生成的内容维持HTTP持久链接。
通常,持久链接需要服务器在开始发送消息体前发送Content-Length消息头字段,但是对于动态生成的内容来说,在内容创建完之前是不可知的。 -
分块传输编码允许服务器在最后发送消息头字段。
对于那些头字段值在内容被生成之前无法知道的情形非常重要,例如消息的内容要使用散列进行签名,散列的结果通过HTTP消息头字段进行传输。没有分块传输编码时,服务器必须缓冲内容直到完成后计算头字段的值并在发送内容前发送这些头字段的值。 -
HTTP服务器有时使用压缩 (gzip或deflate)以缩短传输花费的时间。
分块传输编码可以用来分隔压缩对象的多个部分。在这种情况下,块不是分别压缩的,而是整个负载进行压缩,压缩的输出使用本文描述的方案进行分块传输。在压缩的情形中,分块编码有利于一边进行压缩一边发送数据,而不是先完成压缩过程以得知压缩后数据的大小。
格式
如果一个HTTP消息(请求消息或应答消息)的Transfer-Encoding消息头的值为chunked,那么,消息体由数量未定的块组成,并以最后一个大小为0的块为结束。
每一个非空的块都以该块包含数据的字节数(字节数以十六进制表示)开始,跟随一个CRLF (回车及换行),然后是数据本身,最后块CRLF结束。
在一些实现中,块大小和CRLF之间填充有白空格(0x20)。最后一块是单行,由块大小(0),一些可选的填充白空格,以及CRLF。最后一块不再包含任何数据,但是可以发送可选的尾部,包括消息头字段。消息最后以CRLF结尾。
编码的应答
HTTP/1.1 200 OK
Content-Type: text/plain
Transfer-Encoding: chunked
25
This is the data in the first chunk
1C
and this is the second one
5
conse
6
quence
0
编码应答的解释[编辑]
前两个块的数据中包含有显式的\r\n字符。
"This is the data in the first chunk\r\n" (37 字符 => 十六进制: 0x25)
"and this is the second one\r\n" (28 字符 => 十六进制: 0x1C)
"conse" ( 3 字符 => 十六进制: 0x05)
"quence" ( 8 字符 => 十六进制: 0x06)
应答需要以0长度的块( “0\r\n\r\n”.)结束。
解码的数据[编辑]
This is the data in the first chunk
and this is the second one
consequence
解决Http协议无状态协议
无状态协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息也就是说,当客户端一次HTTP请求完成以后,客户端再发送一次HTTP请求,HTTP并不知道当前客户端是一个”老用户“。
可以使用Cookie来解决无状态的问题,Cookie就相当于一个通行证,第一次访问的时候给客户端发送一个Cookie,当客户端再次来的时候,拿着Cookie(通行证),那么服务器就知道这个是”老用户“。
URI和URL的区别
URI,是uniform resource identifier
,统一资源标识符
,用来唯一的标识一个资源。
Web上可用的每种资源如HTML文档、图像、视频片段、程序等都是一个来URI来定位的
URI一般由三部组成:
- 访问资源的命名机制
- 存放资源的主机名
- 资源自身的名称,由路径表示,着重强调于资源。
URL是uniform resource locator
,统一资源定位器
,它是一种具体的URI,即URL可以用来标识一个资源,而且还指明了如何locate这个资源。
URL是Internet上用来描述信息资源的字符串,主要用在各种WWW客户程序和服务器程序上,特别是著名的Mosaic。
采用URL可以用一种统一的格式来描述各种信息资源,包括文件、服务器的地址和目录等。
URL一般由三部组成:
- 协议(或称为服务方式)
- 存有该资源的主机IP地址(有时也包括端口号)
- 主机资源的具体地址。如目录和文件名等
URN,uniform resource name,统一资源命名,是通过名字来标识资源
URI是以一种抽象的,高层次概念定义统一资源标识,而URL和URN则是具体的资源标识的方式。URL和URN都是一种URI。笼统地说,每个 URL 都是 URI,但不一定每个 URI 都是 URL。这是因为 URI 还包括一个子类,即统一资源名称 (URN),它命名资源但不指定如何定位资源。上面的 mailto、news 和 isbn URI 都是 URN 的示例。
HTTP请求所经历的7个步骤
HTTP通信机制是在一次完整的HTTP通信过程中,Web浏览器与Web服务器之间将完成下列7个步骤:
-
建立TCP连接
在HTTP工作开始之前,Web浏览器首先要通过网络与Web服务器建立连接,该连接是通过TCP来完成的,该协议与IP协议共同构建 Internet,即TCP/IP协议。HTTP是比TCP更高层次的应用层协议,根据规则, 只有低层协议建立之后才能,才能进行更层协议的连接,因此,首先要建立TCP连接,一般TCP连接的端口号是80。 -
Web浏览器向Web服务器发送请求行
一旦建立了TCP连接,Web浏览器就会向Web服务器发送请求命令。例如:GET /sample/hello.jsp HTTP/1.1。 -
Web浏览器发送请求头
浏览器发送其请求命令之后,还要以头信息的形式向Web服务器发送一些别的信息,之后浏览器发送了一空白行来通知服务器,它已经结束了该头信息的发送。 -
Web服务器应答
客户机向服务器发出请求后,服务器会客户机回送应答, HTTP/1.1 200 OK ,应答的第一部分是协议的版本号和应答状态码。 -
Web服务器发送应答头
正如客户端会随同请求发送关于自身的信息一样,服务器也会随同应答向用户发送关于它自己的数据及被请求的文档。 -
Web服务器向浏览器发送数据
Web服务器向浏览器发送头信息后,它会发送一个空白行来表示头信息的发送到此为结束,接着,它就以Content-Type应答头信息所描述的格式发送用户所请求的实际数据。 -
Web服务器关闭TCP连接
一般情况下,一旦Web服务器向浏览器发送了请求数据,它就要关闭TCP连接,然后如果浏览器或者服务器在其头信息加入了这行代码:Connection:keep-alive
TCP连接在发送后将仍然保持打开状态,于是,浏览器可以继续通过相同的连接发送请求。保持连接节省了为每个请求建立新连接所需的时间,还节约了网络带宽。
建立TCP连接->发送请求行->发送请求头->(到达服务器)发送状态行->发送响应头->发送响应数据->断TCP连接
HTTP优化方案
- TCP复用:TCP连接复用是将多个客户端的HTTP请求复用到一个服务器端TCP连接上,而HTTP复用则是一个客户端的多个HTTP请求通过一个TCP连接进行处理。前者是负载均衡设备的独特功能;而后者是HTTP 1.1协议所支持的新功能,目前被大多数浏览器所支持。
- 内容缓存:将经常用到的内容进行缓存起来,那么客户端就可以直接在内存中获取相应的数据了。
- 压缩:将文本数据进行压缩,减少带宽
- SSL加速(SSL Acceleration):使用SSL协议对HTTP协议进行加密,在通道内加密并加速
- TCP缓冲:通过采用TCP缓冲技术,可以提高服务器端响应时间和处理效率,减少由于通信链路问题给服务器造成的连接负担。
Http协议流程
- 域名解析
- 三次握手过程
- 建立连接后,客户端发起Http请求
- .服务器响应Http请求,客户端得到HTML代码
- 浏览器解析HTML代码
- .浏览器对页面进行渲染呈现给用户
浏览器输入一个地址到页面展示中间经历了什么?
-
输入url,先解析url地址是否合法
-
浏览器检查是否有缓存(浏览器缓存-系统缓存-路由器缓存)。如果有,直接显示。如果没有,跳到第三步。
-
在发送http请求前,需要域名解析(DNS解析),解析获取对应过的ip地址。
-
浏览器向服务器发起tcp链接,与浏览器建立tcp三次握手
-
握手成功后,游览器向服务器发送http请求,请求数据包
-
服务器收到处理的请求,将数据返回至浏览器
-
浏览器收到http响应。
-
浏览器解析响应。如果响应可以缓存,则存入缓存
-
浏览器发送请求获取嵌入在HTML中的资源(html,css,JavaScript,图片,音乐等),对于未知类型,会弹出对话框
-
浏览器发送异步请求
-
页面全部渲染结束。
GET和POST的区别:
-
传送方式:get通过地址栏传输,post通过报文传输。
-
传送长度:get参数有长度限制(受限于url长度),而post无限制
-
GET产生一个TCP数据包;POST产生两个TCP数据包。
-
对于GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200(返回数据);而对于POST请求。浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)
-
get是从服务器上获取数据,post是向服务器传送数据。
-
get是把参数数据队列加到提交表单的ACTION属性所指的URL中,值和表单内各个字段一一对应,在URL中可以看到。post是通过HTTP的post机制,将表单内各个字段与其内容放置在HTML header内一起传送到ACTION属性所指的URL地址。用户看不到这个过程。
-
对于get方式,服务器端用Request.QueryString获取变量的值,对于post方式,服务器端用Request.Form获取提交的数据。
-
get传送的数据量较小,因为受URL限制,不能大于2KB,但是效率高。
-
post传送的数据量较大,一般被默认为不受限制,所以上传文件时只能用post。但理论上,IIS4中最大量为80KB,IIS5中为100KB。
-
get安全性非常低,因为URL是可见的,可能会泄露私密信息,如密码等,post安全性较高。但是执行效率却比Post方法好。
-
get方式只能支持ASCII字符,向服务器传的中文字符可能会乱码。
-
post支持标准字符集,可以正确传递中文字符。
-
get请求可以被缓存,可以被收藏为书签,但 post 不行。
-
get请求会保留在浏览器的历史记录中,post 不会。
cookies机制和session机制的区别:
-
cookies数据保存在客户端。session数据保存在服务端
-
cookies可以减轻服务器压力,但是不安全,容易进行cookies欺骗
-
session安全一点,但是占用服务器资源。
HTTP长连接
长连接定义:
client方与server方先建立连接,连接建立后不断开,然后再进行报文发送和接收。这种方式下由于通讯连接一直存在。此种方式常用于P2P点对点的通信。
长连接的操作步骤是:建立连接——数据传输...(保持连接)...数据传输——关闭连接
长连接适用场景:
- 监控系统:后台硬件热插拔、LED、温度、电压发生变化;
- 即时通信系统:其它用户登录、发送信息;
- 即时报价系统:后台数据库内容发生变化;
- 像以上这些连接,如果每次操作都要建立连接然后再操作的话处理速度会降低。所以操- 作时第一次连接上以后,以后每次直接发送数据就可以了,不用再建立TCP连接。
- 再比如:数据库的连接用长连接,如果用短连接频繁的通信会造成socket错误,频繁的socket创建也是对资源的浪费。
HTTP短连接
短连接定义:
Client方与server每进行一次报文收发交易时才进行通讯连接,交易完毕后立即断开连接。此方式常用于一点对多点通讯。
短连接的操作步骤是:建立连接——数据传输——关闭连接...建立连接——数据传输——关闭连接
短连接的适用场景:
短连接多用于操作频繁,点对点的通讯,而且连接数不能太多的情况。每个TCP连接的建立都需要三次握手,每个TCP连接的断开要四次挥手。
- web网站的http服务一般都用短连接。因为长连接对于服务器来说要耗费一定的资源。像web网站这么频繁的成千上万甚至上亿客户端的连接用短连接更省一些资源。
试想如果都用长连接,而且同时用成千上万的用户,每个用户都占有一个连接的话,可想而知服务器的压力有多大。所以并发量大,但是每个用户又不需频繁操作的情况下需要短连接。