一、简介
HTTP
协议(超文本传输协议HyperText Transfer Protocol),它是基于TCP协议的应用层传输协议,简单来说就是客户端和服务端进行数据传输的一种规则。
注意:客户端与服务器的角色不是固定的,一端充当客户端,也可能在某次请求中充当服务器。这取决与请求的发起端。HTTP协议属于应用层,建立在传输层协议TCP之上。客户端通过与服务器建立TCP连接,之后发送HTTP请求与接收HTTP响应都是通过访问Socket接口来调用TCP协议实现。
HTTP
是一种无状态 (stateless) 协议, HTTP
协议本身不会对发送过的请求和相应的通信状态进行持久化处理。这样做的目的是为了保持HTTP协议的简单性,从而能够快速处理大量的事务, 提高效率。
然而,在许多应用场景中,我们需要保持用户登录的状态或记录用户购物车中的商品。由于HTTP
是无状态协议,所以必须引入一些技术来记录管理状态,例如Cookie
。
我们平时打开一个网站,就是通过HTTP来传输数据的。
当我们在浏览器中输入一个 搜狗搜索的 "网址" (URL) 时, 浏览器就给搜狗的服务器发送了一个 HTTP 请求, 搜狗的服务器返回了一个 HTTP 响应.
这个响应结果被浏览器解析之后, 就展示成我们看到的页面内容. (这个过程中浏览器可能会给服务器发送多个 HTTP 请求, 服务器会对应返回多个响应, 这些响应里就包含了页面 HTML, CSS, JavaScript, 图片,字体等信息)
HTTP:超文本传输协议(Hyper Text Transfer Protocol)——是一个简单的请求-响应协议
所谓 "超文本" 的含义, 就是传输的内容不仅仅是文本(比如 html, css 这个就是文本), 还可以是一些其他的资源, 比如图片, 视频, 音频等二进制的数据
二、 HTTP 协议格式
HTTP 是一个文本格式的协议. 可以通过 Chrome 开发者工具或者 Fiddler 抓包, 分析 HTTP 请求/响应的细节
思考问题: 为什么 HTTP 报文中要存在 "空行"?
因为 HTTP 协议并没有规定报头部分的键值对有多少个. 空行就相当于是 "报头的结束标记", 或者是 "报头和正文之间的分隔符".
HTTP 在传输层依赖 TCP 协议, TCP 是面向字节流的. 如果没有这个空行, 就会出现 "粘包问题"
三、HTTP请求详解
请求行中的URL
一个URL例子
https : 协议方案名. 常见的有 http 和 https, 也有其他的类型. (例如访问 mysql 时用的
jdbc:mysql )
mp.csdn.net: 服务器地址. 此处是一个 "域名", 域名会通过 DNS 系统解析成一个具体的 IP
端口号: 上面的 URL 中端口号被省略了. 当端口号省略的时候, 浏览器会根据协议类型自动决定使用
哪个端口. 例如 http 协议默认使用 80 端口, https 协议默认使用 443 端口.
mp_blog/creation/editor : 带层次的文件路径.
spm=1001.2101.3001.5352 : 查询字符串(query string). 本质是一个键值对结构. 键值对之间使用 & 分隔. 键和值之间使用 = 分隔
URL小结:
对于 URL 来说,它里面的结构看起来比较复杂,其实最重要的,和开发最关系紧密的,主要就是四个部分:
- 1、IP地址 / 域名
- 2、端口号(经常会被隐藏,充数的存在)
- 3、带层次结构的路径
- 4、queryString(查询字符串)
这四个最好掌握!!!!
尤其是 3 和 4 ,和我们写代码是密切相关的!
URL 的 encode / decode机制
当query string 中如果包含了特殊字符,就需要对特殊字符进行转义。
这个转义的过程,就叫做 URLencode,反之,把转义后的内容还原回来,就叫做URLdecode。
那么为什么需要进行 encode?
其实很好理解,前面也看到了,一个 URL 里面是有很多特殊的含义的符号的。
比如:
/ : ? & = …这些符号都是在 URL中具有特定含义的。
万一,queryString 里面也包含这类特殊符号,就可能导致 URL 被解析失败!
比如:我们刚才说的 ?号,是用来分割 路径 和 查询字符串。
如果前面 和 后面都存在 问号,那完蛋。
服务器收到这条请求,就懵逼了,到底那个问号后是 查询字符串?它就会产生误会。
为了消除歧义,就规定了,一旦 queryString中遇到了这些符号,就将其转义
————————————————
HTTP 请求 的 方法
前面讲 HTTP 请求部分的时候,就涉及到:GET 和 POST。
get:就是 得到 / 获得 一个东西。
POST:就是 向服务器 传递 / 发送 一个东西。
GET方法
GET 是最常用的 HTTP 方法. 常用于获取服务器上的某个资源.
在浏览器中直接输入 URL, 此时浏览器就会发送出一个 GET 请求.
另外, HTML 中的 link, img, script 等标签, 也会触发 GET 请求.
后面我们还会学习, 使用 JavaScript 中的 ajax 也能构造 GET 请求
通过Fiddler来观察
GET 请求的特点
- 首行的第一部分为 GET
- URL 的 query string 可以为空, 也可以不为空.
- header 部分有若干个键值对结构.
- body 部分为空
一个例子
关于 GET 请求的 URL 长度问题
网上有些资料上描述: get请求长度最多1024kb 这样的说法是错误的.
HTTP 协议由 RFC 2616 标准定义, 标准原文中明确说明: "Hypertext Transfer Protocol --HTTP/1.1," does not specify any requirement for URL length.
没有对 URL 的长度有任何的限制.
实际 URL 的长度取决于浏览器的实现和 HTTP 服务器端的实现. 在浏览器端, 不同的浏览器最大长度是不同的, 但是现代浏览器支持的长度一般都很长; 在服务器端, 一般这个长度是可以配置的
POST方法
POST 方法也是一种常见的方法. 多用于提交用户输入的数据给服务器(例如登陆页面).
通过 HTML 中的 form 标签可以构造 POST 请求, 或者使用 JavaScript 的 ajax 也可以构造 POST 请求
通过Fidder来观察POST请求
POST 请求的特点
首行的第一部分为 POST
URL 的 query string 一般为空 (也可以不为空)
header 部分有若干个键值对结构.
body 部分一般不为空. body 内的数据格式通过 header 中的 Content-Type 指定. body 的长度由header 中的 Content-Length 指定.
一个例子