1. 什么是http协议?
2. 如何理解应用层协议?
3. http协议格式
4. http请求
5. http响应
6. 通过form表单构造http请求
1. 什么是http协议?
HTTP协议(全称为”超文本传输协议”), 是一个应用十分广泛的应用层协议, http协议通常运行在TCP协议之上, 它指定了客户端可能发送给服务器什么样的消息以及得到什么样的响应.
我们通过浏览器打开任意一个网站, 此时就需要通过http协议来传输数据.
例如, 我们在浏览器中输入”www.baidu.com”, 按下回车, 此时, 我们的浏览器就会向百度服务器发送一个申请访问页面的http请求, 紧接着百度就会返回一个http响应, 然后浏览器对响应结果进行解析, 并将解析出来的结果显示在屏幕上, 此时, 我们就可以访问这个网站了.
2. 如何理解应用层协议?
我们已经知道, TCP/IP协议可以在网络中进行路径选择, 从而跨网络进行数据传输, 可是, 在数据传输完成后, 我们还需要对这些数据进行加工处理或使用, 因此, 在网络层和传输层之上, 还需要有一层协议来规定数据传输完成后的应用细节, 这一层协议就是应用层协议.
举个例子, 我们在网上买了一件商品, 此时, 快递公司会将商品从卖家手中传递到我们手中, 这就是网络层和传输层协议实现的功能, 而我们拿到商品之后, 也拿到了这件商品的使用说明, 这里的使用说明就可以简单理解为应用层协议.
对于不同的应用, 需要实现的应用层协议也不同, 而http协议就是应用层协议中最经典的协议.
3. http协议格式
要想深入理解http协议, 我们可以对其进行抓包, 分析出HTTP请求/响应的细节.
这里我选择的抓包工具是fiddler(下载地址: https://www.telerik.com/fiddler/)
通过抓包工具, 我们就可以看到http请求和响应的具体内容.
- 如果左侧页面内的数据包过多, 可以Ctrl + A全选, 再按下delete键清除所有结果.
- 请求和响应的详细数据, 可以通过右下角的 View in Notepad 通过记事本打开
抓包工具的原理:
抓包工具相当于一个代理, 当我们访问浏览器时, 浏览器会将http请求发送给抓包工具, 抓包工具再转发给对应的服务器, 当服务器返回数据时, 又会先将数据发送给抓包工具, 抓包工具会返回给客户端, 这样, 抓包工具就会清楚地知道客户端和服务器之间进行数据交互的细节.
HTTP协议格式
4. http请求
URL基本格式:
URL(Uniform Resource Locator, 统一资源定位符), 就是我们平时俗称的网址.
在互联网中. 每个文件都有一个唯一的URL, 它包含的信息指出了当前文件的位置以及浏览器的处理方式.
URL的基本格式如下:
HTTP请求格式:
认识方法(method)
:
方法 | 说明 |
---|---|
GET | 获取资源 |
POST | 传输实体主体 |
PUT | 传输文件 |
HEAD | 获得报文首部 |
DELETE | 删除文件 |
OPTIONS | 询问支持的方法 |
TRACE | 追踪路径 |
CONNECT | 要求用隧道协议连接代理 |
LINK | 建立和资源之间的关系 |
UNLINE | 断开连接关系 |
日常开发中, 我们最常用到的方法是GET和POST
GET方法:
- GET 是最常用的 HTTP 方法. 常用于获取服务器上的某个资源
- 在浏览器中直接输入 URL, 此时浏览器就会发送出一个 GET 请求
- HTML 中的 link, img, script 等标签, 也会触发 GET 请求
GET请求的特点:
- 首行的第一部分为GET
- URL 的 query string 可以为空, 也可以不为空
- header 部分有若干个键值对结构
- body 部分为空
POST方法:
POST 方法也是一种常见的方法. 多用于提交用户输入的数据给服务器(例如登陆页面). 通过 HTML 中的 form 标签可以构造 POST 请求, 或者使用 JavaScript 的 ajax 也可以构造 POST 请求.
POST请求的特点:
- 首行的第一部分为 POST
- URL 的 query string 一般为空 (也可以不为空)
- header 部分有若干个键值对结构.
- body 部分一般不为空. body 内的数据格式通过 header 中的 Content-Type 指定. body 的长度由 header 中的 Content-Length 指定
面试题:GET方法和POST方法的区别是什么?
- 语义不同: GET 一般用于获取数据, POST 一般用于提交数据.
- GET 的 body 一般为空, 需要传递的数据通过 query string 传递, POST 的 query string 一般 为空, 需要传递的数据通过 body 传递
- GET 请求一般是幂等的, POST 请求一般是不幂等的. (如果多次请求得到的结果一样, 就视为 请求是幂等的).
认识请求报头(header):
header整体是键值对结构, 每个键值对占一行
报头的种类有很多, 我们仅介绍几个常见的:
- Host:表示服务器主机的地址和端口.
- Content-Length:表示 body 中的数据长度.
- Content-Type:表示请求的 body 中的数据格式.(常见选项:application/x-www-form-urlencoded: form 表单提交的数据格式, multipart/form-data: form 表单提交的数据格式, application/json: 数据为 json 格式)
- User-Agent:表示浏览器/操作系统的属性
- Referer:表示这个页面是从哪个页面跳转过来的
- Cookie:Cookie 中存储了一个字符串, 这个数据可能是客户端(网页)自行通过 JS 写入的, 也可能来自于服务器(服 务器在 HTTP 响应的 header 中通过 Set-Cookie 字段给浏览器返回数据), 往往可以通过这个字段实现 “身份标识” 的功能
5. http响应
认识状态码:
状态码表示访问一个页面的结果. (是访问成功, 还是失败, 还是其他的一些情况)
以下为常见的状态码:
- 200 OK: 这是一个最常见的状态码, 表示访问成功.
- 404 Not Found: 找不到资源
- 403 Forbidden: 表示访问被拒绝. 有的页面通常需要用户具有一定的权限才能访问(登陆后才能访问). 如果用户没有登陆, 就可能出现 403.
- 405 Method Not Allowed: 是对方的服务器不一定支持当前HTTP请求的方法(或者不允许用户使用一些其他的方法)
- 500 Internal Server Error: 服务器出现内部错误. 一般是服务器的代码执行过程中遇到了一些特殊情况(服务器异常崩溃)
- 504 Gateway Timeout: 当服务器负载比较大的时候, 服务器处理单条请求的时候消耗的时间就会很长, 就可能会导致出现超时的情况
- 302 Move temporarily: 临时重定向(重定向即跳转到另一个页面)
- 301 Moved Permanently: 永久重定向. 当浏览器收到这种响应时, 后续的请求都会被自动改成新的地址
认识响应报头(header):
响应报头的基本格式和请求报头的格式基本一致. 类似于 Content-Type , Content-Length 等属性的含义也和请求中的含义一致
Content-Type:
响应中的 Content-Type 常见取值有以下几种:
- text/html : body 数据格式是 HTML
- text/css : body 数据格式是 CSS
- application/javascript : body 数据格式是 JavaScript
- application/json : body 数据格式是 JSON
6. 通过form表单构造http请求
form (表单) 是 HTML 中的一个常用标签. 可以用于给服务器发送 GET 或者 POST 请求.
form 发送 GET 请求:
form 的重要参数:
- action: 构造的 HTTP 请求的 URL 是什么.
- method: 构造的 HTTP 请求的 方法 是 GET 还是 POST (form 只支持 GET 和 POST)
input 的重要参数:
- type: 表示输入框的类型. text 表示文本, password 表示密码, submit 表示提交按钮.
- name: 表示构造出的 HTTP 请求的 query string 的 key. query string 的 value 就是输入框的用户 输入的内容
- value: input 标签的值. 对于 type 为 submit 类型来说, value 就对应了按钮上显示的文本
构造一个GET请求:
<form action="http://abcdef.com/myPath" method="GET">
<input type="text" name="userId">
<input type="text" name="classId">
<input type="submit" value="提交">
</form>
form发送POST请求:
<form action="http://abcdef.com/myPath" method="GET">
<input type="text" name="userId">
<input type="text" name="classId">
<input type="submit" value="提交">
</form>
The End