HTTP 协议

HTTP 协议
Web 应用,以前也常被称之为 B/S 应用,B 代表浏览器(Brower),S 则代表服务器(Server),两者之间通过 HTTP 协议进行通信,从而构成了整个 Web 应用。 本文中,将详细介绍 HTTP 协议的相关知识。

HTTP 简介 如何标志网络中的资源 URL 详解
HTTP 请求
HTTP 响应
查看 HTTP 请求与响应 HTTP 事务

HTTP 简介

HTTP 协议是 Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(World Wide Web)服务器传输超文本到本地浏览器的传送协议。

HTTP 是基于 TCP/IP 通信协议来传递数据(HTML 文件, 图片文件, 查询结果等)。 TCP/IP 是一个协议族,HTTP、FTP、Telnet等都属于 TCP/IP 协议。

HTTP 是一个属于应用层的面向对象的协议,由于其简捷、快速的方式,适用于分布式超媒体信息系 统。它于 1990年提出,经过几年的使用与发展,得到不断地完善和扩展。目前在 WWW 中使用的是 HTTP/1.0 的第六 版,HTTP/1.1 的规范化工作正在进行之中,而且 HTTP-NG(Next Generation of HTTP)的建议已经提出。

HTTP 协议工作于客户端-服务端架构为上。浏览器作为 HTTP 客户端通过 URL 向 HTTP 服务端即 Web 服务器发 送所有请求。Web 服务器根据接收到的请求后,向客户端发送响应信息。

主要特点

简单快速:客户向服务器请求服务时,只需传送请求方法和路径。请求方法常用的有 GET、POST、HEAD、PUT 等等。每种方法规定了客户与服务器联系的类型不同。由于 HTTP 协议 简单,使得 HTTP 服务器的程序规模小,因而通信速度很快。
灵活:HTTP 允许传输任意类型的数据对象。正在传输的类型由 Content-Type 加以标记。 无连接:一次请求一次连接。服务器处理完客户的请求,并收到客户的应答后,即断开连接。 无状态:在 HTTP 协议中,客户端的每次请求,对于服务端来说,都是一次新的请求。 多种模式:支持 B/S 及 C/S 模式。

如何标志网络中的资源

URI

URI 是 Uniform Resource Identifier,统一资源标志符,用来唯一的标识一个资源,最常⻅形式是统一 资源定位符。Web 上可用的每种资源如 HTML 文档、图像、视频片段、程序等都是通过 URI 来标志的 URI 一般由三部组成:

访问资源的命名机制
存放资源的主机名 资源自身的名称,由路径表示,着重强调于资源。

URL

URL 是 Uniform Resource Locator,统一资源定位符,它是一种具体的 URI,即 URL 可以用来标识一 个资源,而且还指明了如何 locate 这个资源。

采用 URL 可以用一种统一的格式来描述各种信息资源,包括文件、服务器的地址和目录等。URL 一般由 三部组成:

https://developer.mozilla.org https://developer.mozilla.org/en-US/docs/Learn/ https://developer.mozilla.org/en-US/search?q=URL

 

协议

存有该资源的主机IP地址(有时也包括端口号) 主机资源的具体地址。如目录和文件名等

 

URN

URN 是 Uniform Resource Name,统一资源命名符,是通过名字来标识资源。 URI 是以一种抽象的,高层次概念定义统一资源标识,而 URL 和 URN 则是具体的资源标识的方 式。URL 和 URN 都是一种 URI。笼统地说,每个 URL 都是 URI,但不一定每个 URI 都是 URL。这是因为 URI 还包括一个子类,即统一资源名称 ( URN ),它命名资源但不指定如何定位资源。上面的 isbn 都是 URN 的示例。

URI 与 URL 和 URN 之间的关系 引用

URI 可被视为定位符( URL ),名称( URN )或两者兼备。统一资源名( URN )如同一个人的 名称,而统一资源定位符( URL )代表一个人的住址。换言之,URN 定义某事物的身份,而 URL 提供查找该事物的方法。

用于标识唯一书目的 ISBN 系统是一个典型的URN使用范例。例如, ISBN 0-486-27557-4 无二 义性地标识出莎士比亚的戏剧《 罗密欧与朱丽叶 》的某一特定版本。为获得该资源并阅读该书, 人们需要它的位置,也就是一个 URL 地址。在 类Unix 操作系统中,一个典型的URL地址可能是一 个文件目录,例如 file:///home/username/RomeoAndJuliet.pdf 。该 URL 标识出存储于本 地硬盘中的电子书文件。因此,URL 和 URN 有着互补的作用。

最后,概括起来,URI、URN、URL 之间的关系如下图:

URL 详解

HTTP 使用统一资源标识符(Uniform Resource Identifiers, URI)来传输数据和建立连接。URL 是一 种特殊类型的 URI,包含了用于查找某个资源的足够的信息。

URL,全称是 UniformResourceLocator,中文叫统一资源定位符,是互联网上用来标识某一处资源的 地址。以下面这个URL为例,介绍下普通URL的各部分组成:

 

http://www.aspxfans.com:8080/news/index.asp?boardID=5&ID=24618&page=1#name

从上面的 URL 可以看出,一个完整的 URL 包括以下几部分:
1. 协议部分:该URL的协议部分为 http: ,这代表网⻚使用的是HTTP协议。在Internet中可以使用多

种协议,如 HTTP,FTP 等等。本例中使用的是 HTTP 协议。在 http: 后面的 // 为分隔符
2. 域名部分:该 URL 的域名部分为 www.aspxfans.com 。一个 URL 中,也可以使用 IP 地址来进行资

源的访问。
3. 端口部分:跟在域名后面的是端口,域名和端口之间使用 : 作为分隔符。端口不是一个 URL 必须的

部分,如果省略端口部分,将采用默认的 80 端口。
4. 虚拟目录部分:从域名后的第一个 / 开始到最后一个 / 为止,是虚拟目录部分。虚拟目录也不是一个

URL 必须的部分。本例中的虚拟目录是 /news/ 。

5. 文件名部分:从域名后的最后一个 / 开始到 ? 为止,是文件名部分,如果没有 ? ,则是从域名后的 最后一个 / 开始到 # 为止,是文件部分,如果没有 ? 和 # ,那么从域名后的最后一个 / 开始到结束, 都是文件名部分。本例中的文件名是 index.asp 。文件名部分也不是一个 URL 必须的部分,如果省略 该部分,则使用默认的文件名。

6. 锚部分:从 # 开始到最后,都是锚部分。本例中的锚部分是 name 。锚部分也不是一个 URL 必须的部 分。

7. 参数部分:从 ? 开始到 # 为止之间的部分为参数部分,又称搜索部分、查询部分。本例中的参数部 分为 boardID=5&ID=24618&page=1 。参数可以允许有多个参数,参数与参数之间用 & 作为分隔符。

HTTP 请求
客户端发送一个 HTTP 请求到服务器,一个 HTTP 请求一般包含 4 个部分:请求行、请求头部、空行和

请求数据。如下图:

以下为 GET 请求报文:

GET /index.html?a=1&b=2 HTTP/1.1
Host: localhost.charlesproxy.com:3000
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like
Gecko) Chrome/74.0.3729.131 Safari/537.36

 

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/ *;q=0.8,
application/signed-exchange;v=b3
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Cookie: _ga=GA1.2.448607888.1557887884; _gid=GA1.2.2022442462.1557887884 Connection: keep-alive

 

请求说明:
第一部分:第 1 行为 请求行,用来说明请求类型 ( GET ),要访问的资源( /index.html?a=1&b=2 )

以及所使用的 HTTP 版本( HTTP/1.1 )。 第二部分:请求头部,紧接着请求行(即第一行)之后的部分,用来说明服务器要使用的附加信息。

HOST :服务器的域名。
User-Agent :浏览器的浏览器身份标识字符串。 Accept:能够接受的回应内容类型( Content-Types )。参⻅内容协商。 Accept-Encoding:能够接受的编码方式列表。参考HTTP压缩。 Accept-Language:能够接受的回应内容的自然语言列表。参考 内容协商 。 Cookie:之前由服务器通过 Set- Cookie 发送的一个 超文本传输协议 Cookie。 Connection:该浏览器想要优先使用的连接类型。

第三部分:空行,请求头部后面的空行是必须的。即使第四部分的请求数据为空,也必须有空行。

第四部分:请求体,因为这次请求为 GET,请求的参数保存在请求行的 URL 中。即使是没有数据也必须 有空行。

以下为 POST 请求报文:

POST /users/login HTTP/1.1
Host: localhost.charlesproxy.com:3000
Content-Length: 43
Accept: application/json, text/plain, */*
Origin: http://localhost.charlesproxy.com:3000
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.131 Safari/537.36
Content-Type: application/json;charset=UTF-8
Referer: http://localhost.charlesproxy.com:3000/index.html
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Cookie: _ga=GA1.2.448607888.1557887884; _gid=GA1.2.2022442462.1557887884 Connection: keep-alive

 

{"username":"zhangsan","password":"111111"}

请求说明:

第一部分:请求行,第一行明了是 POST 请求,以及 HTTP 1.1 版本。 第二部分:请求头部,第二行至第十二行。用来说明服务器要使用的附加信息。 第三部分:空行,第十三行的空行。 第四部分:第十四行,向服务器传递的请求数据。

 

GET 和 POST 请求的区别 1. 传输数据的存放位置

GET 提交,请求的数据会附在 URL 之后(就是把数据放置在 HTTP 协议头中),以 ? 分割 URL 和传输 数据,多个参数用 & 连接。

例如: login.action?name=hyddd&password=idontknow&verify=%E4%BD%A0%E5%A5%BD

如果数据是英文字母或者数字,原样发送,如果是空格,转换为 + ,如果是中文或者其他字符,则直接 把字符串用 BASE64 加密,得出如: %E4%BD%A0%E5%A5%BD ,其中 %XX 中的XX为该符号以 16 进制表 示的 ASCII 码。

POST 提交:把提交的数据放置在是 HTTP 包的包体中。上面 POST 请求示例中,空行下面的字符串就 是实际传输的数据。

因此,GET 提交的数据会在地址栏中显示出来,而 POST 提交,地址栏不会改变。 2. 传输数据的大小

首先声明:HTTP 协议没有对传输的数据大小进行限制,HTTP 协议规范也没有对 URL 长度进行限制。 而在实际开发中存在的限制主要有:

GET:特定浏览器和服务器对URL长度有限制,例如 IE 对 URL ⻓度的限制是 2083 字节(2K+35)。对 于其他浏览器,如 Netscape、FireFox 等,理论上没有长度限制,其限制取决于操作系统的支持。

因此对于 GET 提交时,传输数据就会受到 URL 长度的限制。
POST:由于不是通过 URL 传值,理论上数据不受限。但实际上各个 Web 服务器会规定对 POST 提交

数据大小进行限制,Apache、IIS6 都有各自的配置。 3. 安全性

POST 的安全性要比 GET 的安全性高。因为通过 GET 提交的数据,用户名和密码将明文出现在 URL 上。然而登录页面可能被浏览器缓存,或者其他人通过查看浏览器历史记录的形式,就能拿到你的账号 和密码。

HTTP 请求方法
根据 HTTP 标准,HTTP 请求可以使用多种请求方法。

HTTP1.0 定义了 3 种请求方法: GET, POST 和 HEAD方法。 HTTP1.1 新增了 5 种请求方法: OPTIONS, PUT, DELETE, TRACE 和 CONNECT 方法。

GET 请求指定的页面信息,并返回实体主体。
HEAD 类似于 get 请求,只不过返回的响应中没有具体的内容,用于获取报头
POST 向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。 POST 请求可能会导致新的资源的建立和/或已有资源的修改。
PUT 从客户端向服务器传送的数据取代指定的文档的内容。
DELETE 请求服务器删除指定的页面。
CONNECT HTTP/1.1 协议中预留给能够将连接改为管道方式的代理服务器。
OPTIONS 允许客户端查看服务器的性能。
TRACE 回显服务器收到的请求,主要用于测试或诊断。

 

HTTP 响应
一般情况下,服务器接收并处理客户端发过来的请求后,会返回一个 HTTP 的响应消息。HTTP 响应也

由 4 个部分组成,分别是响应行、响应报头、空行和消息体。如下图:

下面是一个 HTTP 响应的例子:

HTTP/1.1 200 OK
Date: Fri, 22 May 2009 06:07:21 GMT Content-Type: text/html; charset=UTF-8 Server:Apache Tomcat/4.0-b1(HTTP/1.1Connector) Conection:close

 

<html>
    <head></head>

<body>
<!--body goes here-->

    </body>
</html>

第一部分:响应行,由 HTTP 协议版本号,状态码,状态描述这 3 个部分组成。 该例子中 HTTP/1.1 表 明 HTTP 版本为 1.1 版本,状态码为 200,状态消息为 OK

第二部分:消息报头,用来说明客户端要使用的一些附加信息。 该例子中第二行和第三行为消息报头。 Date 代表生成响应的日期和时间;Content-Type 指定了 MIME 类型的 HTML(text/html),编码类型是 UTF-8;Server 描述了服务器的版本信息;Conection 表示连接已经关闭。

第三部分:空行,消息报头后面的空行是必须的。 第四部分:响应正文,服务器返回给客户端的文本信息。空行后面的 html 部分为响应正文。

状态码

 

状态代码由三位数字组成,第一个数字定义了响应的类别,共分五种类别:

1xx:指示信息--表示请求已接收,继续处理 2xx:成功--表示请求已被成功接收、理解、接受 3xx:重 定向--要完成请求必须进行更进一步的操作 4xx:客户端错误--请求有语法错误或请求无法实现 5xx:服 务器端错误--服务器未能实现合法的请求

常用状态码:

200 OK
400 Bad Request
401 Unauthorized 域一起使用
403 Forbidden
404 Not Found
500 Internal Server Error 503 Server Unavailable

 

//客户端请求成功 //客户端请求有语法错误,不能被服务器所理解 //请求未经授权,这个状态代码必须和WWW-Authenticate报头

//服务器收到请求,但是拒绝提供服务 //请求资源不存在,eg:输入了错误的URL //服务器发生不可预期的错误 //服务器当前不能处理客户端的请求,一段时间后可能恢复正常

更多状态码:http://www.runoob.com/http/http-status-codes.html 查看 HTTP 请求与响应

在了解了 HTTP 协议的基本知识后,最后我们来看一看如何在浏览器中查看 HTTP 请求以及响应。 这里我们先使用 Node.js 创建一个 Web 服务器,代码如下:(代码具体含义目前不需要关心) server.js

let htmlStr = ` <!DOCTYPE html> <html lang="en"> <head>

 

<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title>

</head>
<body>

<h1>this is a test</h1>
<p>Lorem ipsum dolor sit amet.</p> <ul>

        <li>apple</li>
        <li>banana</li>
        <li>pear</li>
        <li>orange</li>
        <li>watermelon</li>
    </ul>
</body>
</html>
`;
let http = require('http'); http.createServer(function (req, res) {

 

res.writeHead(200, { 'Content-Type': 'text/html' }); res.write(htmlStr);
res.end();

}).listen(3000);
console.log("HTTP server is listening at port 3000.");

接下来在 Google 浏览器中,打开开发者工具,选择 Network 通过 localhost:3000 来进行访问:

在 Network 中会记录下发送 HTTP 请求的次数,以及响应码。点击文件的名字,就可以查看到 HTTP 请 求和 HTTP 响应的具体信息。

更多 HTTP 的相关知识,可以访问这篇博客:https://www.cnblogs.com/rayray/p/3729533.html HTTP 事务

HTTP 事务
HTTP 事务用来描述一次完整的从请求到响应的过程:

 

1 到用户发起请求时,首先进行域名解析

2 拿到域名所对应的 IP 地址之后,通过 TCP 协议建立与服务端的通信连接。( 三次握手,建立连接 )

3 建立TCP连接后发起http请求,服务接收到用户请求之后,进行业务处理,随后将请求之后的结果返 回给浏览器

4 浏览器接收到后台的数据

总结:(域名解析 --> 发起TCP的3次握手 --> 建立TCP连接后发起http请求 --> 服务器响应http请求,浏 览器得到html代码 --> 浏览器解析html代码,并请求html代码中的资源(如js、css、图片等) --> 浏览 器对页面进行渲染呈现给用户)

 

posted @ 2020-06-23 21:32  昨夜小楼又东风。  阅读(146)  评论(0编辑  收藏  举报