【摘要】:本文整理并简要分析了HTTP协议的交互过程和内容格式,包括HTTP请求、HTTP应答的头域和实体内容,HTTP 1.0与HTTP 1.1的差异,并举例说明了Chunked编码的工作过程原理。

1、HTTP协议简介

浏览器和Web服务器之间一问一答的交互过程遵守一定的规则,这个规则就是HTTP协议。HTTP协议时TCP/IP协议集中的一个应用层协议,定义了浏览器和Web服务器之间交换数据过程和数据本身的格式。现在广泛应用的有HTTP/1.0和HTTP/1.1两个版本,1.1和1.0相比最大的特点就是增加对长连接的支持。

2、协议流程

2.1 HTTP/1.0的通信过程

HTTP/1.0只支持短连接,每次连接只处理一个请求,即使对同一站点的每一个页面的访问,浏览器和服务器之间都要建立一次单独的链接。通信过程如图1所示:

2.2 HTTP /1.1的通信过程

HTTP/1.1支持长连接,在一个TCP连接上可以传送多个HTTP请求和应答,减少建立和关闭连接的消耗和延迟。例如一个包含多张图片资源的网页文件的多个请求和响应可以在同一个连接中传输,并且还允许浏览器客户端不用等待上一次请求的结果返回就可以发送下一个请求,也就是支持pipeline管线化。HTTP 1.1的通信过程如图2所示:

3HTTP请求

完整的HTTP请求包括:一个请求行、若干HTTP头域和可选的实体内容三部分:

3.1 请求行

请求行以一个方法符号开头,以空格分开,后面跟着请求的URI和协议版本,格式如下:

Method  Request-URI  HTTP-Version CRLF

其中的Method表示请求方法,Request-URI是同一资源标识符,HTTP-Version表示请求的HTTP协议版本,CRLF表示回车换行。

请求方法有8种,方法名全为大写:

(1)GET    请求获取Request-URI指定的资源

(2)HEAD 请求获取Request-URI制定资源的响应消息报头

(3)POST  用于向服务器提交数据,正常情况下带有“消息体”

(4)PUT    请求服务器存储一个资源,并用Request-URI作为其标识

(5)DELETE      请求服务器删除Request-URI所标识的资源

(6)TRACE   请求服务器回送收到的请求信息,主要用于测试或诊断

(7)CONNECT保留将来使用

(8)OPTIONS请求查询服务器的性能,或者查询与资源相关的选项和需求

3.2   HTTP头域

HTTP头域分为四种:通用头域、请求头域、响应头域和实体头域。每个头域由一个域名、冒号和域值三部分组成,域名大小写无关,域值前可以添加任何数量的空格符。

3.2.1  通用头域

通用头域是指请求和响应都支持的HTTP头域,最常见的有Cache-Control、Connection和Transfer-Encoding,具体含义如下:

(1)    Cache-Control:指定请求和相应遵循的缓存机制,最常见的值是no-cache,指示请求和响应消息不能缓存;

(2)    Connection:用于指定处理完本次请求/响应后,客户端和服务器是否还要继续保持连接。

(3)    Transfer-Encoding:用于指定实体内容的传输编码方式。

3.2.2  请求头域

请求头域是只有在请求头中带有的,用于向服务器传递关于请求或者关于客户端的附件信息。常见的有:Accept、Accept-Encoding、Accept-Language、Accept-Charset、Host、Referer、User-Agent和Cookie,具体含义如下:

(1)    Accept:用于指定客户端程序能够处理的MIME类型,多个时用逗号隔开;

(2)    Accept-Encoding:指定客户端程序支持的压缩方式;

(3)    Accept-Language:指定客户端期望返回哪个国家语言的文档;

(4)    Accept-Charset:指定客户端程序可以使用的字符集;

(5)    Host:指定资源所在的主机名和端口号;

(6)    Referer:指定请求uri的源资源地址,也就是用户从哪个uri过来,允许服务器生成回退链表;

(7)    User-Agent:浏览器客户端信息,如使用哪种浏览器等;

(8)    Cookie:服务器在浏览器端留下的信息,这是最重要的请求头字段之一,例如访问百度的时候通常会带有类似如下的Cookie:

BAIDUID=27C48D40C9CDCF48CEAAFCFD9C47FC52:FG=1;BD_UTK_DVT=1

3.2.3  响应头域

响应头域只在HTTP响应中出现,在第4章节详细讲解。

3.2.4  实体头域

HTTP请求和响应中都可以包含实体头域,实体头域包含实体内容的一些信息。常见的实体头域有:Content-Encoding、Content-Length、Content-Type和Expires,具体含义如下:

(1)    Content-Encoding:指明实体内容采用的压缩方式;

(2)    Content-Length:指明实体内容的长度,单位为字节;

(3)    Content-Type:指定实体内容的MIME类型;

(4)    Expires:指明实体内容在什么时间之后过期,不再缓存。

3.2   可选实体内容

HTTP请求是否带有实体内容主要看请求行中的请求方法,我们只分析GET和POST两种主要的类型,GET方法用于获取服务器上的特定资源,一般没有实体内容。POST方法用于向服务器提交数据,一般带有实体内容。下面是一个请求方法为POST的HTTP请求的完整数据(其中绿色标注的部分是实体内容):

POST /deal_post.phpHTTP/1.1

Referer: http://db-testing-ps1101.db01.baidu.com:8080/post.php

Accept-Language: zh-cn

Content-Type:application/x-www-form-urlencoded

User-Agent: Mozilla/4.0

Host:db-testing-ps1101.db01.baidu.com:8080

Content-Length: 43

Connection: Keep-Alive

Cache-Control: no-cache

Cookie:BAIDUID=27C48D40C9CDCF48CEAAFCFD9C47FC52:FG=1;

data1=a&data2=b&data3=c&Submit=%CC%E1%BD%BB

4HTTP应答

HTTP应答包括:一个状态行、若干消息头和实体内容三部分组成。

4.1 状态行

状态行以HTTP协议版本开头,后面跟着状态码和简单的状态描述,格式如下:

HTTP-Version  Status-Code  Reason-Phrase  CRLF

其中的Status-Code是一个三个数字组成的返回状态码,Reason-Phrase提供一个简单的状态描述,如对于200成功页面就是“OK”,对于404页面未找到错误就是“Not Found”。

HTTP应答的状态行根据状态码可以分为五种类型:

(1)1xx:信息,请求收到,继续处理;

(2)2xx:成功,行为被成功地接受、理解和采纳;

(3)3xx:重定向,为了完成请求,必须进一步执行的动作;

(4)4xx:客户端错误,请求包含语法错误或者请求无法实现;

(5)5xx:服务端错误,服务器不能正确执行一个正确的请求。

下表中是检索前段Web服务器测试中常见的几种返回状态码:

4.2 HTTP头域

前面我们介绍过HTTP头域可以分为四种,HTTP应答包含通用头域、响应头域和实体头域,通用头域和实体头域前面已经介绍过,本节主要介绍响应头域。

响应头域允许服务器传递不能放在状态行中的附件信息,主要用于描述服务器的信息和Request URI的进一步信息,检索前段Web服务器测试中最常见的响应头域有Server、Location、Set-Cookie和P3P,具体含义如下:

(1)       Server:说明响应服务器的名称,如BWS/1.0或者Apache/1.3.27;

(2)       Location:在302跳转页面应答的时候,带有Location指明跳转的目的地址;

(3)       Set-Cookie:服务器对浏览器端设置Cookie,例如不带Cookie访问BWS的时候,BWS会返回类似如下的Set-Cookie内容:

BAIDUID=B589E67D8A2C6B15C2FDD8F20C3DC0D5:FG=1;expires=Wed, 26-Aug-39 01:47:59 GMT; path=/; domain=.baidu.com

(4)       P3P:设置允许Cookie的跨域访问,BWS模块在设置Cookie的时候通常会带有该头域

P3P: CP=" OTI DSP COR IVA OUR IND COM"

4.3 实体内容

HTTP响应的实体内容按照传输编码方式(编码的目的是让浏览器和服务器之间能正确收发数据)区分主要分为三种:

(1)       由Content-Length明确标明实体内容,这是最常见的一种类型;

(2)       没有Content-Length头域,由Transfer-Encoding指明采用Chunked编码;

(3)       既没有Content-Length也没有Transfer-Encoding标明采用Chunked编码;

4.3.1  Content-Length类型

这是最常见的一种类型,由Content-Length头域标明后续的实体内容的字节长度,浏览器或者服务器根据解析出来的Content-Length去读取后续的实体内容。下面是一个该类型的HTTP响应(绿色部分是实体内容,长度为20个字节):

HTTP/1.1 200 OK

Date: Wed, 26 Aug 2009 02:45:57 GMT

Server: Apache/2.0.63 (Unix) PHP/5.2.6

Content-Length: 20

Content-Type: text/html

Content-Language: en

<html>content</html>

4.3.2  Chunked类型

Chunked编码类型也是较常见的,当服务器不能预先确定HTTP报文体的长度时,无法在应答头域Content-Length域来指明报文体长度,此时需要采用chunked编码,通过Transfer-Encodeing头域说明采用chuncked编码。检索前段模块中Apache-snap很多地方就采用了Chunked编码,而BWS不支持Chunked编码。

chunked编码的基本方法是将大块数据分解成多块小数据,每块都可以自指定长度,其具体格式如下:

Chunked-Body  = *chunk        //0至多个chunk

last-chunk     //最后一个chunk

trailer             //尾部

CRL               //结束标记符

chunk            = chunk-size [ chunk-extension ]CRLF

chunk-data CRLF

chunk-size    = 1*HEX

last-chunk    = 1*("0") [ chunk-extension ] CRLF

chunk-extension=*( ";" chunk-ext-name [ "=" chunk-ext-val ] )

chunk-ext-name= token

chunk-ext-val = token | quoted-string

chunk-data    = chunk-size(OCTET)

trailer       = *(entity-header CRLF)

Chunked-Body表示经过chunked编码后的报文体。报文体可以分为chunk, last-chunk,trailer和结束符四部分。chunk的数量在报文体中最少可以为0,无上限;每个chunk的长度是自指定的,即起始的数据必然是16进制数字的字符串,代表后面chunk-data的长度(字节数)。这个16进制的字符串第一个字符如果是“0”,则表示chunk-size为0,该chunk为last-chunk,无chunk-data部分。可选的chunk-extension由通信双方自行确定,如果接收者不理解它的意义,可以忽略。

trailer是附加的在尾部的额外头域,通常包含一些元数据(metadata, meta means"about information"),这些头域可以在解码后附加在现有头域之后。

下面我们以一个实例来分析一下chunked编码页面,首先在apache(本机端口9000)的发布目录htdocs下准备一个文件test.php,内容如下:

<html>

<head>

<title>Hi</title>

<linkrel="stylesheet" href="style.css" type="text/css"

media="all"/>

</head>

<?phpflush(); sleep(5); ?>

<bodyοnlοad="loaded();">

<h1>Hi</h1>

</body>

</html>

在测试机上通过echo –ne  “GET /test.phpHTTP/1.1\r\nHost: www.baidu.com\r\n\r\n” | nc 127.0.0.1 9000访问该页得到的结果如下:

查看应答的二进制内容如下:

由应答报文可以看出,在头域结束符“\r\n\r\n”之后是ASCII码74,表示第一个chunk的chunk-size,转换为十进制是116字节,74后面紧接着“\r\n”是chunk-size和chunk-data的分隔符,因此这里没有chunk-extension,这里我们可以看出头域结束符“\r\n\r\n”之后紧接的地址是000000E7,在000000E7后面是37 34 0d 0a,也就是“74\r\n”,74表示第一个chunk-data的十六进制长度,那么第一个chunk-data的起始地址就是000000EB,下一个chunk的起始地址就是000000EB + 74 + 2 = 00000161,在0000015F的位置我们可以看到0d 0a 32 39 0d 0a,也就是“\r\n29\r\n”,前一个“\r\n”表示上一个chunk的结束,然后29表示十六进制的下一个chunk-data的长度,后一个“\r\n”是chunk-size和chunk-data的分隔符。

从0000015F+ 2 + 2 + 2 = 00000165开始为第二个chunk-data的数据,长度为41个字节,于是下一个chunk的起始位置就是00000165 + 29 = 0000018E,这个地方的数据是0d 0a 30 0d 0a,也就是“0\r\n\r\n”,0作为chunk-size表示这个chunk为最后一个chunk,第一个“\r\n”表示最后一个chunk的结束,而第二个“\r\n”表示没有tailer部分,整个chunk-body结束。

4.3.3  特殊类型

特殊类型指的是HTTP响应中既没有Content-Length指明实体内容的长度,也没有Transfer-Encoding指明采用Chunked编码,只是服务器在发送完响应之后就直接关闭连接。

下面是一个特殊类型HTTP应答的例子:

HTTP/1.1413 Request Entity Too Large
Date:Wed, 26 Aug 2009 05:16:39 GMT
Server:Apache/2.0.63 (Unix) PHP/5.2.6
Vary:Accept-Encoding
Connection:close
Content-Type:text/html; charset=iso-8859-1<!DOCTYPEHTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>413Request Entity Too Large</title>
</head><body>
……

5参考链接

(1)       http://tools.ietf.org/html/rfc2616

百度MTC是业界领先的移动应用测试服务平台,为广大开发者在移动应用测试中面临的成本、技术和效率问题提供解决方案。同时分享行业领先的百度技术,作者来自百度员工和业界领袖等。

>>如有问题,欢迎与我沟通

转载于:https://blog.51cto.com/11009914/1734249

前端接入HTTP协议浅析相关推荐

  1. Golang和HTTPS在网站前端接入里的作用

    网站前端架构技术一直在不断的优化,而要做到全栈优化,就必须要运维.后端架构研发.前端模板渲染研发.系统和网络等各个部门的协作.同时,安全又是网站建设话题中避不开的梗,从2015年年初开始,HTTPS安 ...

  2. UniSwap V3协议浅析(下)

    文章前言 本篇文章我们继续接着之前的UniSwap V3协议浅析(上)来进行分析Uniswap v3设计 源码分析 UniswapV3Factory UniswapV3Factory的主要功能是提供创 ...

  3. Golang和HTTPS在网站前端接入里的高效应用

    网站前端架构技术优化的脚步从未停止过,而要做到全栈优化的目的,运维.后端架构研发.前端模板渲染研发.系统和网络等各个部门的协作当然少不了.与此同时,安全永远是网站建设中绕不开的梗,从2015年年初开始 ...

  4. 【计算机网络】数据链路层 : CSMA/CD 协议 ( 载波监听多点接入 / 碰撞检测 协议 | 单程端到端传播时延 | 截断二进制指数规避算法 | 计算示例 | 最小帧长问题 )★

    文章目录 一. CSMA/CD 协议 二. 传播时延对于 载波监听 的影响 三. 单程端到端传播时延 相关概念 四. 碰撞后重传时机 ( 截断二进制指数规避算法 ) 五.截断二进制指数规避算法 计算示 ...

  5. swift int转string_Swift集合类型协议浅析(下)

    关注[搜狐技术产品]公众号,第一时间获取技术干货 导读 本篇是Swift集合类型协议浅析系列文章的下篇,在这篇文章中,我们将继续围绕集合类型协议展开讨论,侧重点更多地关注于String相关的周边协议. ...

  6. F问题3-7:以太网使用载波监听多点接入碰撞检测协议CSMA/CD。频分复用FDM才使用载波。以太网有没有使用频分复用?...

    F问题3-7:以太网使用载波监听多点接入碰撞检测协议CSMA/CD.频分复用FDM才使用载波.以太网有没有使用频分复用? 答:这里的"载波"并非指频分复用FDM的载波.CSMA/C ...

  7. 关于Darwin接入私有协议、私有SDK码流的讨论

    关于Darwin接入私有协议.私有SDK码流的讨论 最近做到云视频/云监控的项目,跟团队伙伴讨论到一个架构问题,就是将私有协议的码流数据接入到Darwin,再通过Darwin对外提供高效的RTSP/R ...

  8. 【IoT】基于NB-IoT的CoAP协议浅析

    [IoT]基于NB-IoT的CoAP协议浅析 CoAP(Constrained Application Protocol) 协议是 IETF 提出的一种面向网络的协议,采用了与 HTTP 类似的特征, ...

  9. 阿里云云呼叫中心——软电话SDK前端接入

    摘要:2018年十二月份的时候,我们需要基于我们的后台系统开发应急呼叫系统.一直没有总结.我对这部分也许会有很多理解不透彻的地方,望小伙伴们彼此相互学习,多多提出不足呢. 技术:由于是基于我们的后来系 ...

最新文章

  1. win7中Android开发环境搭建超详细(百度)
  2. vSphere可用性之三准备实验环境
  3. 基于MEGA8的声音CLICK模块
  4. 【.NET Core项目实战-统一认证平台】第四章 网关篇-数据库存储配置(2)
  5. DES对称加密(2)三重DES
  6. 使用mac m1跑fortran代码hello world
  7. MYSQL学习笔记 (二)对数据库结构的增删改查
  8. 3 运行时间太长_10大污水处理预处理系统动态图及运行管理、故障处理
  9. Python得到n个从start到end的不重复随机数(set实现)
  10. elasticsearch6.0、jdk1.8、IK、kibana集群配置
  11. python算法基础教程_python算法教程pdf下载
  12. 创建学生管理系统java实训1
  13. 机器学习视频课程(超清完整11周)分享给大家!
  14. 高速PCB设计之阻焊层和助焊层的检查
  15. mac删除默认ABC输入法,mac删除自带ABC输入法
  16. 小白vba之批量数据整理(excel自动化入门)
  17. java解决windows下文件没有Everyone以及完全控制的权限问题
  18. Kindle刷安卓双系统的方法_我是亲民_新浪博客
  19. Praat脚本-006 | 批量修改删除复制某一层
  20. CAD 偏移和复制、移动的区别

热门文章

  1. 在linux环境下安装wiringpi库,wiringPi库的pwm配置及使用说明
  2. java 主线程等待_Java实现主线程等待子线程
  3. 心理学博士vs计算机博士,零基础跨专业考心理学博士,可以给我一些建议吗?...
  4. Linux相关配置 集群免密码登录配置
  5. 对java这门课程的认识_关于java课程的总结
  6. centos上如何装python_centos如何安装Python3
  7. 统计c语言中英文字幕,C语言日记——递归
  8. linux nls_lang oracle,linux操作系统环境变量LANG和NLS_LANG的区别
  9. mysql临时表的的理解,如何理解存储过程中已存在的mysql临时表?
  10. mysql何时会走索引