HTTP协议

一 何为HTTP协议

HTTP(hypertext transport protocol),即超文本传输协议,用于万维网(WWW:World Wide Web )服务器与本地浏览器之间传输超文本的传输协议(互相通信的规则)。

HTTP是一个属于应用层的面向对象的协议,由于其简捷、快速的方式,适用于分布式超媒体信息系统。

二 HTTP工作原理

HTTP协议工作于C/S架构模型上。浏览器作为HTTP客户端通过URL向HTTP服务端即WEB服务器发送所有请求。常见的web服务端有:Apache服务器、Nigix服务器等。

Web服务器根据接收到的请求后,向客户端发送响应信息。HTTP默认端口号为80,可根据实际情况进行修改。

三 HTTP协议特点

3.1 基于TCP/IP

HTTP协议是基于 TCP/IP 协议之上的应用层协议。

3.2 基于请求-响应模式

HTTP协议规定请求从客户端发出,最后服务器端响应该请求并返回。换句话说,肯定是先从客户端开始建立通信的,服务器端在没有接收到请求之前不会发送响应。

image

3.3 无状态保存

HTTP是一种不保存状态,即无状态 (stateless )协议。 HTTP 协议自身不对请求和响应之间的通信状态进行保存。也就是说在 HTTP 这个级别,协议对于发送过的请求或响应都不做持久化处理。

使用HTTP 协议,每当有新的请求发送时,就会有对应的新响应产生。协议本身并不保留之前一切的请求或响应报文的信息。这是为了更快地处理大量事务,确保协议的可伸缩性,而特意把 HTTP 协议设计成如此简单的。可是随着 Web 的不断发展,因无状态而导致业务处理变得棘手的情况增多了。比如,用户登录到一家购物网站,即使他跳转到该站的其他页面后,也需要能继续保持登录状态。针对这个实例,网站为了能够掌握是谁送出的请求,需要保存用户的状态。 HTTP/1.1 虽然是无状态协议,但为了实现期望的保持状态功能 , 于是引入了 Cookie 技术。有了 Cookie 再用 HTTP 协议通信就可以管理状态了。有关 Cookie 的详细内容后面再进行学习。

3.4 无连接

无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。

一句话:HTTP是基于客户端/服务端(C/S)的架构模型,通过一个可靠的链接来交换信息,是一个无状态的请求/响应协议。

何为URL?

URL(Uniform Resource Locator),即统一资源定位符,说白了就是一个网址,组成结构如下:

协议名://域名:端口/路径,比如:http://mysite:8080/main/index.html

四 HTTP的工作流程

HTTP的基本交互流程如下图所示:

image_thumb1

每个HTTP站点都有一个服务器进程监听着TCP的HTTP端口,HTTP端口默认为80,也可由服务器进程设为其他端口。当服务器发现有客户端建立连接并提交了一个HTTP请求(Request)后,就根据请求的内容执行相应的操作,并将结果返回给客户端(Response)。通常客户在浏览器中发起一次网络访问的步骤如下:

第一步:输入网址并按Enter键,比如访问:http://mysite:8080/main/index.html

第二步:浏览器通过域名查询到真实IP,比如为:172.1.1.1

第三步:向服务器172.1.1.1的8080端口发起TCP连接请求并建立连接

第四步:发送HTTP请求的内容,包括访问的地址:/main/index.html、访问方式GET、浏览器本身的产品名等

第五步:服务器返回/main/index.html中的数据作为Response发送给客户端。如果请求的不是一个文件,则服务器需要执行相应的代码,动态生成且返回给客户端

第六步:浏览器收到结果后关闭与服务器的TCP连接

第七步:浏览器将接收到的结果呈现在显示器上

注意:域名解析本身不是HTTP的一部分,客户端应在向服务器建立TCP连接之前就通过DNS服务器完成域名解析工作。

1.根据域名,进行DNS域名解析;
2.根据解析拿到的IP的地址,建立TCP连接;
3.向IP地址发送HTTP请求;
4.服务器处理请求;
5.返回相应结果;
6.关闭TCP连接;
7.浏览器解析HTML;
8.浏览器布局渲染
另一种说明:俗称天龙八步

以上是最典型的HTTP流程,当今的HTTP版本还允许客户端再一次HTTP请求完成后不关闭TCP连接,以便第二次发送HTTP请求时复用该连接,从而达到减少系统整体开销的目的,此技术在HTTP中叫作keep-alive。

补充--如何查询某一域名的ip地址:

在终端输入要搜索网址,前面加上“PING ”。比如说百度就是:ping www.baidu.com

image_thumb3

五 客户端请求消息结构

客户端发送一个HTTP请求到服务器的请求消息包括以下四部分结构:

请求行(request line):请求方式、请求路径、协议和版本,例如:GET /index.html HTTP/1.1

请求头部(header):请求头名称:请求头内容,为key:value格式,例如:Host:localhost

空行:用来与请求体分隔开

请求数据:GET没有请求数据,只有POST有请求数据。

下图给出了请求消息的结构:

image_thumb5

GET /favicon.ico HTTP/1.1\
Host: 127.0.0.1:8880
Connection: keep-alive
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36
Accept: image/webp,image/apng,image/*,*/*;q=0.8
Referer: http://127.0.0.1:8880/
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
请求数据实例

注:本例中没有消息体

六 HTTP请求方法

在HTTP协议中,请求有很多请求方法,其中最为常用的就是GET和POST。下面列举出所有请求方法,供后期查询学习。

序号

方法

描述

1

GET

从访问的地址中获取信息,既获取信息头,又获取信息体。这是互联网上最主要的一种HTTP访问方式

2

POST

客户端通过POST方法向服务器提交新数据,服务器必须保证数据被完整地保存,并且服务器不允许出现重复的POST数据提交。这是HTML中通过表单(Form)提交数据所使用的URL访问方式

3

HEAD

类似于GET请求,只不过返回的响应中没有具体的内容(消息体),用于获取报头(消息头)

4

PUT

POST访问方法类似,PUT也是一种客户端向服务器提交数据的方式。但是PUT允许客户端重新提交主键的数据,当通过PUT访问方式在服务器中发现重复主键的数据时,它会用新提交的数据覆盖服务器中已有的数据

5

DELETE

从给定的地址中删除信息

6

CONNECT

HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器

7

OPTIONS

为客户端提供一种查询“本URL地址中有哪些可用的访问方式”的方法

8

TRACE

回显服务器收到的请求,主要用于测试或诊断

6.1 GET请求方法

HTTP默认的请求方法是GET,主要有以下特点:

  • 没有请求体
  • 数据有相应大小限制
  • GET请求数据会显示在浏览器的地址栏中

GET请求常用的操作:

  • 在浏览器的地址栏中直接给出URL,那么就一定是GET请求
  • 点击页面上的超链接一定是GET请求
  • 提交表单时,表单默认使用GET请求,但可以设置为POST

请求信息示例如下:

GET /favicon.ico HTTP/1.1
Host: 127.0.0.1:8880
Connection: keep-alive
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36
Accept: image/webp,image/apng,image/*,*/*;q=0.8
Referer: http://127.0.0.1:8880/
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
  • GET /favicon.ico  HTTP/1.1:GET请求,请求服务器路径为  /favicon.ico  ,协议为1.1;
  • Host:127.0.0.1:8880:请求的主机名为127.0.0.1:8880;
  • Connection: keep-alive:客户端支持的链接方式,保持一段时间链接,默认为3000ms;
  • User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36:与浏览器和OS相关的信息。有些网站会显示用户的系统版本和浏览器版本信息,这都是通过获取User-Agent头信息而来的;
  • Accept:image/webp,image/apng,image/*,*/*;q=0.8:告诉服务器,当前客户端可以接收的文档类型,其实这里包含了*/*,就表示什么都可以接收;
  • Accept-Language: zh-cn,zh;q=0.9:当前客户端支持的语言,可以在浏览器的工具选项中找到语言相关信息;
  • Accept-Encoding: gzip, deflate:支持的压缩格式。数据在网络上传递时,可能服务器会把数据压缩后再发送;
  • Referer: http://127.0.0.1:8880/:请求来自哪个页面,例如你在百度上点击链接到了这里,那么Referer:http://www.baidu.com;如果你是在浏览器的地址栏中直接输入的地址,那么就没有Referer这个请求头了;
  • Accept-Charset: GB2312,utf-8;q=0.7,*;q=0.7:客户端支持的编码;
  • Cookie: JSESSIONID=369766FDF6220F7803433C0B2DE36D98:因为不是第一次访问这个地址,所以会在请求中把上一次服务器响应中发送过来的Cookie在请求中一并发送去过;这个Cookie的名字为JSESSIONID。
Referer请求头是比较有用的一个请求头,它可以用来做统计工作,也可以用来做防盗链。
统计工作:我公司网站在百度上做了广告,但不知道在百度上做广告对我们网站的访问量是否有影响,那么可以对每个请求中的Referer进行分析,如果Referer为百度的很多,那么说明用户都是通过百度找到我们公司网站的。
防盗链:我公司网站上有一个下载链接,而其他网站盗链了这个地址,例如在我网站上的index.html页面中有一个链接,点击即可下载JDK7.0,但有某个人的微博中盗链了这个资源,它也有一个链接指向我们网站的JDK7.0,也就是说登录它的微博,点击链接就可以从我网站上下载JDK7.0,这导致我们网站的广告没有看,但下载的却是我网站的资源。这时可以使用Referer进行防盗链,在资源被下载之前,我们对Referer进行判断,如果请求来自本网站,那么允许下载,如果非本网站,先跳转到本网站看广告,然后再允许下载。
Referer的应用
HTTP无状态:无状态是指协议对于事务处理没有记忆能力,服务器不知道客户端是什么状态。从另一方面讲,打开一个服务器上的网页
和你之前打开这个服务器上的网页之间没有任何联系
如果你要实现一个购物车,需要借助于Cookie或Session或服务器端API(如NSAPI and ISAPI)记录这些信息,请求服务器结算页面时同时将这些信息提交到服务器
当你登录到一个网站时,你的登录状态也是由Cookie或Session来“记忆”的,因为服务器并不知道你是否登录
优点:服务器不用为每个客户端连接分配内存来记忆大量状态,也不用在客户端失去连接时去清理内存,以更高效地去处理WEB业务
缺点:客户端的每次请求都需要携带相应参数,服务器需要处理这些参数

容易犯的误区:
1、HTTP是一个无状态的面向连接的协议,无状态不代表HTTP不能保持TCP连接,更不能代表HTTP使用的是UDP协议(无连接)
2、从HTTP/1.1起,默认都开启了Keep-Alive,保持连接特性,简单地说,当一个网页打开完成后,客户端和服务器之间用于传输
HTTP数据的TCP连接不会关闭,如果客户端再次访问这个服务器上的网页,会继续使用这一条已经建立的连接
3、Keep-Alive不会永久保持连接,它有一个保持时间,可以在不同的服务器软件(如Apache)中设定这个时间
注意点

6.2 post请求方法

特点:

  • 数据不会出现在地址栏中
  • 数据的大小没有上限
  • 有请求体
  • 请求体中如果存在中文,会使用URL编码!
Http协议中参数的传输是"key=value"这种键值对形式的,如果要传多个参数就需要用“&”符号对键值对进行分割。如"?name1=value1&name2=value2",这样在服务端在收到这种字符串的时候,会用“&”分割出每一个参数,然后再用“=”来分割出参数值。

针对“name1=value1&name2=value2”我们来说一下客户端到服务端概念上的解析过程:
    上述字符串在计算机中用ASCII吗表示为:
        6E616D6531 3D 76616C756531 26 6E616D6532 3D 76616C756532。
        6E616D6531:name1
        3D:=
        76616C756531:value1
        26:&
        6E616D6532:name2
        3D:=
        76616C756532:value2
    服务端在接收到该数据后就可以遍历该字节流,首先一个字节一个字节的进行,当到3D这字节后,服务端就知道前面吃得字节表示一个key,再向后进行,如果遇到26,说明刚才3D到26子节之间的是上一个key的value,以此类推就可以解析出客户端传过来的参数。

现在有这样一个问题,如果我的参数值中就包含=或&这种特殊字符的时候该怎么办。
    比如:说“name1=value1”,其中value1的值是“va&lu=e1”字符串,那么实际在传输过程中就会变成这样“name1=va&lu=e1”。我们的本意是就只有一个键值对,但是服务端会解析成两个键值对,这样就产生了歧义。

如何解决上述问题带来的歧义呢?解决的办法就是对参数进行URL编码
    URL编码只是简单的在特殊字符的各个字节前加上%,例如,我们对上述会产生奇异的字符进行URL编码后结果:“name1=va%26lu%3De1”,这样服务端会把紧跟在“%”后的字节当成普通的字节,就是不会把它当成各个参数或键值对的分隔符。
URL编码基础知识了解

POST请求是可以有体的,而GET请求不能有请求体。

  • Content-Type: application/x-www-form-urlencoded:表单的数据类型,说明会使用url格式编码数据;url编码的数据都是以“%”为前缀,后面跟随两位的16进制。
  • Content-Length:13:请求体的长度,这里表示13个字节。
  • keyword=hello:请求体内容!hello是在表单中输入的数据,keyword是表单字段的名字。

七 服务端响应消息结构

HTTP响应也由四个部分组成,分别是:状态行、消息报头、空行和响应正文。

响应内容是由服务器发送给浏览器的内容,浏览器会根据响应内容来显示。遇到<img src=''>会开一个新的线程加载,所以有时图片多的话,内容会先显示出来,然后图片才一张张加载出来。

HTTP/1.1 200 OK                                                                   # 状态行
Date: Fri, 08 Dec 2017 08:47:56 GMT
Content-Type:text/html;charset=utf-8
Content-Length:0
Server:BWS/1.0
Set-Cookie:BDSVRTM=223; path=/
Set-Cookie:BD_HOME=1; path=/
Set-Cookie:H_PS_PSSID=1456_24886_21119_17001_25178; path=/; domain=.baidu.com     # 以上为消息报头:人为组合
                                                                                  # 空行
<!DOCTYPE html>                                                                   # 响应正文
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    
</body>
</html>
  • HTTP/1.1 200 OK:响应协议为HTTP1.1,状态码为200,表示请求成功,OK是对状态码的解释;
  • Server:xxx:服务器的版本信息;
  • Content-Type: text/html;charset=UTF-8:响应正文使用的编码为UTF-8;
  • Content-Length: xx:响应正文为xx字节;
  • Set-Cookie: xxxx:响应给客户端的Cookie;
  • Date: Wed, 25 Sep 2012 04:15:03 GMT:响应的时间,这可能会有8小时的时区差;

7.1 HTTP状态码

当访问一个网页时,访问者的浏览器会向网页所在服务器发出请求。当浏览器接收并显示网页前,此网页所在的服务器会返回一个包含HTTP状态码的信息头(server header)用以响应浏览器的请求。

常见状态码如下:

  • 200:请求成功,浏览器会把响应体内容(通常是html)显示在浏览器中;
  • 301:资源被永久转移到其他URL
  • 302:重定向,当响应码为302时,表示服务器要求浏览器重新再发一个请求,服务器会发送一个响应头Location,它指定了新请求的URL地址;
  • 404:请求的资源没有找到,说明客户端错误的请求了不存在的资源;
  • 500:请求资源找到了,但服务器内部出现了错误;

HTTP状态码分类

HTTP状态码由三个十进制数字组成,第一个十进制数字定义了状态码的类型,后两个数字没有分类的作用。HTTP状态码共分为5种类型:

状态码

类别

描述

1**

Information(信息性状态码)

表明服务器已经收到request,但需要进一步处理,请客户端等待

2**

Success(成功状态码)

请求正常处理完毕

3**

Redirection(重定向状态码)

请求地址被重定向,需要客户端重新发起请求

4**

Client Error(客户端错误状态码)

服务器无法处理请求。一般为请求中提交的参数或内容有错误

5**

Server Error(服务器错误代码)

服务器处理请求时出错,一般本类错误需要联系服务器管理员处理

更多:HTTP状态码详细列表

7.2 其他报头信息

告诉浏览器不要缓存的报头信息:

  • Expires: -1;
  • Cache-Control: no-cache;
  • Pragma: no-cache;

自动刷新报头信息,浏览器会在3秒之后请求http://www.baidu.com:

Refresh: 3;url=http://www.baidu.com 

7.3 HTML中指定报头信息

在HTMl页面中可以使用<meta http-equiv="" content="">来指定报头信息,例如:在index.html页面中给出<meta http-equiv="Refresh" content="3;url=http://www.baidu.com">,

表示浏览器只会显示index.html页面3秒,然后自动跳转到http://www.baidu.com

八 常用头字段

请参考:http://tools.jb51.net/table/http_header

 

参考:http://www.cnblogs.com/yuanchenqi/articles/6000358.html

posted @ 2018-09-23 15:43  Joe1991  阅读(140)  评论(0)    收藏  举报