HTTP
1.1 HTTP(超文本传输协议)
- 完成从客户端到服务器端一系列的运作流程
- web是建立在HTTP协议上通信的
- 为了解决文件传输的难题
1.2 TCP/IP
-
通常使用的网络(包括互联网)是在TCP/IP协议族的基础上运作的,HTTP属于它内部的一个子集
-
TCP/IP 是互联网相关的各类协议族的总称;TCP/IP 是指 TCP 和 IP 这两种协议。还有一种说法认为,TCP/IP 是在 IP 协议的通信过程中,使用到的协议族的统称
-
TCP/IP 协议族有4层:应用层、传输层、网络层和数据链路层
-
应用层:规定了向用户提供应用服务时通信的协议。比如,FTP(File Transfer Protocol,文件传输协议)、DNS(Domain Name System,域名系统)以及HTTP协议。
-
传输层:传输层对接上层应用层,提供处于网络连接中两台计算机之间的数据传输所使用的协议。(TCP || UDP)
1)TCP协议是全双工的,即发送数据和接收数据是同步进行的。提供可靠的字节流服务。TCP协议在建立和断开连接时有三次握手和四次挥手,因此在传输的过程中更稳定可靠但同时就没UDP那么高效了
2)UDP协议是面向无连接的,也就是说在正式传递数据之前不需要先建立连接。UDP 协议不保证有序且不丢失的传递到对端,也就是说不够稳定,但也正因如此,UDP协议比TCP更加高效和轻便。
-
网络层: 该层规定了通过怎样的传输路线到达对方计算机,并把数据包传送给对方。就跟携程提供的回家路线图作用一样。 (IP)
-
链路层:用来处理连接网络的硬件部分
-
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dUYCE1WC-1646135007512)(/Users/admin/Library/Application Support/typora-user-images/image-20211027172022151.png)]
http请求的基本过程图解:
-
发送端在层与层之间传输数据时,每经过一层时必定会被打上一个该层所属的首部信息。反之,接收端在层与层传输数据时,每经过一层 时会把对应的首部消去。
-
接收端的服务器在链路层接收到数据,按序往上层发送,一直到应用层。当传输到应用层,才能算真正接收到由客户端发送过来的 HTTP请求。
tcp三次握手的图解
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-p6UbAMKM-1646135007519)(/Users/admin/Library/Application Support/typora-user-images/image-20211027174003550.png)]
DNS 提供从域名到IP地址之间的解析服务
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bweAsLUv-1646135007525)(/Users/admin/Library/Application Support/typora-user-images/image-20211027174723780.png)]
图解:在使用 HTTP 协议通信过程中DNS服务、TCP协议、IP协议都发挥了什么作用
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-63xo6ix0-1646135007527)(/Users/admin/Library/Application Support/typora-user-images/image-20211027175525433.png)]
-
C端(客户端):
DNS:解析域名为ip地址
HTTP:生成针对目标服务器的请求报文
TCP:为了方便通信,把http请求报文分割成报文段,把每个报文段可靠的传给对方
-
中间:
IP协议:搜索对方的地址,一边中转一边传送。
-
服务器端:
TCP:从对方那里接收到的报文以原来的顺序重组
HTTP:对web端请求的内容进行处理
TCP/IP·:请求的结果向客户端回传
1.3 URI 和 URL
URL(统一资源定位符)
正是使用web浏览器等访问web页面时需要输入的网页地址
URI(统一资源标识符)
某个协议方案表示的资源的定位标识符, URL是一种URI
区别和联系
- uri和url都定义了资源是什么,但URL还定义了该如何访问资源。
- URL是一种具体的URI,是URI的子集,它不仅唯一标识资源,还提供了定位该资源的信息。
- URI 是一种语义上的抽象概念,可以是绝对的,也可以是相对的,而URL则必须提供足够的信息来定位,是绝对的。
1.4 串行连接、持久连接、管道化持久连接、http/2.0多路复用简介
最新:HTTP/2.0多路复用
每个HTTP请求都有一个序列标识符,这样浏览器可以并发多个请求,服务器接收到数据后,再根据序列标识符重新排序成不同的请求报文,而不会导致数据错乱同样,服务端也可以并发返回多个响应给浏览器,浏览器收到后根据序列标识重新排序并归入各自的请求的响应报文。并且同一个域名下的所有请求都复用同一个TCP连接,极大增加了服务器处理并发的上限。
看图区分三种链接:
如图中(a):HTTP/1.0 版本(称为串行连接或短连接、短轮询)。串行连接每次发起请求都必须建立新的tcp连接。
如图中(b):HTTP/1.1 实现并默认了所有连接都是持久连接。持久连接多个http请求可以复用同一个tcp连接,但是下次请求必须在上次响应返回之后进行。
如图中©:管道化持久连接也可以复用同一个tcp连接,并且可以不用等待发出多个http请求,但是响应必须按顺序返回。
1.5 HTTP报文
用于HTTP协议交互的信息被称为HTTP报文。客户端的HTTP报文叫请求报文,服务端的HTTP报文叫响应报文。
-
请求报文
- 请求行(请求方法、协议版本)
- 请求首部(请求URI、客户端信息等)
- 内容实体(用户信息和资源信息等,可为空)
-
响应报文
- 状态行(协议版本、状态码)
- 响应首部(服务器名称、资源标识等)
- 内容实体(服务端返回的资源信息)
请求方法
-
GET:get方法一般用于获取服务器资源
-
POST:向指定资源提交数据,请求服务器进行处理(例如提交表单或者上传文件)。数据被包含在请求本文中。这个请求可能会创建新的资源或修改现有资源,或二者皆有。
-
PUT:向指定资源位置上传其最新内容。
-
DELETE:delete方法用于删除文件
-
HEAD:head方法用于获取报文首部,不返回报文主体
-
OPTIONS:options方法用于询问请求URI资源支持的方法。
这个方法可使服务器传回该资源所支持的所有HTTP请求方法。用’*'来代替资源名称,向Web服务器发送OPTIONS请求,可以测试服务器功能是否正常运作。
状态码
2XX | 成功(这系列表明请求被正常处理了) |
---|---|
200 | OK,表示从客户端发来的请求在服务器端被正确处理 |
204 | No content,表示请求成功,但响应报文不含实体的主体部分 |
206 | Partial Content,进行范围请求成功 |
3XX | 重定向(表明浏览器要执行特殊处理) |
---|---|
301 | moved permanently,永久性重定向,表示资源已被分配了新的 URL |
302 | found,临时性重定向,表示资源临时被分配了新的 URL |
303 | see other,表示资源存在着另一个 URL,应使用 GET 方法获取资源(对于301/302/303响应,几乎所有浏览器都会删除报文主体并自动用GET重新请求) |
304 | not modified,表示服务器允许访问资源,但请求未满足条件的情况(与重定向无关) |
307 | temporary redirect,临时重定向,和302含义类似,但是期望客户端保持请求方法不变向新的地址发出请求 |
4XX | 客户端错误 |
---|---|
400 | bad request,请求报文存在语法错误 |
401 | unauthorized,表示发送的请求需要有通过 HTTP 认证的认证信息 |
403 | forbidden,表示对请求资源的访问被服务器拒绝,可在实体主体部分返回原因描述 |
404 | not found,表示在服务器上没有找到请求的资源 |
405 | Method Not Allowed 当某个请求所针对的资源不支持对应的请求方法的时候 |
5XX | 服务器错误 |
---|---|
500 | internal sever error,表示服务器端在执行请求时发生了错误 |
501 | Not Implemented,表示服务器不支持当前请求所需要的某个功能 |
503 | service unavailable,表明服务器暂时处于超负载或正在停机维护,无法处理请求 |
首部字段
通用首部 | 作用(请求报文和响应报文都可能使用) |
---|---|
Cache-Control | 控制缓存的行为:no-cache (强制向服务器再次验证)、no-store (不做任何缓存)、max-age=111111 (资源可缓存最大时间 秒)、public (客户端、代理服务器都可利用缓存)、private (代理服务器不可用缓存) |
Connection | 浏览器想要优先使用的连接类型: keep-alive close (开启和关闭持久连接) |
Date | 创建报文时间 |
Pragma | 只用于请求报文,客户端要求中间服务器不返回缓存的资源 |
Via | 代理服务器相关信息,每经过一个代理服务器就会添加相关信息,用逗号分割 |
Transfer-Encoding | 传输编码方式:chunked 分块传输 |
Upgrade | 要求客户端使用的升级协议,需配合Connection: Upgrade 一起使用:websocket |
Warning | 缓存相关问题的警告 |
请求首部 | 作用(请求报文专用) |
---|---|
Accept | 能正确接收的媒体类型:application/json text/plain、text/javascript |
Accept-Charset | 能正确接收的字符集: unicode-1-1 |
Accept-Encoding | 能正确接收的编码格式列表:gzip deflate |
Accept-Language | 能正确接收的语言列表:zh-cn,zh;1=0.9,en,1=0.8 |
Authorization | 客户端认证信息:Bearer dSdSdFFlsfdjasd123 ,一般存token用 |
Cookie | 发送给服务器的Cookie信息 |
Expect | 期待服务端的指定行为 |
From | 请求方邮箱地址 |
Host | 服务器的域名,用于区分单台服务器多个域名的虚拟主机,是HTTP/1.1唯一必须包含的字段。 |
If-Match | 两端资源标记比较,只有判断条件为真服务端才会接受请求:If-Mach: "123456 ,和服务端文件标记比较 |
If-Modified-Since | 本地资源未修改返回 304(比较时间) |
If-None-Match | 本地资源未修改返回 304(比较标记) |
User-Agent | 客户端信息 |
Max-Forwards | 限制可被代理及网关转发的次数 |
Proxy-Authorization | 向代理服务器发送验证信息 |
Range | 请求某个内容的一部分,配合If-Range 使用 |
Referer | 请求发起页面的原始URI |
TE | 传输编码方式 |
响应首部 | 作用(响应报文专用) |
---|---|
Accept-Ranges | 告知客户端服务器是否可接受范围请求,是bytes ,否none |
Age | 资源在代理缓存中存在的时间 |
ETag | 资源标识,资源发生变化时标识也会发生改变 |
Location | 客户端重定向到某个 URL |
Proxy-Authenticate | 向代理服务器发送验证信息 |
Server | 服务器名字:Apache Nginx |
WWW-Authenticate | 获取资源需要的认证方案 |
Set-Cookie | 需要存在客户端的信息,一般用于识别用户身份 |
实体首部 | 作用(补充请求报文或响应报文相关信息) |
---|---|
Allow | 资源的正确请求方式:GET HEAD POST |
Content-Encoding | 内容的编码格式:gzip deflate |
Content-Language | 内容使用的语言:zh-CN |
Content-Length | request body 长度(即实体主体的大小): |
Content-Location | 返回数据的备用地址 |
Content-MD5 | Base64加密格式的内容 MD5检验值 |
Content-Range | 响应主体的内容范围 |
Content-Type | 内容的媒体类型(如’application/json;charset=UTF-8’则会发送预检请求) |
Expires | 内容的过期时间 |
Last_modified | 内容的最后修改时间 |
两种请求方法
浏览器发送 CORS 请求(跨域请求)时, 会将请求分为简单请求与复杂请求.
-
简单请求
- 请求的方法只能为HEAD、GET、POST
- 无自定义请求头
Content-Type
只能是这几种:
text/plain` `multipart/form-data` `application/x-www-form-urlencoded
-
复杂请求
- PUT, Delete 方法的 ajax 请求
- 发送 JSON 格式的 ajax 请求(比如post数据)
- 带自定义头的 ajax 请求
-
对比
1) 简单请求会先执行,后判断 , 流程如下:
1.1 浏览器监测到请求是CORS跨域请求,添加一个origin字段(页面源信息:协议、域名、端口)
1.2 服务端收到后作相应的处理(对比origin, 服务端判断这个源是否接受)返回结果给浏览器
1.3 浏览器检查响应头是否允许跨域信息
1.4 ✅允许, 那就当做没事发生。 ❌不允许, 浏览器抛出相应的错误信息。
2)复杂请求在发生请求时, 如果是 CORS 请求,浏览器预先发送一个 option 请求。浏览器这种行为被称之为预检请求(注意如果不是跨域请求就不会发生预检请求,比如反向代理)。
1.6 WEB服务器
虚拟主机
-
一台物理服务器(一个IP地址)虚拟出多个主机 => 每个主机映射一个独立的域名, 因此:
当用户访问域名时,DNS域名系统会将其解析成IP地址 => 根据IP找到物理服务器 => 通过请求首部的HOST字段确认对应的虚拟主机
代理服务器
客户端和服务器之间的"中间商":HTTP请求通过代理服务器转发给服务器,再将服务器的响应返回给客户端的行为。
作为缓存服务器
用来隐藏用户身份(正向代理)或服务器身份(反向代理)增加安全性
😄正向代理
- 由客户端向代理服务器发出请求,并指定目标访问服务器
- 代理服务器向源服务器转交需求,并将获得的内容返回给客户端
- 隐藏了请求的客户端身份,不知道真正发送请求的是谁。
😂反向代理
- 是客户端向反向代理发出请求
- 反向代理服务器收到需求后判断请求走向何处,然后再将结果反馈给客户端
- 隐藏了真实服务器的身份。只要知道反向代理服务器是谁就好了,我们甚至可以把反向代理服务器当做真正服务器看待
- 这种形式的代理通常被用作实现负载均衡,比如Nginx就是一种出色的反向代理服务器。
🏁!!!反向代理解决了跨域的问题:
利用的是浏览器存在同源策略,服务器之间没有。
- 本地服务在浏览器向本地代理服务器发起请求 --> 本地代理服务器转发 --> 目标服务器 --> 代理服务器获取到目标服务器的响应数据后返回给浏览器数据
1.7 HTTPS
HTTP没有保密性,所以传输数据相当于在网上以明文的方式裸奔。为了解决这个问题,出现了各种加密技术。
-
对称加密
- 唯一密钥:key1可用来加密也可用来解密
- 需要双方都拥有密钥key1
- 如果第一次传输密钥被第三方截获就玩完。
-
非对称密钥
- 公钥
key3
和私钥key2
都可用于对应的加密和解密 - 服务端生成一对密钥,私钥保存在服务端,公钥给客户端用。
- 非对称密钥在加密和解密中使用不同密钥,所以叫非对称密钥
- 客户端的明文通过公钥加密后的密文需要用私钥解密。
- 无需在客户端和服务端之间共享密钥,只要私钥不发给任何用户,即使公钥在网上被截获,也无法被解密,仅有被窃取的公钥是没有任何用处的。
- 公钥
-
混合加密
-
服务端:用(非对称加密的私钥key2)加密(对称加密的密钥
key1
)传给客户端 -
客户端:用(非对称加密的公钥
key3
)解密出(对称加密的密钥key1
) -
双方都有了key1,开始利用
key1
加密通信。!!! 缺点:黑客可以自己生成(非对称加密公钥)发送给客户端,而此时无法验证公钥的可信度
-
-
SSL
- 从证书认证机构申请证书(证书中含有证书签名和服务器公钥
key3
)。 - 在客户端发起HTTP请求时,服务端将证书发送给客户端。
- 客户端认证证书的真伪,然后解密出服务端公钥
key3
- 用(公钥key3)加密自己生成的(对称加密密钥
key1
)并传给服务端 - 最后利用
key1
加密进行通话
- 从证书认证机构申请证书(证书中含有证书签名和服务器公钥
优点: 至于安全性,由于私钥是机构的,可以避免第三方伪造证书。并且就算得到了服务端公钥,也无法解密出公钥key3
加密过的对称加密密钥key1
。
HTTPS基于HTTP协议,通过SSL或TLS(可以看作SSL3.0)提供加密处理数据、验证对方身份以及数据完整性保护。特点如下:
- 内容加密:采用混合加密技术,中间者无法直接查看明文内容
- 验证身份:通过证书认证客户端访问的是自己的服务器
- 保护数据完整性:防止传输的内容被中间人冒充或者篡改
HTTPS和HTTP的区别主要如下:
- HTTPS协议需要到CA(证书颁发机构)申请证书,一般免费证书很少,需要交费。
- HTTP协议运行在TCP之上,所有传输的内容都是明文,HTTPS运行在SSL/TLS之上,SSL/TLS运行在TCP之上,所有传输的内容都经过加密的。
- HTTP和HTTPS使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。
- HTTP的连接很简单,是无状态的;HTTPS协议是由HTTP+SSL协议构建的可进行加密传输、身份认证的网络协议,可以有效的防止运营商劫持,解决了防劫持的一个大问题,比HTTP协议安全。
1.8 WEB安全防范
XXS攻击(跨站脚本攻击)
-
想办法将脚本注入到页面中的攻击方法
-
两种方式:
1)通过修改浏览器URL导致脚本被注入到页面 -> 会被谷歌浏览器自动防御攻击
2)通过输入框将脚本代码注入数据库 -> 需要手动防御
推荐使用’xss’库的白名单过滤防御方法:
const xss = require('xss')
let html = xss('<h1 id="title">XSS Demo</h1><script>alert("xss");</script>')
// -> <h1>XSS Demo</h1><script>alert("xss");</script>
CSRF 攻击(跨站请求伪造)
CSRF攻击是源于Web的隐式身份验证机制. Web的身份验证机制虽然可以保证一个请求是来自于某个用户的浏览器,但却无法保证该请求是用户批准发送的
CSRF攻击的问题一般是由服务端解决,防范 CSRF 攻击可以遵循以下几种规则:
- Get 请求不用于对数据进行修改
- Cookie设置
HTTPOnly
- 接口设置禁止跨域
- 请求时附带验证信息,比如验证码或者 Token
例子:
CSRF中文名为跨站请求伪造。假如掘金有个加关注的GET接口,id参数是关注人Id,如下:
https://juejin.cn
那我只需要在我的一个页面里面写一个img标签:
<img src="https://juejin.cn" />