目录
前言
什么是协议?就是一种规定,描述了通信双方要按照什么样的格式传输信息。而本文讲解的HTTP 也是协议中的一种。
1、HTTP 介绍
HTTP,全称为“超文本传输协议”,是一种应用非常广泛的 应用层协议!
应用层,很多时候需要程序员自定义应用层协议,也有一些现成的协议,供我们使用,其中 HTTP 就是其中的佼佼者。
我们日常的一些操作其实都涉及到 HTTP协议 运用,比如我们在浏览器打开一个网页,背后浏览器和服务器的交互,大概率使用的就是 HTTP 协议。此外,手机APP和服务器之间的交互、服务器之间的相互调用,也会使用 HTTP 协议,所以 HTTP协议 与我们的生活息息相关。
HTTP 协议是个最典型的 “一问一答”模型的协议!
比如:当我们在浏览器中输入一个 “网址”之后看到一个网页这个过程其实分为三步:
- 客户端向服务器发送 HTTP 请求
- 服务器收到后,根据请求,找到客户端想要的资源(一般是html),并把这个资源通过 HTTP响应返回给 浏览器
- 客户端收到 HTML 之后,对页面进行渲染
以上就是 HTTP 传输信息大致方式,典型的一问一答型。接下来,将重点介绍 HTTP 报文格式,也是我们学习的重点 !!
报文格式简单概括就是了描述 HTTP 请求是什么样的,响应是什么样的
在学习HTTP报文格式之前我们需要安装一下抓包工具
大家可以参考这篇安装:抓包工具简单介绍和 fiddler 安装
2、URL介绍
1)了解 URL 和 URI
URI 全称 Uniform Resource Identifier,即统一资源标志符
URL 全称 Universal Resource Locator,即统一资源定位符
什么是URL?URL 就是我们平常所说的网址,例如 https://www.baidu.com 是一个 URL,而 URI 与 URL 概念类似,只不过 URL 是 URI 的一个子集!也就是说每个 URL 都是 URI,但并非每个URI都为URL。
URI 除了URL之外还包括一个子集,叫作 URN,全称为 Universal Resource Name,即统一资源名称。URN 只为资源命名而不指定如何定位资源,例如 urn:isbn:0451450642 指定了一本书的 ISBN,可以标识这本书,但没有指定到哪里获取这本书。
在互联网中,URN 使用的非常少,几乎所有的 URI 都是 URL,所以对于一般的网页链接我们既可以称为 URI,也可以称为 URL,在日常生活中是称 URL 的多一点。
2)URL 格式
URL 的书写并不是随意书写的,它是由因特网标准RFC1738进行约定的,具体格式如下
在URL规定格式中,括号包括内容是非必要部分,例如 https://www.baidu.com 就只包含了 scheme 和 hostname 两部分。但是哪些非必要的部分,并不代表不重要,接下来我将分别介绍每一部分代表的含义。
- scheme:协议。常用的协议有 http、https、ftp等,另外 scheme 也常常被称为 protocol。
- username,passowrd:用户名和密码,有时候登陆时会显示,现在用到比较少
- hostname:主机地址,该地址可以是域名也可以是IP地址,比如 https://www.baidu.com 这个 URL 中的 hostname 就是 www.baidu.com(百度的二级域名)。
- port:端口,这个就是服务器设定的服务端口,例如 https:127.0.0.1:8080 这个 URL 中的端口就是 8080。但是有些 URL 中没有端口信息,这是使用了默认端口,例如 http 协议的默认端口是 80,https 协议的默认端口是443。
- path:路径,指的就是网络资源在服务器中的指定地址
- parameters:参数,用来指定访问某个资源时的附加信息
- query:查询,用来查询某个类资源,如果又多个资源,则用 & 隔开
- fragment:片段,是对资源描述的部分补充。
3)URL encode
在URL格式中,像 / ? : @ 等这样的字符,已经被URL当做特殊字符使用。如果 URL 中查询部分涉及到这些特殊字符,就可能导致该 URL 解析错误。
这个原理就像编程语言中的 变量名 不能是“关键字”一样。例如在java中,我们不能给一个变量起名为 ‘int’。
针对这种情况的发生,我们就会对 URL 中的特殊字符进行转义,这个转义过程就叫 URL endcode。
例,我在百度中搜索“C++”,在URL中 ‘+’ 就被转义为 “%2B”。
除了特殊字符之外,中文也会进行转义
查看转义编码网站:查看字符编码(UTF-8)
3、HTTP 协议格式
HTTP协议格式可以分为两种,HTTP请求报文格式 和 HTTP响应报文格式。
我们打开 fiddler,在浏览器访问 www.baidu.com,在 fiddler 中查看请求和响应
1)请求报文格式
我们先来看HTTP请求报文,分为四个部分
第一部分:首行
首行包括:HTTP方法+URL+版本号
- HTTP方法,也就是你想通过该请求做些什么事情,常见的方法有 GET、POST ,这些具体会在 请求头 中介绍。
- URL 请求的网址
- 版本号,一般情况下会省略
第二部分:请求头header
请求头,主要由一个个键值对组成。每一行,是一个键值对,键和值之间使用 “: ” 来分割 。
第三部分:空行
空行 代表 header 的结束的标记。一个HTTP请求的 header 可以有若干个,官方就用空行,作为 header 的结束标记,类似于链表的 null。
第四部分:正文 body
正文部分并不是所有的请求都有的,一些需要提交数据的请求中就会包含。
例如,我正在写这篇文章,我抓取该网页请求,就能看见请求中正文。
正文格式有很多格式,常见的就是json
2)响应报文格式
响应报文跟请求报文类似,也分四个部分
第一部分:首行
首行包括:版本号+状态码+状态码描述
- 版本号,与请求首行里的版本号相同
- 状态码, 描述当前请求的“状态”,例如200请求成功、404未找到
- 状态码描述 ,对状态码的解释说明
第二部分:响应头 header
与请求中header一样,都是由多个键值对组成。每个键值对占一行,键和值之间使用:空格来分割 。
第三部分:空行
header 的结束标记
第四部分:正文body
正文格式有很多中,常见的就是 json、html等,此处访问百度的响应报文中正文就是html,如果是登陆页面的话json格式的多一点。
3)协议格式总结
这里简单介绍一下协议格式,接下来具体介绍请求和响应报文内部细节。
4、HTTP 请求(Request)
请求,由客户端发往服务器,分为四部分:请求方法(Request Method)、请求的网址(Request URL)、请求头(Request Headers)、请求体(Request Body)。下面分别介绍这四部分。
1)请求方法
请求方法,用于标识请求客户请求服务端的方式,常见的请求的方法有:GET 和 POST。
① GET
GET 是最常用的 HTTP 方法,常用与获取服务器上的某个资源。GET 传递数据时,会把数据放到 URL的 query 中。例如我们在百度中搜索“java”,便发起一个GET请求,地址中就会出现若干键值对,其中一个就包含我们的输入的请求“java”。
常见的构造GET请求的场景:
- 浏览器地址栏直接输入URL
- html 里面的 link、a、img、script
- form 表单
- ajax
② POST
POST 方法也是一种常见的方法,常用于提交用户输入的数据给服务器,例如登陆页面等。
常见的构造POST请求的场景:
- HTML中from标签
- ajax
我们平常遇到的绝大部分请求是 GET 或 POST 请求。除了这个两个,还有一些请求方法如下:
方法 | 说明 | 支持的HTTP协议版本 |
GET | 获取资源 | 1.0、1.1 |
POST | 传输实体主体 | 1.0、1.1 |
PUT | 传输文件 | 1.0、1.1 |
HEAD | 获取报文首部 | 1.0、1.1 |
DELETE | 删除文件 | 1.0、1.1 |
OPTIONS | 询问支持的方法 | 1.1 |
TRACE | 追踪路径 | 1.1 |
CONNECT | 要求用隧道协议连接代理 | 1.1 |
LINK | 建立和资源之间的联系 | 1.0 |
UNLINE | 断开连接关系 | 1.0 |
2)请求的网址(Request URL)
请求网址,可以唯一确定客户端想要请求的资源,也就是URL。关于URL的各个细节,这里就不再赘述了。
3)请求头(Request Headers)
请求头也叫报头,用来说明服务器要使用的附加信息,这些信息可能不止一条,而且整体结构呈现“键值对”的格式,每个键值对占一行,键和值之间用分号分割。
这些信息的种类有很多,以下主要介绍一些重要的。
1. Host
表示服务器主机的地址和端口,通俗点就是去哪里找到服务器。
例如:在浏览器搜索www.baidu.com,发送的请求中Host的值就为www.baidu.com
一般Host的值就是 IP + 端口,这里的端口可以省略。
省略:代表默认值,HTTP 的默认值为 80,Https 的默认值为 443
2. Content-Length
表示body中的数据长度
如果发送报文没有body的话,就没有该信息
3. Content-type
表示请求的body中的数据格式。body 中的数据可以放很多中格式,对于接收方来说,解析方式是截然不同的。
常见的形式:
- application/x-www-form-urlencoded: form 表单提交的数据格式. 此时 body 的格式形如:
- multipart/form-data: form 表单提交的数据格式(在 form 标签中加上enctyped="multipart/form-data" ,通常用于提交图片/文件。body 格式形如:
- application/json: 数据为 json 格式。body 格式形如:
Content-type 更多细节:MIME types (IANA media types) - HTTP | MDN
4. User-Agent
简称UA,这是一个特殊的字符串头,可以是服务器识别客户端使用的操作系统即版本、浏览器即版本等信息。
关于 User-Agent : https://www.nowamagic.net/librarys/veda/detail/2576
5. Referer
用于标识请求是从哪个页面发送过来的,服务器可以拿到这一信息并做相应的处理,如做来源设计、防盗链处理等。
注:如果直接在浏览器中输入URL,或者直接通过收藏夹访问页面时是没有Referer的。
6. Cookie
Cookie 是浏览器在本地存储数据的一种机制。这是网站为了辨别用户,进行会话跟踪而存储在用户本地的数据。主要是用来保持本地访问会话。
例如,我们访问B站页面,并登陆我们的账号,此时服务器就会用会话保存登陆信息,当我们观看各种鬼畜视频时(在该站点访问其他页面),就会处于登陆状态,这就是 Cookie 的功劳。
4)请求体(Request Body)
请求体,一般承载的内容是 POST 请求中的表单数据,对于 GET 请求,请求体为空。
如下,我登录B站时抓取到的请求
输入账号和密码之后,点击登录,我的账号和密码加密之后就会放在请求体中发送给服务器。查看上张图会发现发送请求中 Content-type 为 application/json ,所以发送的请求体格式就为 json。
除此之外,Content-type 还可以设为 application/x-www-form-urlencoded,这样内容就会以表单数据的形式放在请求体中提交,同时 Content-type 也可设为 multipart/from-data 来上传文件。
Content-type | POST 提交数据的方式 |
---|---|
application/x-www-form-urlencoded | 表单数据 |
multipart/from-data | 表单文件上传 |
application/json | 序列化 json 数据 |
text/xml | XML 数据 |
4、HTTP响应(Response)
响应,就是由服务器返回给客户端,可以分为三个部分: 响应状态码、响应头、响应体。
1)响应状态码(Resqonse Status Code)
状态码,是一个数组。这个数字描述了当前这次请求的“状态”(成功,失败,失败的原因)
例如,我们在百度页面访问 123 这个资源(不存在),服务器就会响应一个404 Not Found。
状态码有很多种,主要分为五类:1xx、2xx、3xx、4xx、5xx
下面列举出各个分类常见的状态码
1xx:信息响应
状态码 | 说明 | 详情 |
---|---|---|
100 | 继续 | 请求者应当继续提出请求。服务器已收到请求的一部分,正在等待其余部分 |
101 | 切换协议 | 请求者已要求服务器切换协议,服务器已确认并准备切换 |
2xx:成功响应
状态码 | 说明 | 详情 |
---|---|---|
200 | 成功 | 服务器已成功处理请求 |
201 | 已创建 | 请求成功并且服务器创建了新的资源 |
202 | 已接收 | 服务器已接收请求,但尚未处理 |
203 | 非授权信息 | 服务器已成功处理了请求,但返回的信息肯来自另一个源 |
204 | 无内容 | 服务器成功处理了请求,但没有返回任何内容 |
205 | 重置内容 | 服务器成功处理了请求,内容被重置 |
206 | 部分内容 | 服务器成功处理了部分请求 |
3xx:重定向
状态码 | 说明 | 详情 |
---|---|---|
300 | 多种选择 | 针对请求,服务器可执行多种操作 |
301 | 永久移动 | 请求的网页已永久移动到新位置,即永久重定向 |
302 | 临时移动 | 请求的网页暂时跳转到其他页面,即暂时重定向 |
303 | 查看其他位置 | 如果原来的请求是POST,重定向目标文档应该通过GET提取 |
304 | 未修改 | 此处请求返回的网页未经修改,继续使用上次的资源 |
305 | 使用代理 | 请求者应该使用代理访问该页面 |
307 | 临时重定向 | 临时从其他位置响应请求的资源 |
4xx:客户端错误
状态码 | 说明 | 详情 |
---|---|---|
400 | 错误请求 | 服务器无法解析该请求 |
401 | 未授权 | 请求无法解析该请求 |
403 | 禁止访问 | 服务器拒绝此请求 |
404 | 未找到 | 服务器找不到请求的页面 |
405 | 方法禁用 | 服务器禁用了请求中指定的方法 |
406 | 不接收 | 无法使用请求的内容响应请求的页面 |
407 | 需要代理授权 | 请求者需要使用代理授权 |
408 | 请求超时 | 服务器请求超时 |
409 | 冲突 | 服务器在完成请求时发送的冲突 |
410 | 已删除 | 请求的资源已永久删除 |
411 | 需要有效长度 | 服务器不接收不含有效内容长度标头字段请求 |
412 | 未满足前提条件 | 服务器未满足请求者在请求中设置的某一个前提条件 |
413 | 请求实体过大 | 请求实体过大,超出服务器的处理能力 |
414 | 请求 URI 过长 | 请求的网址太长,服务器无法处理 |
415 | 不支持类型 | 请求格式不被请求页面支持 |
416 | 请求范围不符 | 页面无法提供请求范围 |
417 | 未满足期望值 | 服务器未满足期望请求标头字段的要求 |
418 | 彩蛋 | 愚人节笑话 |
5xx:服务器错误
状态码 | 说明 | 详情 |
---|---|---|
500 | 服务器内部错误 | 服务器遇到错误,无法完成请求 |
501 | 未实现 | 服务器不具备完成请求的能力 |
502 | 错误网关 | 服务器作为网关或代理,接收到上游服务器的无效响应 |
503 | 服务不可用 | 服务器目前无法使用 |
504 | 网关超时 | 服务器作为网关或代理,没有及时从上游服务器收到请求 |
505 | HTTP版本不支持 | 服务器不支持请求中使用 HTTP 协议版本 |
更多细节请参考官方文档:HTTP 状态码 | 菜鸟教程
2)响应头(Response Headers)
响应头,包含了服务器对请求的应答信息,如 Content-Type、Server、Set-Cookie等。下面简要介绍一些常用的响应头信息
- Date : 用于表示响应产生的时间。
- Last-Modified:用于指定资源的最后修改时间。
- Content-Encoding:用于指定响应内容的编码。
- Server:包含服务器的信息,例如名称、版本号...
- Content-Type:文档类型,指定返回的数据是什么类型,也就是响应报文 body 中的数据格式。常见有 text/html 格式为 HTML,text/css 格式为 CSS,application/javascript 格式为 Javascript,application/json 格式为 JSON。
- Set-Cookie:设置 Cookie。响应头中 Set-Cookie 用于告诉浏览器需要将次内容放置 Cookie 中,下次请求将 Cookie 带上。
3)响应体(Response Body)
响应体,也能叫正文,响应的数据都存在正文中,例如请求一个网页,正文就是网页的 HTML代码。
以上就是HTTP的一些基本原理和具体细节,大家需要好好掌握涉及到的知识点,为学习Servlet打好基础。