第41章 HTTP超文本传输协议基础知识
本章节为大家讲解HTTP(HyperText Transfer Protocol,超文本传输协议),从本章节开始,正式进入嵌入式Web的设计和学习。
(本章的知识点主要整理自网络)
41.1 初学者重要提示
41.2 HTTP基础知识参考资料
41.3 HTTP基础知识点
41.4 HTTP通信实例
41.5 总结
41.1 初学者重要提示
- HTTP超文本传输协议在实际项目中有比较重要的实用价值,需要初学者对HTTP的基础知识也有个认识。
- HTTP涉及到的知识点非常多,我们这里仅整理出几个比较重要的知识点。最主要的是41.3.5小节的HTTP请求消息和41.3.6小节的HTTP响应消息,针对这两个知识点专门在41.4小节做了一个举例。
41.2 HTTP基础知识参考资料
大家可以从以下地址获得HTTP基础知识:
- RFC2616地址(HTTP/1.1) : ftp://ftp.rfc-editor.org/in-notes/rfc2616.txt 。
- wiki百科中文版HTTP:地址链接(这个是超链接)
- wiki百科英文版HTTP:地址链接(这个是超链接)
- 百度百科HTTP:地址链接(这个是超链接)
对于初学者来说,学习上面四个参考资料就够了。如果大家有网络方面的书籍,比如《TCP/IP详解》,也可以直接看书籍。
41.3 HTTP基础知识点
(这里的知识点整理自上面的参考资料地址)
教程这里也对HTTP的基础知识做个介绍,方便大家先有个大概的认识。
41.3.1 HTTP简要说明
超文本传输协议(HTTP,HyperText Transfer Protocol)是互联网上应用最为广泛的一种网络协议。所有的WWW文件都必须遵守这个标准。设计HTTP最初的目的是为了提供一种发布和接收HTML页面的方法。1960年美国人Ted Nelson构思了一种通过计算机处理文本信息的方法,并称之为超文本(hypertext),这成为了HTTP超文本传输协议标准架构的发展根基。Ted Nelson组织协调万维网协会(World Wide Web Consortium)和互联网工程工作小组(Internet Engineering Task Force )共同合作研究,最终发布了一系列的RFC,其中著名的RFC 2616定义了HTTP 1.1。
41.3.2 HTTP和HTTPS
HTTPS(Hyper Text Transfer Protocol over Secure Socket Layer)是以安全为目标的HTTP通道,简单讲是HTTP的安全版。即HTTP下加入SSL层,HTTPS的安全基础是SSL,因此加密的详细内容就需要SSL。现在主流的网站已经全部采用HTTPS。
超文本传输协议HTTP被用于在Web浏览器和网站服务器之间传递信息。HTTP协议以明文方式发送内容,不提供任何方式的数据加密,如果攻击者截取了Web浏览器和网站服务器之间的传输报文,就可以直接读懂其中的信息,因此HTTP协议不适合传输一些敏感信息,比如信用卡号、密码等。
为了解决HTTP协议的这一缺陷,需要使用另一种协议:HTTPS。为了数据传输的安全,HTTPS在HTTP的基础上加入了SSL协议,SSL依靠证书来验证服务器的身份,并为浏览器和服务器之间的通信加密。
HTTPS和HTTP的区别主要为以下四点:
- HTTPS协议需要到CA申请证书,一般免费证书很少,需要交费。
- HTTP是超文本传输协议,信息是明文传输,HTTPS 则是具有安全性的SSL加密传输协议。
- HTTP和HTTPS使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。
- HTTP的连接很简单,是无状态的,HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比HTTP协议安全。
41.3.3 HTTP技术框架
HTTP是一个客户端和服务器端请求和应答的标准。客户端是终端用户,服务器端是网站。
- 通过使用Web浏览器、网络爬虫或者其它的工具,客户端发起一个到服务器上指定端口(默认端口为80)的HTTP请求,我们称这个客户端叫用户代理。
- 应答的服务器上存储着一些资源,比如HTML文件和图像,我们称这个应答服务器为源服务器。
- 在用户代理和源服务器中间可能存在多个中间层,比如代理,网关,或者隧道(tunnels)。
尽管TCP/IP协议是互联网上最流行的应用,HTTP协议并没有规定必须使用它和基于它支持的层。 事实上,HTTP可以在任何其他互联网协议上,或者在其他网络上实现。HTTP只要求其下层协议提供可靠的传输,任何能够提供这种保证的协议都可以被其使用。也正是因为这个,HTTP采用的TCP通信,而没有采用UDP。
通常,由HTTP客户端发起一个请求,建立一个到服务器指定端口(默认是80端口)的TCP连接。HTTP服务器则在那个端口监听客户端发送过来的请求。一旦收到请求,服务器向客户端发回一个状态行,比如"HTTP/1.1 200 OK"和响应的消息,消息的消息体可能是请求的文件、错误消息、或者其它一些信息。
通过HTTP或者HTTPS协议请求的资源由统一资源标示符(URI,Uniform Resource Identifiers),或者更准确一些,URLs来标识。
41.3.4 HTTP请求方法
HTTP/1.1协议*定义了如下几种方法来操作指定的资源:
- GET
从指定的资源请求数据。
- HEAD
与 GET 相同,但只返回 HTTP 报头,不返回消息主体。
- POST
向指定资源提交数据,请求服务器进行处理(例如提交表单或者上传文件)。数据被包含在请求消息中。这个请求可能会创建新的资源或修改现有资源,或二者皆有。
- PUT
向指定资源位置上传其最新内容。
- DELETE
请求服务器删除Request-URI(HTTP请求信息格式中请求行的一个成员)所标识的资源。
- TRACE
回显服务器收到的请求,主要用于测试或诊断。
- OPTIONS
这个方法可使服务器传回该资源所支持的所有HTTP请求方法。用“*”来代替资源名称,向Web服务器发送OPTIONS请求,可以测试服务器功能是否正常运作。
- CONNECT
HTTP/1.1协议中预留给能够将连接方式改为隧道(tunnels)方式的代理服务器。通常用于SSL加密服务器的连接(经由非加密的HTTP代理服务器)。
------------------------------------------------------------------------------------------------------
请求方法的名称是区分大小写的。当某个请求所针对的资源不支持对应的请求方法时,服务器应当返回状态码405(Method Not Allowed),当服务器不认识或者不支持对应的请求方法时,应当返回状态码501(Not Implemented)。
HTTP服务器至少应该实现GET和HEAD方法,其他方法都是可选的。当然,所有的方法支持的实现都应当匹配各自的定义。此外,除了上述方法,特定的HTTP服务器还能够扩展自定义的方法。例如:
PATCH(由 RFC 5789 指定的方法)可将局部修改应用到资源。
41.3.5 HTTP请求消息格式
发出的请求消息(message request)包括以下几个部分:
- 请求行(Request line,仅一行)
请求行格式如下:
请求行由请求方法、URL和协议版本三个部分组成,中间用空格分隔,且必须以<CR><LF>回车和换行符结尾。
这个字段是大小写敏感的,包括OPTIONS、GET、HEAD、POST、PUT、DELETE、TRACE等。方法GET和HEAD应该被所有的通用WEB服务器支持,其他所有方法的实现是可选的。GET方法取回由Request-URI标识的信息。HEAD方法也是取回由Request-URI标识的信息,只是可以在响应时,不返回消息体。POST方法可以请求服务器接收包含在请求中的实体信息,可以用于提交表单,比如向新闻组、BBS、邮件群组,数据库等发送消息。
SP表示空格。Request-URI遵循URI格式,在此字段为星号(*)时,说明请求并不用于某个特定的资源地址,而是用于服务器本身。HTTP-Version表示支持的HTTP版本,例如为HTTP/1.1。
<CR><LF>表示回车换行符。
举一个请求行的例子:GET /images/logo.gif HTTP/1.1,表示从/images目录下请求logo.gif这个文件。
- 请求头域(Request header fields,可以多行)
请求头域的格式如下:
请求头域必须以<CR><LF>作为结尾。在HTTP/1.1协议中,所有的请求头域,除Host外,都是可选的。
请求头域允许客户端向服务器传递关于请求或者关于客户机的附加信息。请求头域可能包含下列字段Accept、Accept-Charset、Accept-Encoding、Accept-Language、Authorization、From、Host、If-Modified-Since等。对请求头域的扩展要求通讯双方都支持,如果存在不支持的请求头域,一般将会作为实体头域处理。
下面是典型的请求消息:
Host: download.*******.de Accept: */* Pragma: no-cache Cache-Control: no-cache User-Agent: Mozilla/4.04[en](Win95;I;Nav) Range: bytes=554554-
上面第一行表示HTTP客户端(可能是浏览器、下载软件)通过GET方法获得指定URL下的文件。
注:具体这些响应头域代表的含义,请看wiki百科中文版上的说明:地址链接(这是一个超链接)和wiki百科英文版:地址链接(这是一个超链接)。
- 空行(Empty line 仅一行)
空行内必须只有<CR><LF>而无其他空格。
- 其他消息体(Message body)
这一部分是HTTP可选的正文数据部分。
41.3.6 HTTP响应消息格式
响应消息(message request)包括以下几个部分:
- 状态行(Status line 仅一行)
状态行格式如下:
状态行由HTTP版本、状态码和状态码描述三个部分组成,中间用空格分隔,且必须以<CR><LF>回车和换行符结尾。
HTTP-Version表示支持的HTTP版本,例如为HTTP/1.1。Status-Code是一个三个数字的结果代码。Reason-Phrase给Status-Code提供一个简单的文本描述。Status-Code主要用于机器自动识别,Reason-Phrase主要用于帮助用户理解。Status-Code的第一个数字定义响应的类别,后两个数字没有分类的作用。第一个数字可能取5个不同的值:
1xx: 信息响应类,表示服务器已经接收了客户端请求,客户端可以继续发请求。
2xx: 处理成功响应类,表示服务器已经成功接收到请求并进行处理。
3xx: 重定向响应类,表示需要客户端采取进一步的操作才能完成请求。
4xx: 客户端错误,表示客户请求包含语法错误或者是不能正确执行。
5xx: 服务器端错误,表示服务器在处理客户端请求的过程中有错误或者异常状态发生。
注:关于状态码更详细的介绍,可以看百度百科:地址链接 (这是一个超链接)
- 响应头域(Response header fields 可以多行)
响应头域的格式如下:
响应头域必须以<CR><LF>作为结尾。
响应头域允许服务器传递不能放在状态行的附加信息,这些域主要描述服务器的信息和Request-URI的进一步信息。响应头域包含Age、Location、Proxy-Authenticate、Public、Retry-After、Server、Vary、Warning、WWW-Authenticate等。对响应头域的扩展要求通讯双方都支持,如果存在不支持的响应头域,一般将会作为实体头域处理。
下面是典型的响应消息:
HTTP/1.0 OK Date:Mon,31Dec200104::57GMT Server:Apache/1.3.(Unix) Content-type:text/html Last-modified:Tue,17Apr200106::28GMT Etag:"a030f020ac7c01:1e9f" Content-length: Content-range:bytes55******/
注:具体这些响应头域代表的含义,请看wiki百科中文版上的说明:地址链接(这是一个超链接)和wiki百科英文版:地址链接(这是一个超链接)。
- 空行(Empty line 仅一行)
空行内必须只有<CR><LF>而无其他空格。
- 其他消息体(Msessage body)
这一部分是HTTP的正文数据部分。
41.3.7 HTTP无状态协议
HTTP无状态协议,是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时,它的应答就较快。
客户端与服务器进行动态交互的Web应用程序出现之后,HTTP无状态的特性严重阻碍了这些应用程序的实现,毕竟交互是需要承前启后的,简单的购物车程序也要知道用户到底在之前选择了什么商品。于是,两种用于保持HTTP连接状态的技术就应运而生了,一个是Cookie,而另一个则是Session。HTTP本身是一个无状态的连接协议,为了支持客户端与服务器之间的交互,我们就需要通过不同的技术为交互存储状态,而这些不同的技术就是Cookie和Session了。
Cookie是通过客户端保持状态的解决方案。从定义上来说,Cookie就是由服务器发给客户端的特殊信息,而这些信息以文本文件的方式存放在客户端,然后客户端每次向服务器发送请求的时候都会带上这些特殊的信息。让我们说得更具体一些:当用户使用浏览器访问一个支持Cookie的网站的时候,用户会提供包括用户名在内的个人信息并且提交至服务器,接着,服务器在向客户端回传相应的超文本的同时也会发回这些个人信息,当然这些信息并不是存放在HTTP响应体(Response Body)中的,而是存放于HTTP响应头(Response Header)。当客户端浏览器接收到来自服务器的响应之后,浏览器会将这些信息存放在一个统一的位置,自此,客户端再向服务器发送请求的时候,都会把相应的Cookie再次发回至服务器。而这次,Cookie信息则存放在HTTP请求头(Request Header)了。
41.3.8 HTTP持久连接
在HTTP 0.9和1.0中,TCP连接在每一次请求/回应对之后关闭。在HTTP 1.1中,引入了保持连接的机制,一个连接可以重复在多个请求/回应使用。持续连接的方式可以大大减少等待时间,因为在发出第一个请求后,双方不需要重新运行TCP握手程序。
HTTP 1.1还使改进了HTTP 1.0的带宽。 例如,HTTP 1.1引入了分块传输编码,以允许传递内容可以在持久连接上被传输而不必使用到缓冲器。HTTP隧道允许客户端在收到每个回应之前发送多个请求,进一步减少用户感受到的滞后时间。协议的另一个补充是字节服务,允许客户端请求资源的某一部分,服务器仅回应某资源的指定部分。
41.3.9 HTTP版本
HTTP已经演化出了很多版本,它们中的大部分都是向下兼容的。在 RFC 2145 中描述了HTTP版本号的用法。客户端在HTTP请求消息中告诉服务器它采用的协议版本号,而服务器则在响应中采用相同或者更早的协议版本。
- HTTP/0.9
已过时。只接受GET一种请求方法,没有在通讯中指定版本号,且不支持请求头。由于该版本不支持POST方法,因此客户端无法向服务器传递太多信息。
- HTTP/1.0
这是第一个在通讯中指定版本号的HTTP协议版本,至今仍被广泛采用,特别是在代理服务器中。
- HTTP/1.1
持久连接被默认采用,并能很好地配合代理服务器工作。还支持以隧道(tunnels)方式同时发送多个请求,以便降低线路负载,提高传输速度。
HTTP/1.1相较于HTTP/1.0协议的区别主要体现在:
- 缓存处理。
- 带宽优化及网络连接的使用。
- 错误通知的管理。
- 消息在网络中的发送。
- 互联网地址的维护。
- 安全性及完整性。
- HTTP/2
HTTP/2是HTTP协议自1999年HTTP 1.1发布后的首个更新,主要基于SPDY协议。它由互联网工程任务组(IETF)的Hypertext Transfer Protocol Bis(httpbis)工作小组进行开发。该组织于2014年12月将HTTP/2标准提议递交至IESG进行讨论,于2015年2月17日被批准。
HTTP/2标准于2015年5月以RFC 7540正式发表。HTTP/2的标准化工作由Chrome、Opera、Firefox、Internet Explorer 11、Safari、Amazon Silk及Edge等浏览器提供支持。
多数主流浏览器已经在2015年底支持了该协议。此外,根据W3Techs的数据,在2017年5月,在排名前一千万的网站中,有13.7%支持了HTTP/2。
41.4 HTTP通信实例
为了帮助大家更好的理解HTTP的请求消息和响应消息,我们这里举一个例子。请求消息如下(注意,下面代码有4行,第3行和第4行都是回车换行):
GET /index.html HTTP/1.1 Host: www.example.com
- GET /index.html HTTP/1.1
这个是请求行,请求方法使用GET,请求的URL是/index.html,即获取此网页内容,协议版本是HTTP/1.1。特别注意,这三个部分之间一定要有空格,且末尾一定要带回车换行。回车换行在这里的表现形式就是切换到了下一行Host。
- Host: www.example.com
这个是请求头域,Host头域必须要有,这里是访问网站www.example.com。特别注意,末尾也要有回车和换行符,反映在这里就是空白的第3行,由回车和换行符切换到这一行的。
- 空行
空行也是必不可少的,反映在这里就是空白的第4行,也是由回车和换行符切换到这一行的。
为了让大家看到回车换行的效果,将请求消息整理到记事本里面,然后用winhex软件打开这个记事本就可以看到回车换行的数值了。
下面我们测试HTTP请求消息,测试方法也比较简单,依然使用我们TCP通信章节用的网络调试助手。
- 第1步:创建客户端。
- 第2步:填写请求信息。
- 第3步:点击发送就可以看到返回的响应消息了。
返回的完整消息内容如下:
HTTP/1.1 OK Cache-Control: max-age= Content-Type: text/html Date: Sun, Aug :: GMT Etag: "359670651+ident" Expires: Sun, Aug :: GMT Last-Modified: Fri, Aug :: GMT Server: ECS (rhv/) Vary: Accept-Encoding X-Cache: HIT Content-Length: <!doctype html> <html> <head> <title>Example Domain</title> <meta charset="utf-8" /> <meta http-equiv="Content-type" content="text/html; charset=utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <style type="text/css"> body { background-color: #f0f0f2; margin: ; padding: ; font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif; } div { width: 600px; margin: 5em auto; padding: 50px; background-color: #fff; border-radius: 1em; } a:link, a:visited { color: #38488f; text-decoration: none; } @media (max-width: 700px) { body { background-color: #fff; } div { width: auto; margin: auto; border-radius: ; padding: 1em; } } </style> </head> <body> <div> <h1>Example Domain</h1> <p>This domain is established to be used for illustrative examples in documents. You may use this domain in examples without prior coordination or asking for permission.</p> <p><a href="http://www.iana.org/domains/example">More information...</a></p> </div> </body> </html>
- HTTP/1.1 200 OK
这个是状态行,协议版本HTTP/1.1,状态码200,状态码描述OK,表示响应消息返回成功。
- Cache-Control
这个是响应头域,表示缓冲控制,无论是否可以缓存此对象,都要告诉服务器到客户端的所有缓存机制。这里表示604800秒后缓冲的内容失效。
- Content-Type
属于响应头域,内容类型用于定义网络文件的类型和网页的编码,决定文件接收方将以什么形式、什么编码读取这个文件。这里返回的内容类型是TEXT/HTML。
- Date
属于响应头域,表示此条消息被发送时的日期和时间。
- Etag
属于响应头域,表示对于某个资源的某个特定版本的一个标识符,通常是一个消息散列。ETag是HTTP协议提供的若干机制中的一种Web缓存验证机制,并且允许客户端进行缓存协商。
- Expires
属于响应头域,表示指定一个日期/时间,超过该时间则认为此回应已经过期。
- Last-Modified
属于响应头域,表示所请求对象的最后修改日期。
- Server
属于响应头域,表示服务器名字。
- Vary
属于响应头域,用于告知下游的代理服务器,应当如何对未来的请求协议头进行匹配,以决定是否可使用已缓存的回应内容而不是重新从原始服务器请求新的内容。
- X-Cache
属于响应头域,表示HTTP请求是由代理服务器回应的,HIT表示代理直接回应。
- Content-Length
属于响应头域,表示回应消息体的长度,即实际内容,单位字节。这里是1270字节的数据。
- 剩下的内容就是HTML格式的消息实体了。
具体大家可以实际操作下,有个感性的认识,另外就是换个其它的网址也操作下,加深理解。
41.5 总结
本章节就为大家讲解这么多,更多HTTP的相关知识需要大家查阅相关书籍进行学习,或者网上搜索相关资料进行学习。