计算机网络——HTTP
输入URL返回页面的过程:首先,DNS解析域名得到IP,然后利用IP发起TCP三次握手(浏览器会随机生成一个端口去连接服务器的web80端口),然后客户端发起HTTP请求,然后服务器响应请求,返回响应数据。浏览器解析数据,渲染呈现。
HTTP常见字段。客户端发送请求的时候,用Host字段来指定服务器的域名。服务器返回数据的时候,通过Content-Length字段表明本次回应的数据长度。Connection字段最常用于客户端要求服务器使用TCP持久连接,以便其他请求复用。
HTTP协议特点。允许传输任何类型的数据,由content-type决定。明文传输,而且是无状态的,每次客户端发的数据都会被服务器认为是新的请求,上一次和这一次无关。支持cs模式。
HTTP请求报文格式,行头体。请求行,请求头,请求体。请求行包括请求方法,请求URL,使用的HTTP版本。请求头是属性名和属性值。
请求头:accept指定客户端能接受的内容类型。accept-coding指定客户端可以支持的web服务器返回内容压缩编码类型。
accept-language指定HTTP客户端用来展示返回信息所优先选择的语言。connect表示是否需要持久连接。
content-length请求头的长度。content-type请求提交的内容类型。cookie。hose客户端地址。origin目标地址。refere包含一个URL。user-agent客户端信息。
HTTP响应报文格式,状态行,响应头,响应体。状态行包含协议版本,状态码和状态描述。
HTTP状态码:1表示成功接收到客户端请求,需要客户端继续发送请求。2表示成功处理了客户端请求。3表示重定向,就是成功接收了请求,但是还需要进一步操作才能完成请求。4表示无法处理请求(客户端错误)。5表示处理请求失败(服务端错误)。
#HTTP 常见
(1)HTTP1.1是长连接,减少了TCP连接的重复建立和断开所造成的额外开销,减轻了服务器端的负载。
(2)HTTP1.1是管道网络传输,允许浏览器同时发出A请求和B请求,但是服务器还是按照顺序接收,先回应A请求,再回应B请求。要是前面的回应特别慢,后面就会有许多请求排队等着,这称为队头阻塞,会导致客户端一直请求不到数据。0
HTTP1.1相比于1.0。长连接,断电续传,新增一些以4开头的错误状态响应码,Host头处理(因为多个虚拟主机可以共享一个IP地址了)。
HTTP1.1支持长连接和请求的流水线处理,它在TCP连接上可以传送多个HTTP请求和相应,减少了建立和关闭连接的消耗和延迟。
HTTP1.0存在一些带宽浪费的现象,比如客户端只是需要某个对象的某一部分,但是服务器却将整个对象都传过来,而且不支持断点续传的功能。HTTP1.1支持只发送head信息,不携带body信息。如果服务器任务客户端有权限请求服务器,则返回100,客户端收到100然后把请求body发送到服务器。如果返回401,客户端就可以不用发送请求body了,节省了带宽。
HTTP1.0认为每台服务器绑定一个唯一的IP地址,因此,请求消息中的URL没有传递主机名。
HTTP2.0相比于1.1。
二进制的文件传输格式。
多路复用(并发响应多个客户端请求)。
头部压缩技术(HPACK算法,头信息表,只发送索引号。把头和数据分离,封装成头帧和数据帧。记录已发送的键值对防止重复发送,防止数据冗余,降低开销)。
服务端推送功能(不需要客户端发起请求)。
还有数据流。关于数据流,HTTP2的数据报不是按照顺序发送的,同一个连接里面连续的数据包,可能属于不同的回应。因此,必须要对数据包做标记,指出它属于哪一个回应。每个请求或回应的所有数据包都是一个数据流。每个数据流都标记着一个独一无二的编号,规定客户端发出的数据流编号为奇数,服务器发出的是偶数。客户端还可以指定数据流的优先级。优先级高的请求,服务器就先响应该请求。
HTTP2的问题在于,多个HTTP请求在复用一个TCP连接,下层的TCP协议是不知道有多少个HTTP请求的。所以一旦发生丢包现象就会触发重传机制,TCP连接中的所有HTTP请求都必须等待这个丢了的包被重传回来。这是基于TCP传输层的问题,所以HTTP3把TCP协议改成了UDP协议。
UDP是不可靠传输的,但是基于UDP的QUIC协议可以实现类似TCP的可靠性传输。当某个流发生丢包的时候,只会阻塞这个流,其他流不会受到影响。HTTPS要建立一个连接,要花费6次交互,先是建立三次握手,然后是TLS的三次握手。QUIC协议直接把以前的TCP和TLS的6次交互,合并成了3次,减少了交互次数。
HTTP风险:窃听(第三方获知通信内容,密码被盗)、篡改(第三方修改通信内容,垃圾广告弹出)、冒充(第三方冒充他人参与通信,冒充淘宝骗钱)。
HTTPS和HTTP的区别。HTTP是基于TCP协议的超文本传输协议,HTTPS是具有安全性的SSL加密传输协议。端口不一样,一个是80,一个是443。HTTPS需要到CA机构申请证书,花销大。要注意ssl协议也是基于TCP协议的。
HTTPS的基本原理。首先是TCP三次握手。然后客户端发送一个client hello包,告诉服务器自己可以支持的加密算法(协商加密算法)、SSL协议支持的版本、随机产生的数num1。服务器回应sever hello包,告诉客户端加密算法、确认协议版本、随机产生的数num2。然后服务器向数字证书颁发机构CA获取数字证书(自己设了公钥)传给客户端。客户端收到证书后,首先确认证书真实性,然后拿出服务器公钥,使用它加密报文,并向服务端发送随机数num3、加密通信算法改变通知(以后都用新的会话密钥)加密通信、握手结束通知和给服务端校验的摘要。接着就用三个随机数和之前协商的加密算法,算出本次通信的会话密钥(对称加密)。
(1)混合加密:非对称加密和对称加密的结合。通信之前使用非对称加密交换会话密钥,后续通信过程中全部使用对称加密的会话密钥的方式加密明文数据。
(2)摘要算法:浏览器发数据之前会先通过摘要算法算出明文对应的md5码之类的特定指纹,然后指纹和明文一起发送过去服务器。服务器用相同的摘要算法算出明文,通过对比指纹判断数据的完整性。
(3)数字证书:服务器把公钥给CA机构,CA用自己的私钥和服务器的公钥做成数字签名颁发数字证书。数字证书从服务器传到客户端。客户端通过CA公钥(事先就在浏览器或操作系统)确认证书真实性,从数字证书获取服务器公钥,使用该公钥对报文加密发送。服务器使用加密算法计算的私钥对报文解密。
考虑到性能的问题,双方在加密应用信息的时候使用的是对称加密密钥。但是这个密钥不能被泄漏,所以使用非对称加密的方式保护对称加密密钥的协商(三个随机数和加密算法)。
对称加密算法有AES和ADS。
非对称加密算法有RSA和DSA和ECDHE。(公钥,密钥,比如HTTPS)
get和post请求的不同。
功能,参数传递的方式,传输大小,安全性性。此外,从浏览器端来看,get产生一个TCP数据包,post产生两个(发送过去收到100,然后接收到之后,再次发送)。(1)get是从服务器获取数据,参数在url请求行发送,因此不太安全,url的传输大小比较小。(2)post是向服务器传送数据。参数在响应体里面传送,因此比较安全,传输大小比较大。
cookie和session是在登录进去和使用过程中起作用的,避免使用过程中每次都要重新登录。在输入账号密码登录的过程不起作用。
cookie和session的区别。cookie在浏览器,很容易被窃取。session在服务端,安全性比较高。cookie长时间保持,session短时间失效。cookie存储容量小(小于4k),session存储容量大(但是不能太大,要有删除机制)。cookie只能设置字符串,session是一个对象,属性可以是任何类型。session默认被存放在服务器的一个文件里面,不是内存,它可以放在文件、数据库、内存。session的运行依赖于session id,而session id是存放再cookie中的,也就是说,浏览器如果仅用了cookie,session也会失效,但是可以通过在url中传递session id。
网站免登录方法。
方式一:使用cookie保存用户登录信息,设置有效期,在用户下次访问时免去登录环节,直接通过cookie获取用户信息。
方式二:直接将session会话保存,用户下次访问的时候,记录使用这个session。但是,浏览器关闭,浏览器端的session会消失。当下次启动浏览器访问网站,会得到由网站自动分配的新的session。
如何做到关闭浏览器后到下次登录时session依然存在?
cookie技术详情。
HTTP协议本身无状态,不能进行登录验证,所以cookie技术对其进行扩展。服务器会在响应头添加set-cookie字段,把cookie值发送给浏览器,浏览器收到这个响应之后,就会自动把cookie保存起来。下次浏览器再发送请求的时候,会把这个cookie附带在请求头的cookie字段发给服务器。
cookie是按照域名进行存储的,从A域名得到的cookie数值只能发送会A域名。
cookie分为临时的cookie和长久的cookie。如果没设置有效期,浏览器关闭的时候就会删除这个cookie,这就是临时cookie。如果设置了有效期,浏览器会一直保存这个cookie,直到有效期到达,这就是长久cookie。
cookie技术可以把信息存储在不同对的服务器里面,并且可以实现多次请求下的数据共享。但是如果传输的信息比较多,使用cookie技术就会增加服务端程序处理的难度,因此就出现了session技术。
session技术详情。
session是一种把会话数据保存在服务端的技术。对Tomcat来说,session是一块在服务器开辟的内存空间,存储结构是ConcurrentHashMap。session是一种建立在cookie之上的通信状态保留机制,可以实现在服务端存储某个用户的一些信息。
服务器使用request对象创建一个session,将session的ID以set-cookie返回给浏览器。只要浏览器不关,每次访问服务器的时候,就会携带session的ID。服务器发现浏览器带session的ID过来,就会使用内存中与之对应的session为其服务。
服务器的session对象默认30分钟没有使用,就会自动销毁,在web.xml文件手工设置session的失效时间。
web开发中,webserver会自动的为那个用户创建一个session,提供数据存储功能(存储登录信息自动登录,和数据库就不一样,才会有session删除机制)
在HTTP通讯中,客户端发送请求,服务器接受请求并创建session会话,使用响应头返回sessionid给客户端。浏览器收到sessionid以后会保存在本地cookie。当客户端要发起第二次请求的时候,就会访问本地cookie获取sessionid放到请求头,服务器解析请求头和session配对。
session存在的问题有安全性(session劫持)、增加服务器压力、session同步。
session劫持防范。sessionID的数值只允许cookie进行设置,不能通过URL重置方式进行设置。同时要设置cookie的httponly为true。这个属性是设置是否可以通过客户端的脚本访问这个设置的cookie,可以防止这个cookie被XSS读取从而引起session劫持,同时cookie设置不会像URL重置方式那么容易获取sessionID。另一种方法就是在每个请求里面添加token,每次验证这个token,保证用户请求的唯一性。
token是服务端生成的一串字符串,作为客户端进行请求的一个令牌。当第一次登录之后,服务器生成一个token,把这个token返回给客户端。以后客户端只要带上这个token来请求数据就可以,无需再次带上用户名和密码。
token的目的就是为了减轻服务器的压力,减少频繁查询数据库,使得服务器更加健壮。
token的设置。
(1)可以用设备号/设备mac地址作为token。客户端在登录的时候获取设备mac,将其作为参数传递到服务端。服务端收到这个参数之后,就使用一个变量来接收,同时将其作为token设置到session里面。客户端每次请求的时候都要拦截,将客户端传来的token和服务端的session里的token进行对比。如果相同就放行,不同就拒绝。
(2)可以用session值作为token。客户端使用用户名和密码登录。服务端收到用户名和密码,如果正确了就在本地获取sessionID作为token返回个客户端,客户端以后带上这个请求数据就可以。这种缺点是session过期之后,客户端必须重新登录才能访问数据。
分布式系统会带来session共享的问题。同一个用户的多次请求被分发到集群的不同服务器上,就会出现取不到session用户需要重新登录验证的情况。
解决方案:
第一种,session复制和同步,tomat自带该功能。需要数据传输,有延迟,且受内存限制。
第二种,客户端cookie存储法,不安全,存储大小受限。
第三种,反向代理hash一致性。反向代理层让同一个用户的请求落在同一个服务器上。失去了nginx负载均衡的意义。
第四种,后端统一集中存储,比如数据库或缓存,需要增加一次网络调用。可以使用spring session框架,将session缓存到redis里面。使用redis和EhCache实现一级和危机缓存。
第五种,使用token的方式代替session功能,移动端没有session概念,使用token实现。token最终会存到redis,Redis-cluster分片集群中默认支持分布式共享。(最靠谱的分布式session数据一致性解决方案)
使用cookie来完成(很明显这种不安全的操作并不可靠)
使用Nginx中的ip绑定策略,同一个ip只能在指定的同一个机器访问(不支持负载均衡)
利用数据库同步session(效率不高)
使用tomcat内置的session同步(同步可能会产生延迟)
使用token代替session
我们使用spring-session以及集成好的解决方案,存放在redis中
1xx
类状态码属于提示信息,是协议处理中的一种中间状态,实际用到的比较少。
2xx
类状态码表示服务器成功处理了客户端的请求,也是我们最愿意看到的状态。
-
「200 OK」是最常见的成功状态码,表示一切正常。如果是非
HEAD
请求,服务器返回的响应头都会有 body 数据。 -
「204 No Content」也是常见的成功状态码,与 200 OK 基本相同,但响应头没有 body 数据。
-
「206 Partial Content」是应用于 HTTP 分块下载或断点续传,表示响应返回的 body 数据并不是资源的全部,而是其中的一部分,也是服务器处理成功的状态。
3xx
类状态码表示客户端请求的资源发生了变动,需要客户端用新的 URL 重新发送请求获取资源,也就是重定向。
-
「301 Moved Permanently」表示永久重定向,说明请求的资源已经不存在了,需改用新的 URL 再次访问。
-
「302 Found」表示临时重定向,说明请求的资源还在,但暂时需要用另一个 URL 来访问。
301 和 302 都会在响应头里使用字段 Location
,指明后续要跳转的 URL,浏览器会自动重定向新的 URL。
- 「304 Not Modified」不具有跳转的含义,表示资源未修改,重定向已存在的缓冲文件,也称缓存重定向,也就是告诉客户端可以继续使用缓存资源,用于缓存控制。
4xx
类状态码表示客户端发送的报文有误,服务器无法处理,也就是错误码的含义。
-
「400 Bad Request」表示客户端请求的报文有错误,但只是个笼统的错误。
-
「403 Forbidden」表示服务器禁止访问资源,并不是客户端的请求出错。
-
「404 Not Found」表示请求的资源在服务器上不存在或未找到,所以无法提供给客户端。
5xx
类状态码表示客户端请求报文正确,但是服务器处理时内部发生了错误,属于服务器端的错误码。
-
「500 Internal Server Error」与 400 类型,是个笼统通用的错误码,服务器发生了什么错误,我们并不知道。
-
「501 Not Implemented」表示客户端请求的功能还不支持,类似“即将开业,敬请期待”的意思。
-
「502 Bad Gateway」通常是服务器作为网关或代理时返回的错误码,表示服务器自身工作正常,访问后端服务器发生了错误。
-
「503 Service Unavailable」表示服务器当前很忙,暂时无法响应客户端,类似“网络服务正忙,请稍后重试”的意思。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?