这篇博客我们来讲解HTTP协议原理部分,以便我们后续的代码编写。
HTTP协议是位于应用层上的协议,HTTP协议叫做超文本传输协议。他定义了客户端(如浏览器)与服务端之间如何通信。
所谓超文本,意思就是传输的内容不仅仅只是文本,还可以是一些其他类型的数据。比如图片、视频等等。
我们日常在浏览器输入网址进行浏览时,就是用的HTTP协议来进行数据传输。
当我们在浏览器中输入网址时,浏览器会向服务器发送一个HTTP请求,服务器处理之后会返回一个HTTP回应。这个响应被浏览器解析之后,就变成了我们想要浏览的网址页面。
我们先来认识一下HTTP协议的格式。我们用一个抓包工具来分析一下HTTP协议。
此处我们用FIddler工具来抓包。Fiddler 抓包工具的原理就相当于一个"代理",当我们在浏览器中输入一个网址时,会生成HTTP请求发送给代理,然后代理再把这个HTTP请求发送给服务器,服务器在收到请求后会生成一个HTTP响应,代理收到响应后再发送给浏览器。
Fiddler工具下载地址:Web Debugging Proxy and Troubleshooting Tools|Fiddler
首先点击此处。
然后点击此处下载即可。
打开下载好的Fiddler工具,首次使用需要设置开启https(因为当前网络使用的主要协议是https,很少使用http)。
点击Tools,点击Options。
在,弹出来的地方点击HTTPS,勾选所有蓝色框内的小框。(期间会弹出来一个证书下载框,务必下载,不然会导致无法抓包)
安装完成,接下来就可以使用Fiddler了。
我们来看看具体的HTTP请求与HTTP响应的格式。
上图就是HTTP请求协议格式。咱们来细讲一下各段。
请求行:
请求方法:HTTP的方法,获取资源和传输主体。
URL:输入的网址。
HTTP版本:使用的HTTP协议的版本号,如HTTP/1.0。
请求报头:header,里面是一行行的键值对,个数不限制。
空行:请求报头的结束标志。
请求正文:空行后面的内容都是正文,正文可以是空字符串。如果正文有内容,则在请求报头里面会有一个 Content-Length 属性来标识正文的长度。如果服务器返回了一个 html 页面 , 那么html页面内容就是在body中。
来看看实际HTTP请求中各段的样子:
上图就是HTTP响应协议格式。咱们来细讲一下各段。
状态行:
HTTP版本:使用的HTTP协议的版本号,如HTTP/1.0。
状态码:不同的状态码代表了不同的信息,例如 200 是一个最常见的状态码,还有 404 。
状态码描述:状态码对应的描述,例如状态码 200 对应的就是 OK ,404 对应的就是 Not Found。
响应报头:header,里面是一行行的键值对,个数不限制。
空行:响应报头的结束标志。
请求正文:空行后面的内容都是正文,正文可以是空字符串。是服务器返回给客户端的具体数据。
来看看实际HTTP响应中各段的样子:
前面说过,我们在浏览器中输入的网址相当于URL,URL的组成如下:
像 / ? : 等这样的字符, 已经被 url 当做特殊意义理解了. 因此这些字符不能随意出现.
比如, 某个参数中需要带有这些特殊字符, 就必须先对特殊字符进行转义。
转义的规则如下:
将需要转码的字符转为 16 进制,然后从右到左,取 4 位(不足 4 位直接处理),每 2 位 做一位,前面加上%,编码成%XY 格式
例如:
"+" 被转义成了 "%2B"
urldecode 就是 urlencode 的逆过程;这里给个工具,读者自行查看(点此查看)感受如何URLEncode。
最常用的是GET方法和POST方法。
GET方法: 用于获取服务器上的资源,在浏览器中直接输入 URL, 此时浏览器就会发送出一个 GET 请求。 POST方法: 多用于提交用户输入的数据给服务器 ( 例如登陆页面 )。通过 HTML 中的 form 标签可以构造 POST 请求 , 或者使用 JavaScript 的 ajax 也可以构造 POST 请求。
经典面试题:GET和POST的区别 1) GET一般用于获取服务器的某一资源(也就是进行查询操作),POST一般适用于提交数据给服务器(进行修改、删除和更新操作)。 2) GET 和 POST 的参数传递也是不同的,GET 请求是将参数拼加到 URL 上进行参数传递的,而 POST 是将参数写入到请求正文中传递的。 3)GET 请求一般是幂等的, POST 请求一般是不幂等的. (如果多次请求得到的结果一样, 就视为请求是幂等的)。 4)GET可以被本地缓存,而POST不能被本地缓存。 5) GET 请求的参数会保存在历史记录中,而 POST 请求的参数不会保留到历史记录中。
表示请求的 正文 中的数据格式。
表示正文的长度。
表示浏览器这个请求要访问的服务器的地址和端口。
大多数情况下,Host 中的值和 URL 中的域名是一致的;但是如果当我们访问的服务器不是直接访问,而是通过”代理“来访问的,此时 Host 和 URL 可能就不一致了(相当于 Host 是最终目标,URL是当前目标)。因此在这里 Host写一遍去确认访问的服务器是什么。
声明用户的操作系统和浏览器版本信息,通俗来讲就是表明是电脑还是手机,和版本信息。
表示当前页面是从哪个页面跳转过来的。如果直接在浏览器中输入 URL, 或者直接通过收藏夹访问页面时是没有 Referer 的。
这个方便我们进行操作。
搭配 3xx 状态码使用, 告诉客户端接下来要去哪里访问。
用于在客户端存储少量信息. 通常用于实现会话(session)的功能。
Cookie 中存储了一个字符串, 这个数据可能是客户端(网页)自行通过 JS 写入的, 也可能来自于服务器(服务器在 HTTP 响应的 header 中通过 Set-Cookie 字段给浏览器返回数据)。往往可以通过这个字段实现 "身份标识" 的功能。
Cookie是当浏览器第一次访问服务器时,服务器返回响应给浏览器的同时也附带cookie给浏览器。这样浏览器下一次再访问服务器时,带着这个cookie,此时服务器就会自动识别浏览器的身份。 Cookie一般是保存在浏览器本地上。在服务器上会保存着Session。
读者打开浏览器,点击上方的小锁。
点击之后就会出现Cookies。
进去就能看到当前保存的Cookies数据。
HTTP 中的 Connection 字段是 HTTP 报文头的一部分,它主要用于控制和管理客户 端与服务器之间的连接状态。
核心作用: • 管理持久连接:Connection 字段还用于管理持久连接(也称为长连接)。持久 连接允许客户端和服务器在请求/响应完成后不立即关闭 TCP 连接,以便在同一个连接 上发送多个请求和接收多个响应。 持久连接(长连接): • HTTP/1.1:在 HTTP/1.1 协议中,默认使用持久连接。当客户端和服务器都不明 确指定关闭连接时,连接将保持打开状态,以便后续的请求和响应可以复用同一个连 接。 • HTTP/1.0:在 HTTP/1.0 协议中,默认连接是非持久的。如果希望在 HTTP/1.0上实现持久连接,需要在请求头中显式设置 Connection: keep-alive。 语法格式: • Connection: keep-alive:表示希望保持连接以复用 TCP 连接。 • Connection: close:表示请求/响应完成后,应该关闭 TCP 连接。
状态码表示访问一个页面的结果 ( 是访问成功 , 还是失败 , 还是其他的一些情况 ...)。
以下为状态码的类别:
下面是常见的状态码:
状态码 | 含义 | 应用样例 |
---|---|---|
100 | Continue | 上传大文件时,服务器告诉客户端可以 继续上传 |
200 | OK | 访问网站首页,服务器返回网页内容 |
201 | Created | 发布新文章,服务器返回文章创建成功 的信息 |
204 | No Content | 删除文章后,服务器返回“无内容”表示操 作成功 |
301 | Moved Permanently | 网站换域名后,自动跳转到新域名;搜 索引擎更新网站链接时使用 |
302 | Found 或 See Other | 用户登录成功后,重定向到用户首页 |
304 | Not Modified | 浏览器缓存机制,对未修改的资源返回304 状态码 |
400 | Bad Request | 填写表单时,格式不正确导致提交失败 |
401 | Unauthorized | 访问需要登录的页面时,未登录或认证 失败 |
403 | Forbidden | 尝试访问你没有权限查看的页面 |
404 | Not Found | 访问不存在的网页链接 |
500 | Internal Server Error | 服务器崩溃或数据库错误导致页面无法 加载 |
502 | Bad Gateway | 使用代理服务器时,代理服务器无法从 上游服务器获取有效响应 |
503 | Service Unavailable | 服务器维护或过载,暂时无法处理请求 |
这里再说说重定向的相关状态码:
状态码 | 含义 | 是否为临时重定向 | 应用样例 |
---|---|---|---|
301 | Moved Permanently | 否(永久重定向) | 网站换域名后,自 动跳转到新域名; 搜索引擎更新网站 链接时使用 |
302 | Found 或 See Other | 是(临时重定向) | 用户登录成功后, 重定向到用户首页 |
307 | Temporary Redirect | 是(临时重定向) | 临时重定向资源到 新的位置(较少使 用) |
308 | Permanent Redirect | 否(永久重定向) | 永久重定向资源到 新的位置(较少使 用) |
关于重定向的验证,以 301 为代表。
HTTP 状态码 301(永久重定向)和 302(临时重定向)都依赖 Location 选项。
以下 是关于两者依赖 Location 选项的详细说明:
HTTP 状态码 301(永久重定向):
• 当服务器返回 HTTP 301 状态码时,表示请求的资源已经被永久移动到新的位 置。
• 在这种情况下,服务器会在响应中添加一个 Location 头部,用于指定资源的新位 置。这个 Location 头部包含了新的 URL 地址,浏览器会自动重定向到该地址。
• 例如,在 HTTP 响应中,可能会看到类似于以下的头部信息:
HTTP/1.1 301 Moved Permanently\r\n
Location: https://www.new-url.com\r\n
HTTP 状态码 302(临时重定向):
• 当服务器返回 HTTP 302 状态码时,表示请求的资源临时被移动到新的位置。
• 同样地,服务器也会在响应中添加一个 Location 头部来指定资源的新位置。浏览 器会暂时使用新的 URL 进行后续的请求,但不会缓存这个重定向。
• 例如,在 HTTP 响应中,可能会看到类似于以下的头部信息:
HTTP/1.1 302 Found\r\n
Location: https://www.new-url.com\r\n
总结:无论是 HTTP 301 还是 HTTP 302 重定向,都需要依赖 Location 选项来指定资 源的新位置。这个 Location 选项是一个标准的 HTTP 响应头部,用于告诉浏览器应该 将请求重定向到哪个新的 URL 地址。
响应报头的格式和请求报头的格式基本一致。像 Content-Type , Content-Length 等属性的含义也和请求中的含义一致。不过响应的 Content-Type 常见取值有这几种:
form (表单) 是 HTML 中的一个常用标签. 可以用于给服务器发送 GET 或者 POST 请求。
form 的重要参数 : action: 构造的 HTTP 请求的 URL 是什么。 method: 构造的 HTTP 请求的 方法 是 GET 还是 POST,如果不写默认是POST 方法(form 只支持 GET 和 POST)。 input 的重要参数 : type: 表示输入框的类型 . text 表示文本 , password 表示密码 , submit 表示提交按钮 . name: 表示构造的 HTTP 请求的 query string 的 key. query string 的 value 是输入框用户的 输入的内容 . value: input 标签的值 . 对于 type 为 submit 类型来说 , value 就对应了按钮上显示的文本。
<form action="https://www.baidu.com/" method="GET">
<input type="text" name="userId">
<input type="password" name="classId">
<input type="submit" value="提交">
</form>
抓包如下:
form 代码和 HTTP 请求之间的对应关系:
总结:
好了,到这里今天的知识就讲完了,大家有错误一点要在评论指出,我怕我一人搁这瞎bb,没人告诉我错误就寄了。