分享

Http--基础理解

 quandsu 2017-03-12

在我们日常的开发工作中,主要接触的应用层协议主要是Http协议,对Http协议的基本理解对我们日常开发中的问题解决会用一定的帮助,这篇文章将对Http协议进行一个基本的介绍。

1 前言

下图是一个比较简单的互联网的概念模型

这里写图片描述

它们在我们日常的生活在很常见: 
1. Clients: 我们日常使用的手机、电脑和pad在这里主要充当的角色就是客户端(Clients); 
2. Servers: 我们所浏览的网页是存放在服务器端(Servers),这些服务器一般叫做内容提供者,例如百度公司提供搜索服务的服务器; 
3. Network Communication: 客户端和服务器一般在地理空间上是异地的,而要在两者之间建立起联系,就需要通信链路将两者关联起来,日常生活中我们所接触到的电信等宽带公司就提供这些基础的链路通信功能,这样就可以使我们的客户端和服务器进行通信.

这篇文章所介绍的http协议是我们享用所有网络服务当中应用最为广泛的协议之一,我们日常浏览使用浏览器进行浏览网页、看视频和听音乐等服务都使用http协议进行数据通信.

2 Http的历史

Http(Hypertext Transfer Protocal)的中文名称是超文本传输协议,该协议是用来定义如何传输超文本内容的一组通信规约,其中的“超文本”是一种特殊的文本,它具有可以链接到其他的文本的特点,这也是它与其他普通文本的重要区别,这里的“链接”可以理解为我们在网页中进行点击,页面就跳转到其他页面.

Http协议的最初是由欧洲核子研究中心的Tim Berners-Lee开发的,他同时也开发了相关连的html以及一个基于文本内容的浏览器,不得不说这货太厉害了.

对,就是这货

不久之后Http协议的开发和维护工作就交由IETF,IETF提议并通过Http 1.0 和Http 1.1 标准,当前最新的是Http 2.0,想了解最新的Http 2.0的动态可以登陆 https://http2./ 进行了解;

这篇文章主要对当前还在广泛使用的Http 1.1进行介绍. Http1.1协议定义在rfc2616.

3 Http的定义

Http协议所描述的通讯过程概念图如下所示: 
这里写图片描述

注意:上图描述的”HTTP over TCP/IP”,它表达的意思是HTTP的数据是通过TCP传输层协议来提供数据通讯服务,学过网络课程的童鞋可能知道,TCP和UDP的最大区别就是它提供可靠的通讯服务,So, HTTP自然选中它了,其实HTTP协议和TCP并不是强制的约束,HTTP协议只要求底层的数据传输服务提供可靠的数据传输即可,对协议没有特定的要求. 另外一个就是HTTP协议默认用80端口,当然你可以改变.

在这个概念图中我们可以知道,我们的浏览器向服务器发送请求,服务器处理完成后,将处理的结果以Http Response的形式返回给我们,下面我将通过一个简单的网页访问来介绍Http的一些概念.

Http协议通讯的简单场景描述—访问有道词典首页: 
1

在我们没有详细讨论协议本身的细节之前,我们可以想象一下自己正常的超市购物情形,一般我们先得确!定自己去哪家超市,然后再在超市里面找到我们想要的商品;

同样,我们要获取网络上面的资源获取也不外乎这样的寻找过程,首先,我们得明确出我们想到哪获取我们要的网页,其次,我们得明确的说明获取哪个网页(毕竟一个服务器上的网页辣么的多).为了解决上面两个问题,Http协议规定了Request应该包含这两个信息,perfect!!! 问题完美解决…

为了解释的能够具体一点,我先介绍一下HTTP协议规定的Request格式

Request  = Request-Line            
           *(( general-header       
           | request-header         
           | entity-header ) CRLF)  
           CRLF
           [ message-body ]     

Request-Line   = Method SP Request-URI SP HTTP-Version CRLF
Method         = "OPTIONS"              
                      | "GET"                   
                      | "HEAD"                   
                      | "POST"                  
                      | "PUT"                   
                      | "DELETE"               
                      | "TRACE"                
                      | "CONNECT"                
                      | extension-method
       extension-method = token
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

上面定义中包含的特殊字符解释:

SP: 表示空格;

CRLF: 表示回车换行;

HTTP-Version: 表示HTTP的协议版本,当前使用最多的是”HTTP/1.1”,和”HTTP/1.0”,最新的是”HTTP/2.0”;

METHOD: 表示当前请求的类型,不同的类型对服务器意味着不同的处理方式,例如: POST表示新增,DELETE表示删除资源,HTTP协议预定义了一些方法:OPTIONS, GET, POST, DELETE, PUT, TRACE,HEAD等;

Request-URI: 表示请求资源的路径,这个路径是相对服务器上配合的资源路径,而且必须以”/”开头;

HTTP 的Request的具体格式是定义在等号右边表达式中,大家可能对上面的表示方法不熟悉,解释如下: 
1 Http 的请求的第一行是”Request-Line”,它的具体定义是在第8行中;

格式为: “Method SP Request-URI SP HTTP-Version CRLF”,其中的字符意义大家在上面的解释中知道了,现在举个例子:GET /index.html HTTP/1.1, 这个Request-Line说明了当求请求的方法是GET, 请求的是服务器的/index.html路径下的文件资源,后面的HTTP/1.1表示当前的请求使用的是HTTP协议的1.1版本.

2 第二行的“*”表示后面括号里面定义的对象出现多次,其实就是可以出现多个请求的报头;

“general-header | request-header | entity-header) CRLF”:表示的是请求的报头,内容可以是general-header, request-header或entity-header等三种不同类别的请求头,具体的内容以后解释;括号后面的“CRLF”表示换行,这个表达式的意思是: 每个general-header定义之后应该换行,也就是每一个header需要使用一行;

4 中间的“CRLF”用来分开请求的header和body,这个比较容易理解,毕竟这两个是不同的概念;

5 message: 它是请求的body的部分,用来装载本地将要发给服务器端的数据,例如:博文、图片等;

上面介绍了这么多的基础知识了,让我们实际操作一下, 首先打开自己的浏览器开发工具(F12), 让后在浏览器的地址栏输入:dict.youdao.com,可以看到开发工具的实际请求内容,好多请求啊:

这里写图片描述

点击众多请求中的第一个,然后可以看到开发工具展开显示请求的详细内容:

这里写图片描述

这里我们点击”Request Header”旁边的view source按钮,将会看到实际发送的请求内容:

这里写图片描述

在请求中我们请求的服务器地址记录在Host这个请求报头,而我们请求的具体资源,记录在第一行的“GET / HTTP/1.1”中 这一行包含三类信息,分别对应” request-method  request-url   http-version”,而我们现在请求的就是首页信息,即请求中的“request-url”为”/”;

2 有道的服务器收到我们的请求后,首先解析请求的内容,发现用户想要的是首页信息,这时服务器就从自己的网站根目录下找到index.html,并将该页面作为结果返回给用户;

用户浏览器收到有道服务器的response,response当中包含response header 和 response body, response header用来表示请求的处理结果,以及request body内容的格式及长度信息,以下是客户端收到的response header:

HTTP/1.1 200 OK
Server: nginx
Date: Sun, 21 Aug 2016 11:26:56 GMT
Content-Type: text/html; charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
Vary: Accept-Encoding
Content-Language: zh-CN
Content-Encoding: gzip
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

在response header的第一行中表明本次请求的处理结果,可以看到上面有”OK”的字样,表明本次请求已经被服务器成功处理,这里面的“200”其实是一个状态码,而“OK”其实就是对这个状态码的字面解释,在日常的而开发过程中我们会经常遇到404(Not Found)和500(Internal Error),这些状态码都表明了当前请求被服务器处理的结果,用户可以根据状态码了解请求是否被正确的处理.

response body 就是用来包含用户请求的资源内容,例如本次请求的内容就是首页的html内容.

这里写图片描述

浏览器在判断本次请求成功处理(返回状态码是200)后,根据Response Header中Content-Type了解到response body里面的内容是html文档,所以浏览器html执行引擎将response body里面的内容进行解析和渲染,即最终的页面结果就是我们所看到的:

这里写图片描述

Http协议的特点 
1. 通信不对称: 服务器一直处在等待接受用户请求的状态,服务器不允许主动向客户端发送请求,然而,客户端就主动向服务器发生请求; 
2. 状态无关:这个概念主要描述的是Http的请求之间并没有关系,当前的请求并不知道之前请求的任何状态信息;

3.1 http定义的功能

在上面的例子中我们看到了一个普通的Http请求的处理过程,Http标准定义了几种访问服务器的方法,除了上面说描述的”GET”之外,此外还有: 
1. POST 
2. HEAD 
3. TRACE 
4. DELETE 
5. PUT 
… 
每一种请求方式都有存在的使用目的,具体可以参考: https://www./Protocols/rfc2616/rfc2616-sec9.html,本篇仅对日常开发经常用到的两个请求方式GET和POST进行说明;

3.2 GET方法

GET方法一般用来请求服务器的资源,对服务器的本身的数据没有任何的改变,仅仅将请求需要的页面返回给用户,例如一般的新闻站点,它们提供的服务就是仅供用户浏览.

GET请求的格式一般是:

GET   request-url  HTTP/1.1
Host: hostname
Accept: text/html;*/*
...
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

例如你要获取百度的首页,这是请求中的hostname就是百度服务器的地址:www.baidu.com,同时你请求的首页信息,request-url可以是”/”或是”/index.html” 
注意: 
request-url必须是以”/”开头的字符串,表示相对于服务器的资源根目录例如:如果服务器的页面放置在”/data/www/”目录下,请求中的第一个”/”就是代表这个目录,如果请求的是url是”/index.html”,其获取的页面在服务器的路径就是”/data/www/index.html”.

3.3 POST方法

POST方法一般是用来向服务器提交表单数据,例如用户的登陆页,用户需要输入自己的用户名和密码等信息.

POST请求将用户提交的数据保存在Request Body当中,下面给出一个简单的表单提交页面:

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>登陆</title>
</head>

<body>
    <form method="POST" action="/login.html">
        <label for="name">用户名</label>
        <input type="text" name="name" id="name"><br>
        <label for="password">密码</label>
        <input type="password" name="password" id="password">
        <input type="submit" value="提交">
    </form>
</body>
</html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

页面是: 
这里写图片描述

当我们在页面填写完信息后,点击提交按钮后,浏览器会将我们的表单内容封装到Request Body当中. 
这里写图片描述

参考: 
1. A Practical Guide to Writing Clients and Servers 
2. RFC 2616 标准 
3. Http基础理解 
4. RFC2616 is dead

To be continued.

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多