HTTP学习之旅(一)

98 阅读7分钟

前言

立志做前端人员的小summer,对HTTP总是浅尝辄止,一些细节东西了解的很模糊,那么就来整理一下吧😊,借助,三元大神的(建议精读)HTTP灵魂之问,巩固你的 HTTP 知识体系 - 掘金 (juejin.cn)

正文

HTTP报文结构是怎样的

什么是HTTP报文

HTTP报文是在应用程序之间发送的数据块,这些数据块将通过以一些文本形式的元信息开头,用于HTTP协议交互

  • 客户端的HTTP报文叫做请求报文
  • 服务器端的HTTP报文叫做响应报文

报文一般都是由:header+body

起始行+头部+空行+实体

请求报文

请求报文.png

起始行

在起始行中,没两个部分用空格隔开

  1. 方法+ 路径+http版本

  2. 一般用于描述,用户希望如何请求资源(采用什么措施,什么版本)

GET /home HTTP/1.1
请求头
  • 里面包含了若干属性,格式:属性:值
  • 并且他们的属性,是不区分大小写的
  • 属性里面不可以出现,空格和下划线

请求头大致分为四个类型

  • 通用首部字段
  • 请求首部字段
  • 响应首部字段
  • 实体首部字段
空行

用于区分头部实体

空行后面的全部都是实体

假如你在头部里故意加一个空行,

那么,空行后面的所有内容都会被认为是实体

实体(请求体)

就是具体的数据

HTTP可以承载很多类型的数据:HTML,图片,音频等

响应报文

起始行

响应报文的起始行和请求报文的起始行还是有区别的

http版本+状态码+原因

http1.1 200 ok

那么我们先来聊一聊状态码

状态码

RFC规定了状态码一共为3位数,一共有5类

状态码原因
1xx当前协议处于中间状态
2xx成功状态
3xx重定向状态,资源发生改变,需要重新请求
4xx请求报文有误
5xx服务端发生错误

这边详细说说几个特殊的

2xx:

  • 200:OK,请求成功的状态码,这个我们通常用于请求会数据,会在响应体里面放数据

  • 204:no content,也是表示请求成功,但是他是没有实体的,也就是,没有数据

  • 206:partial Content,用于HTTP分块下载和断点继承

    一般用于解决:

    • 大文件的下载问题
    • CDN和原始HTTP服务器问题

3xx:

  • 301:表示永远重定向

    大概可以理解为,你这个网站的url改变了,并且原来的站点,不会再维护,而是使用一个新的站点,那么我们就可以永久重定向

  • 302:临时重定向

浏览器对于301,会进行缓存优化,当你第二次访问的时候,就会自动访问重定向的那个地址,但是,因为302是临时的,那么他是不会进行缓存的

响应头

和请求头一样,都是键值对的形式

空行

用于区分,响应头和响应实体

响应实体

影响的实体,就是服务器返回给浏览器的数据,它返回的类型一般和content-Type来决定

响应头.png

这个是由MIME类型决定的,简单说说,就是它是一种定义返回类型的东西,你这个值设置为什么类型,那么我响应体里面,相应的数据就只可以是这个类型,具体可以参考:MIME 类型 | 菜鸟教程 (runoob.com)

总结

HTTP报文结构,就是类似于Header+body这种

  • 起始行
  • 头部
    • 请求头
    • 响应头
  • 空行
  • 实体
    • 响应体
    • 请求体

HTTP的请求方法

HTTP/0.9:只有一个GET命令

HTTP/1.0:

  • GET:用于获取资源
  • HEAD:用于获取资源的元信息
  • POST:提交数据

HTTP/1.1:

  • PUT:修改数据
  • patch:打补丁式修改数据
  • OPTIONS:一般用于跨域请求
  • DELETE:删除数据
getPost有什么区别?
  • 语义上其实就有很大区别

    • get:是获取资源
    • Post:是上传资源,一种Update/Insert的感觉
  • 缓存角度

    • Get:是会被浏览器主动缓存的
    • Post不会被缓存

    首先我们先来了解一下HTTP缓存

    就是不更新服务端数据的请求

    因为我们的Get,就是直接获取数据,不会对数据进行修改,自然就不需要更新服务端数据请求了,那么就可以使用HTTP缓存

    但是因为POST,其实是将数据发送到服务器端去存储,那么肯定是会对服务器数据产生变化的,那么就不会去使用缓存

  • 编码角度

    • Get:只进行URL编码。所以只接受ASCII字符
    • POST:没有限制

    我的理解是:我们会将ASCII码进行转码,变为URL,然后进行请求,假如这时候我们使用的是非ASCII码,那么转码的时候,就没法转为对应的URL,那么请求就出错了

  • 参数角度

    • GET:将参数放在了URL里面,不安全

      其实就是那个Query

    • POST:会将数据放在请求体里面,比较安全

      浏览器像服务器发送,那么就是进行请求,数据放在响应体里面

  • 幂等性角度

    • Get:无论你请求多少次,我的数据都不会发生变化
    • Post:它是一种相当于upDate的感觉,会对服务器数据库造成修改的
  • TCP角度

    • GET:只会发送一次,它会将请求报文,一次性发出去
    • Post:会分两次进行发送,第一次发送请求头,返回100,那么我才发送请求体,然后200,返回数据,但是火狐,只会发送一次

    但是目前来说

    • 在网络状态比较好的时候,其实发送一次数据包和发送两次数据包没什么差别
    • 假如在网络差的时候,两次包的TCP在验证包完整性上,有着非常大的优势

但是在这篇文章中,作者介绍到,其实GETPOST并没有本质上的区别:99%的人都理解错了HTTP中GET与POST的区别 (qq.com)

书中介绍:

GET和POST本质上就是TCP链接,并无差别。但是由于HTTP的规定和浏览器/服务器的限制,导致他们在应用过程中体现出一些不同

  1. 无论是GET还是POST,其实他们都是属于TCP链接,所以其实GETPOST做的事情差不多
  2. 假如我们将GET上添加request body,给POST添加url参数,其实是可以的
  3. 他说,我们可以将TCP比作汽车,我们将HTTP看成是交通规则,HTTP定义了好几种服务,GETPOST
  4. Get:他要求我们将传送的数据放在车顶上
  5. Post:要求将传送的数据放在车厢里面
  6. 但是我们也完全可以在GET的时候,将数据悄悄的放在车厢里面送过去,Post的时候,完全可以在车顶放一些东西
  7. 但是在那个世界里,这么干,是不被人认可的,但是是可行的
  8. HTTP,他只是一个行为准则,但是TCP才是实现的基本

总结

其实可以将HTTP,理解为一种行为准则,她告诉你,你可以进行GET,POST,PUT,Patch操作,这是一种规范的感觉

理解URI

URI.png

举个例子:

https://www.baidu.com/s?wd=HTTP&rsv_spt=1
scheme协议,比如HTTP,HTTPSFTP啥的,后面一定需要://
user:passwd@登录主机用的信息,一般不显示出来
host:port主机名和端口号
path表示请求的路径,标记资源所在位置
query查询,key = value这种形式,用&来隔开
fragement表示定位锚点

在这边:

  • schemeHTTPS
  • host:www.baidu.com
  • port:对于http,一般都是80端口,对于https,一般都是443端口
  • path:/s
  • query:wd=HTTP&rsv_spt=1

URI编码

URI里面只可以使用ASCII,这也从另一个方面说明了get请求,只接受ASCII

因此URI引入了编码机制,它会将非ASCII码和界定符转换为十六进制字节符,在前面加上%

会将空格转变为%20

URI编码.png

那么什么是我们平时理解的URL呢?

url和uri.png

可以很形象的看出,URI比URL多了一个定位锚点