HTTP
文章目录
理解HTTP协议
HTTP 协议 , 也叫超文本传输协议 , 是一个使用非常广泛的应用层协议
应用层协议 , 经常是需要进行 “自定义协议” 的.
HTTP 之所以应用非常广泛 , 主要原因就是 HTTP 可定制性非常强
但是 , 我们什么时候会用到HTTP 协议呢?
主要你在上网 , 就在使用
- 浏览器打开一个网页
- 手机app 从网络上加载一份数据
- 打开游戏,游戏的一些界面
等等
HTTP 是一个 "一问一答"这种形式的协议
一个请求 - > 一个响应
HTTP协议是一个应用层协议
HTTP 请求发送出去后, 就需要从应用 层到物理层 , 层层封装
接收方收到之后 , 再从物理层到应用层层层分用 , 最终才能够完成传输
学习HTTP协议 , 最主要就是认识HTTP的报文协议格式 , 需要借助抓包工具来把HTTP协议给显示出来 , 抓包工具就相当于一个 " 代理" , 借助这样的代理 , 就可以看到网络数据
HTTP协议报文格式
以下使用fiddler 抓包工具
所谓的HTTP 请求 , 其实就是通过代码 , 构造出一个符合 HTTP格式要求的字符串 , 往 tcp 的 socket 中写
一个HTTP 请求数据 , 包含了4个部分:
1.首行
2.header
3.空行 是header 的结束标记
4.正文(body) 空行后面的内容 , 有的时候可以没有
响应: 响应很可能是压缩过的 , 本身http 是文本 , 压缩成了二进制
我们将响应进行解压缩
HTTP响应 , 就是这个要显示的 html 的本体 , 浏览器拿到这个 HTTP 响应 , 也就拿到了里面的 html 就可以显示了
HTTP请求
GET方法和POST方法
GET : “从服务器这里拿个东西”
POST : “往服务器里提交个东西”
天下HTTP 请求分十斗 ,GET请求独占八斗 , POST占一斗 , 剩下请求共分一斗
一般看到的请求大部分都是GET , 什么时候能看到POST呢?
1.登录的时候
2.上传文件的时候
GET POST 表示的是不同的意思 , 但实际上也并非需要严格遵守
对于body , GET 也可能有 body , 非常少见 . POST也可以没有body , 非常少见
GET 和 POST 的区别:
- GET 习惯上用来表示 " 获取一个数据",POST用来表示 “提交一个数据”
- GET 一般没有body ,需要携带数据则放到URL,通过query string 传递 , POST 一般有body,需要传递的数据通过body传递
- GET请求通常会涉及成幂等的 , POST 则无要求
- GET 可缓存的(前提是幂等),POST则不能
- GET 请求可以被浏览器收藏 , POST不能
幂等: 数学上的术语.
如果输入一定 , 得到的输出也一定 , 这种情况就可以认为是幂等的
幂等性 , 在服务器开发中也是很关键的.
设计成幂等之后 , 这样的请求就可缓存了
补充说明:
- 关于语义:GET完全可以用于提交数据,POST也完全可以用于获取数据
- 关于幂等性:标准建议GET实现为幂等的. 实际开发中GET也不必完全遵守这个规则
- 关于安全性:有些资料说"POST比GET请求安全" . 这样的说法是不科学的.是否安全取决于前端在传输密码等敏感信息时,是否进行加密,和GET和POST无关
- 关于传输数据量:有的资料说:GET传输的数据量小,POST传输数据量大",这个也是不科学的,标准没有规定GET的URL的长度,也没有规定POST的body长度,传输数据量多少,完全取决于不同浏览器和不同服务器之间的实现区别
- 关于传输数据类型:有的资料上说"GET只能传输文本数据,POST可以传输二进制数据",这个也是不科学的.GET的query string 虽然是无法直接传输二进制数据,但是可以针对二进制数据进行url encode
其他方法
- PUT与POST相似,只是具有幂等特性,一般用于更新
- DELETE删除服务器指定资源
- OPTIONS返回服务器所支持的请求方法
- HEAD类似于GET,只不过响应体不返回,测试的时候会用到这个
- CONNECT预留,暂无使用
URL
URL 唯一的资源定位符 , 描述了网络上的唯一的一个资源
严格来说 , 这个概念并非是HTTP里面的概念 , 跟多协议都会用到URL ,MySQL , jdbc 就用过URL
针对于URL 来说 , 结构大概是这几个部分 :
协议名://ip:端口号/带层次的路径?查询字符串
请求报头header
header 的整体的格式也是"键值对"结构
每个键值对占一行 . 键和值之间使用 冒号空格 来分割
header 中的键值对, 大部分都是HTTP 协议规定的 , 当然这里也是可以添加自定义的键值对
Host
表示服务器主机的地址和端口
Content-Type
描述了body的数据格式
Content-Length
描述了body的长度(字节)
User-Agent UA
用户使用的客户端是什么样子的
UA主要描述了浏览器是什么版本,系统是什么版本
UA 现在一个重要用途,就是区分用户是 手机/PC/平板
Referer
描述了当前这个页面 , 从哪个页面跳转来的
如果直接在地址栏输入 url , 或者直接通过收藏夹访问页面时 , 此时请求中没有 Referer的
Cookie
Cookie 的本质,是浏览器在本地存储 用户自定义数据的一种关键机制
Cookie 中存储了一个字符串 , 这个数据可能是客户端(网页)自行通过JS写入的 , 也可能是来自于服务器(服务器在HTTP 响应的 header 中通过 Set-Cookie 字段给浏览器返回数据)
-
Cookie从哪里来
从服务器来的 . 当我们的浏览器访问服务器的时候 , 服务器会在HTTP 响应中 , 通过Set-Cookie 字段 , 把 Cookie 的键值对 , 返回给浏览器 , 浏览器收到这个数据 , 就会在本地存储
-
Cookie 到哪里去
会在下次请求的时候 , 把 Cookie带给服务器
Cookie 在浏览器这边 , 只能算是"暂存" , 真正要让这个数据发挥作用 , 还得由服务器来使用
-
Cookie有啥用
是浏览器本地存储数据的机制
存的数据不一定非得是角色 , 任何想存的数据都行(前提是字符串)
Cookie 这里最典型的应用 , 就是存储用户的身份信息,(用户登录之后,身份)
理解登录过程:
HTTP 响应
版本号(和请求相同)
状态码 数字 , 数字来表示这次请求执行成功还是失败 , 失败的原因
状态码的描述 通过一个或者一组单词,描述这个状态码的含义
HTTP 中提供的状态码 , 是非常多的
但是常用的就几个:
200 OK 表示的是请求成功
404 Not Found 表示要访问的资源不存在
403 Forbidden 访问被拒绝(没有权限)
500 Internal Server Error 服务器内部错误 (你的服务器bug 了 , 抛了异常没有catch到就会 500)
504 Gateway Timeout 服务器访问超时了 , 浏览器给服务器发送请求 , 服务器要返回响应 , 结果服务器迟迟没有响应
302 Move temporarily 临时重定向 不确定下次要不要继续重定向
301 Moved Permanently 永久重定向 以后都重定向了
重定向就是访问旧的地址 , 被在自动引导到新的地址上
状态码分类:
类别 | 原因 | |
---|---|---|
1XX | Informational(信息性状态码) | 接收的请求正在处理 |
2XX | Success(成功状态码) | 请求正常处理完毕 |
3XX | Redirection(重定向状态码) | 需要进行附加操作以完成请求 |
4XX | Client Error(客户端错误状态码) | 服务器无法处理请求 |
5XX | Server Error(服务器错误状态码) | 服务器处理请求出错 |
构造HTTP 请求
-
直接通过浏览器地址栏 , 输入一个URL -> 构造出一个 GET 请求
-
HTML 中 , 一些特殊标签 , 也会触发 GET 请求
1)link
2)script
3)img
4)a
比如 , 有个页面中 , 有一个 img 标签
此时当页面被加载好之后 , 浏览器就会根据 img 标签的 src 属性 给服务器发起一个 GET请求 来获取到图片内容
-
form 表单 , 可以触发GET 和POST请求
通过 form 表单构造 HTTP 请求
通过 ajax 构造 HTTP 请求
ajax 是现在最主流的前后端交互方式之一
<script>
$.ajax({
url: "https://www.sogou.com",
type: "get", //可以写作post,put,delete等
data:"这是 body",
contentType:"text/plain",
success: function(body) {
//写处理响应代码
console.log(body);
}
});
</script>
ajax 虽然有许多优势 , 但是有一个非常重要的问题
跨域问题 : 这个问题不是bug , 而是浏览器为了限制安全问题 , 引入的保护机制 (为了防止 a 网站的页面请求 b 网站的数据)
现在运行 ajax 代码的页面的域名是 abc.com
但是 ajax 里的请求 , 访问的域名是 def.com
这两个域名不一致的话 , 哪怕服务器给你响应了数据,浏览器还是不能处理,还是会报错
postman 工具构造HTTP请求
使用postman 工具