输入URL发生了什么?
TCP建立连接为什么需要三次握手,为什么不采用两次?
- 确保建立可靠的连接。
- 防止资源浪费。防止两次握手情况下已经失效的连接请求报文段又突然发送到服务器端而发生错误。比如说:客户端A向服务器B发出TCP连接请求,第一个连接请求报文在网络的某个节点滞留,A认为该报文超时,又重新传了个报文;B收到后,和A建立了连接;数据传输完毕后,双方断开了连接。此时该滞留的连接请求报文到达了B,B认为A又发送了一次连接请求。此时如果采用的是两次握手,B认为连接已经成功建立,一直等待A传输数据,但是A此时无连接请求,不予理睬,从而造成B的资源白白浪费。如果采用的是三次握手,B向A发送SYN确认报文后,需要等待A发送ACK确认报文后才成功建立连接,但是A没有要连接,所以建立连接失败。
TCP释放连接为什么需要四次挥手,为什么不采用三次?
- 因为释放连接时,服务器端的ACK和FIN是分开的。在发送了ACK后,服务端还要处理一些数据之后才发送FIN表示同意关闭连接,而三次握手是ACK和SYN同时发送,所以会比三次握手多一次。
TCP释放连接,为什么客户端还需等待2MSL?
- 保证客户端发送的最后一个确认报文段能到达服务器。如果客户端不等待2MSL,最后一个确认报文段丢失时,服务器不能正常进入关闭状态,而此时客户端已经关闭了,无法再进行重传。
- 客户端发送完最后一个确认报文后,在这个2MSL时间中,就可以使本连接持续的时间内所产生的所有报文段都从网络中消失。这样新的连接中不会出现旧连接的请求报文。
TCP和UDP的区别
TCP
- 面向连接的、可靠的、面向字节流的传输层协议。
- 面向连接:需要三次握手建立连接。
- 可靠的:检验(检验和包括首部、数据)、序号(对每个字节都编序号)、确认(累积确认)、重传(超时、冗余ACK)。
- 面向字节流:对每个字节都编序号,UDP是对报文段编序号。
- 应用场景:在传输大量数据且对可靠性要求高的情况下。
UDP
- 无连接的、不可靠的、面向报文的传输层协议。
- 应用场景:在实时性要求高且高速传输、可靠性要求低且追求效率的情况下。
常见状态码
1xx
- 101 Switching protocol:服务器同意客户端切换协议的时候返回。(由HTTP1切换至HTTP2或者WebSocket)
2xx
- 200 OK:成功。
3xx
- 301 Moved Permanently:永久重定向。(会缓存;域名更换、从HTTP升级到HTTPS)
- 302 Found:临时重定向。(不会缓存;未登录时访问已登录页时跳转到登录页面、404后跳转到首页)
- 304 Not Modified:命中协商缓存。
4xx
- 400 Bad Request:请求错误。
- 403 Forbidden:禁止访问。(法律禁止、敏感信息)
- 404 Not Found:未找到资源。
5xx
- 500 Internal Server Error:服务器出错。
- 503 Service Unavailable:服务器繁忙。
HTTP和HTTPS的区别
HTTP
- Hyper Text Transfer Protocol
- HTTP是明文传输的超文本传输协议(定义了客户端和服务器之间交换报文的格式和方式)。
- 默认使用80端口,使用TCP作为传输层协议。
- URL以http开头。
HTTPS
- Hyper Text Transfer Protocol over SecureSocket Layer
- HTTPS是基于HTTP协议的、使用TLS/SSL协议(在http层和tcp层之间增加一层tsl/ssl层)进行加密和解密的超文本传输安全协议。
- 默认使用443端口,使用TCP作为传输层协议。
- URL以https开头。
- 请求完整过程见下图补充
HTTP方法
- GET:请求资源。
会被缓存。
只能进行URL编码,只能接受ASCII编码。
参数一般放在URL,不安全。
幂等。(执行同样的操作,结果一样)
TCP角度:将请求报文一次发出去。- POST:上传资源。
不会被缓存。
没有限制。
参数一般放在请求体,安全。
不幂等。
TCP角度:分成两个数据包,先发送header,服务器响应100Continue再发送body部分。- HEAD:类似GET,用于获取报文首部,不返回报文主体。一般用于验证URL是否有效。
- PUT:修改资源。
- DELETE:删除资源。
- OPTIONS:预检请求的时候发送。
HTTP/1.0、HTTP/1.1、HTTP/2.0、HTTP/3.0的区别
HTTP/1.1
- 持久连接
默认开启- 管道化
在同一个TCP连接上同时发送多个HTTP请求,服务器按照顺序处理。- 新增host字段
指定要发送到的IP地址和端口号。- 断点续传、并行下载
新增请求头字段Range和响应头字段Content-Range。- 引入了更多的缓存控制策略
HTTP/2.0(基于SPDY)
- 二进制分帧。
HTTP/1.x的数据传输是基于文本的,需要不断读入字节直到分隔符为止,造成HTTP队头阻塞。HTTP/2.0是基于二进制的,将数据分割成多个乱序的帧。- 多路复用
在一个TCP连接上可以传输多个数据帧。- 请求优先级
- header压缩
- 服务端推送
HTTP/3.0
- QUIC协议。(TCP协议中存在队头阻塞、连接延迟等问题;改TCP协议不实际,因为中间设备僵化、操作系统内核不易修改)
基于UDP实现重传、拥塞控制等TCP中的特性。
集成了TLS加密功能。
实现了HTTP/2.0的多路复用功能。
实现了快速握手功能。
HTTP/2.0和SPDY的区别
- HTTP/2.0支持HTTP明文传输,SPDY强制使用HTTPS。
- HTTP/2.0 header压缩算法采用HPACK,SPDY采用DEFLATE。
HTTP/1.1如何复用TCP连接
在请求头设置Connection: keep-alive。
实时通讯
短轮询
- 重复发送Http请求,查询目标事件是否完成。
- 优点:编写简单。
- 缺点:浪费带宽和服务器资源。
长轮询
- 在服务端hold住http请求(死循环或者sleep等等方式),等到目标时间发生(保持这个请求等待数据到来或者恰当的超时),返回http响应。
- 优点:在无消息的情况下不会频繁的请求。
- 缺点:编写复杂。
SSE(Server-Sent Events)
- 服务器向客户端声明,接下来要发送的是流信息。这时,客户端不会关闭连接,会一直等着服务器发过来的新的数据流,视频播放就是这样的例子。SSE 就是利用这种机制,使用流信息向浏览器推送信息。它基于 http 协议,目前除了 IE/Edge,其他浏览器都支持。它相对于前面两种方式来说,不需要建立过多的 http 请求,相比之下节约了资源。
(以上都基于HTTP)
WebSocket
- 全双工通信。
CDN
Content Delivery Network
内容分发网络
SQL注入
- 把 SQL 命令插入到请求表单或查询字符串中,最终达到欺骗服务器执行恶意的 SQL 命令。
XSS攻击
Cross-Site Scripting
- 执行恶意脚本,从而拿到用户信息并进行操作。
- 存储型:将恶意脚本存储到服务端数据库,然后在客户端执行这些脚本,从而达到攻击的效果。
- 反射型:将恶意脚本作为请求参数,由服务器返回到浏览器中执行解析。
- 文档型:劫持数据包,修改html文档。
防御措施
- 字符转义。
- 使用白名单、黑名单的方式进行过滤。
CSRF
Cross-Site Request Forgery
跨站点请求伪造
- 攻击者盗用了用户的身份,以用户的名义发送恶意请求。
防御措施
- 利用Cookie的SameSite属性。
Strict:禁止在跨域请求下携带Cookie。
Lax:只能在get方法提交表单或者a标签发送get请求下携带Cookie。
None:默认。请求会自动携带上Cookie。- 检验请求头Origin和Referer字段。
- CSRF Token。
在使用Django作为后端框架时,当浏览器向服务器请求,服务器会生成一个CSRF Token附在返回的页面中,当浏览器再次请求时必须带上这个token让服务器进行检验。一般第三方站点无法拿到这个token。