【计算机网络】
一、常见的 HTTP 状态码
HTTP协议状态码分类
1** | 信息,服务器收到请求,需要请求者继续执行操作 |
2** | 成功,操作被成功接收并处理 |
3** | 重定向,需要进一步的操作以完成请求 |
4** | 客户端错误,请求包含语法错误或无法完成请求 |
5** | 服务器错误,服务器在处理请求的过程中发生了错误 |
200 - OK,请求成功
201 - Created,已创建。成功请求并创建了新的资源
202 - Accepted,已接受。已经接受请求,但未处理完成
301 - Moved Permanently,资源(网页等)被永久转移到其它URL
302:Found,临时移动。与301类似。但资源只是临时被移动。客户端应继续使用原有URL
303:See Other,查看其它地址。与301类似。使用GET和POST请求查看
304 - Not Modified,未修改。所请求的资源未修改,服务器返回此状态码时,不会返回任何资源
400 - Bad Request,客户端请求的语法错误,服务器无法理解
403 - Forbidden,服务器理解请求客户端的请求,但是拒绝执行此请求
404 - Not Found,请求的资源(网页等)不存在
500 - Internal Server Error,内部服务器错误
502 - Bad Gateway,作为网关或者代理工作的服务器尝试执行请求时,从上游服务器接收到无效的响应
504 - Gateway Time-out,作为网关或者代理工作的服务器尝试执行请求时,未能及时从上游服务器(URI标识出的服务器,例如HTTP、FTP、LDAP)或者辅助服务器(例如DNS)收到响应
关于 502 和 504,更多详见:状态码502和504分析_服务重启是报502还是504-CSDN博客
二、TCP 三次握手建立连接,四次挥手断开连接
TCP(Transmission Control Protocol) 传输控制协议
三次握手:一个完整的三次握手也就是 请求---应答---再次确认 。
在TCP/IP协议中,TCP协议提供可靠的连接服务,采用三次握手建立一个连接:
位码即TCP标志位,有6种标示:SYN(synchronous建立连接) 、ACK(acknowledgement 确认) 、PSH(push传送) 、FIN(finish结束)、RST(reset重置) 、URG(urgent紧急)
Sequence number(顺序号码) 、Acknowledge number(确认号码)
第一次握手:客户端发送位码为 SYN=1,随机产生 seq number=x 的数据包到服务器,并进入SYN_SEND状态,等待服务器确认; 服务器由 SYN=1 知道客户端要求建立连接;
第二次握手:服务器收到请求后要确认连接信息,向客户端发送 ack number=x+1,ACK=1,SYN=1,随机产生seq number=y 的数据包,此时,服务器进入SYN_RECV状态;
第三次握手:客户端收到后检查ack number是否正确,即第一次发送的seq number+1,以及位码ACK是否为1,若正确,客户端会再发送ack number=y+1,ACK=1, seq number=x+1,服务器收到后确认seq number的值与ACK=1,则连接建立成功。此时,客户端和服务器进入ESTABLISHED状态,完成三次握手,客户端与服务器开始传送数据。
为什么是三次握手,而不是两次握手? 为了不浪费资源。
比如说,A 向 B 发送了第一次请求,B 也回应了 A ,向 A 发送了一次请求。但是,B 发送的报文因为某种原因丢失了,导致 A 没有收到 B 的报文。此时,A 会一直等着接收 B 的报文( B 以为自己的报文发送成功了,也一直等着接收 A 的报文),直到请求超时,A 会再发送第一次请求,要求重新建立连接。然后,成功建立连接之后,A 和 B 终于可以愉快地进行数据传输了。那么,之前没有成功的那次连接呢,很明显浪费掉了,双方都在等待,占用着 B 的资源,却没有进行数据传输。所以需要 A 再向 B 发送一个报文,保证 A 收到了 B 发送过来的报文,这也是为什么第三次握手可以携带数据了,毕竟第三次握手起到的是一个确认连接成功的作用。
四次挥手:
由于TCP连接是全双工的,因此每个方向都必须单独进行关闭。这个原则是当一方完成它的数据发送任务后就能发送一个FIN来终止这个方向的连接。收到一个 FIN 只意味着这一方向上没有数据流动,一个TCP连接在收到一个FIN后仍能发送数据。首先进行关闭的一方将执行主动关闭,而另一方执行被动关闭。
(1)客户端A发送一个FIN,用来关闭客户端A到服务器B的数据传送(报文段4)。
(2)服务器B收到这个FIN,它发回一个ACK,确认序号为收到的序号加1(报文段5)。和SYN一样,一个FIN将占用一个序号。
(3)服务器B关闭与客户端A的连接,发送一个FIN给客户端A(报文段6)。
(4)客户端A发回ACK报文确认,并将确认序号设置为收到序号加1(报文段7)。
为什么建立连接是三次握手,而关闭连接却是四次挥手呢?
这是因为服务端的LISTEN状态下的SOCKET当收到SYN报文的连建请求后,它可以把ACK和SYN(ACK起应答作用,而SYN起同步作用)放在一个报文里来发送。但关闭连接时,当收到对方的FIN报文通知时,它仅仅表示对方没有数据发送给你了;但未必你所有的数据都全部发送给对方了,所以你可以未必会马上会关闭SOCKET,也即你可能还需要发送一些数据给对方之后,再发送FIN报文给对方来表示你同意现在可以关闭连接了,所以它这里的ACK报文和FIN报文多数情况下都是分开发送的。
三、TCP 和 UDP 的区别
(1)TCP是面向连接的传输控制协议,而UDP提供了无连接的数据报服务;
(2)TCP面向字节流,UDP面向报文;
(3)TCP可靠性高,确保传输数据的正确性,不出现丢失或乱序;UDP在传输数据前不建立连接,不对数据报进行检查与修改,无须等待对方的应答,所以会出现分组丢失、重复、乱序,应用程序需要负责传输可靠性方面的所有工作;
(4)TCP是全双工连接的,既能接受数据,也能发送数据;
(5)UDP具有较好的实时性,工作效率较TCP高;
(6)UDP段结构比TCP的段结构简单,因此网络开销也小。
HTTP为什么基于TCP,而不是UDP?
HTTP使用TCP而不是UDP的原因在于(打开)一个网页必须传送很多数据,而TCP协议提供传输控制,按顺序组织数据和错误纠正。
四、HTTP请求方式有几种?其中GET和POST的区别是什么?
HTTP请求,最初设定了八种方法。这八种方法本质上没有任何区别。只是让请求,更加有语义而已。
(1)OPTIONS 返回服务器所支持的请求方法
(2)GET 向服务器获取指定资源
(3)HEAD 与GET一致,只不过响应体不返回,只返回响应头
(4)POST 向服务器提交数据,数据放在请求体里
(5)PUT 与POST相似,只是具有幂等特性,一般用于更新
(6)DELETE 删除服务器指定资源
(7)TRACE 回显服务器端收到的请求,测试的时候会用到这个
(8)CONNECT 预留,暂无使用
PS:GET用于查询,PUT、POST、DELETE用于修改。
RESTful(Representational State Transfer),中文意思是表述性状态转移(和没翻译差不多),可以理解为客户端和服务端的交互形式。
GET和POST的区别:GET和POST本质上都是TCP连接,并无差别。但是由于HTTP的规定和浏览器或服务器的限制,且不同浏览器的限制不同,导致他们在应用过程中体现出一些不同。(GET和POST都是向服务器提交数据,并且都会从服务器获取数据。)
(1)传送方式:get的参数通过地址栏(url)传送,post的参数通过报文(放在request body中)传送。
(2)传送长度:get请求在url中传递的参数是有长度限制的,而post没有。
(3)安全性:get比post更不安全,因为参数直接暴露在url中,所以不能用来传递敏感信息。
(4)编码方式:get请求只能进行url编码,而post支持多种编码方式。
(5)get请求,浏览器会主动cache,而post不会,除非手动设置。
(6)get请求的参数会被完整保留在浏览历史记录里,而post中的参数不会被保留。
(7)get产生一个TCP数据包;post产生两个TCP数据包。
对于GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200 ok(返回数据);
而对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)。
五、cookie 和 session 的区别
(1)cookie的数据存储在浏览器端,而session的数据存储在服务端。
(2)cookie的存储数量有限,只允许4KB,而session的存储数量无限制。
(3)session比cookie更安全,因为我们可以轻松访问cookie的值,但是我们无法轻松访问session的值。
(4)cookie可以设置过期时间,使cookie过期;而session无法保存永久数据,使用session-destory(),我们将会销毁会话()。
六、cookie 和 localStorage、sessionStorage 的区别
相同点:都是保存在浏览器端,且是同源的。
不同点:
(1)cookie在浏览器和服务器间来回传递;sessionStorage 和 localStorage 不会自动把数据发给服务器,仅在本地保存。
(2)存储大小限制不同: cookie数据不能超过4k;sessionStorage 和 localStorage 比 cookie 大得多,可以达到5M。
(3)数据有效期不同:
sessionStorage:仅在当前浏览器窗口关闭前有效,自然也就不可能持久保持。
localStorage:始终有效,窗口或浏览器关闭也一直保存,除非自己清除了localStorage的内容,因此用作持久保持数据。
cookie:只在设置的cookie过期时间之前一直有效,即使窗口或浏览器关闭。
若不设置时间,则表示这个cookie的生命周期为浏览器会话期间,关闭浏览器窗口,cookie就会消失。这种生命周期为浏览器会话期的cookie被称之会话cookie。会话cookie一般不存储在硬盘而是保存在内存里,当然这个行为并不是规范规定的。
若设置了过期时间,浏览器就会把cookie保存到硬盘上关闭后再打开浏览器这些cookie仍然有效直到超过设定的过期时间。对于保存在内存里的cookie,不同的浏览器有不同的处理方式。
(4)作用域不同:
sessionStorage 不在不同的浏览器窗口中共享,即使是同一个页面(即数据不共享)。
localStorage 在所有同源窗口中都是共享的(即数据共享)。
cookie 也是在所有同源窗口中都是共享的(即数据共享)。
七、HTTP 和 HTTPS 的区别
超文本传输安全协议(英语:Hypertext Transfer Protocol Secure,缩写:HTTPS,常称为HTTP over TLS,HTTP over SSL或HTTP Secure)是一种通过计算机网络进行安全通信的传输协议。HTTPS经由HTTP进行通信,但利用SSL/TLS来加密数据包。
HTTPS的主要思想是在不安全的网络上创建一安全信道,并可在使用适当的加密包和服务器证书可被验证且可被信任时,对窃听和中间人攻击提供合理的防护。
HTTPS报文中的任何东西都被加密,包括所有报头(header)和荷载。
HTTPS的信任继承基于预先安装在浏览器中的证书颁发机构(如Symantec、Comodo、GoDaddy和GlobalSign等)(意即“我信任证书颁发机构告诉我应该信任的”)。因此,一个到某网站的HTTPS连接可被信任,当且仅当:
(1)用户相信他们的浏览器正确实现了HTTPS且安装了正确的证书颁发机构;
(2)用户相信证书颁发机构仅信任合法的网站;
(3)被访问的网站提供了一个有效的证书,意即,它是由一个被信任的证书颁发机构签发的(大部分浏览器会对无效的证书发出警告);
(4)该证书正确地验证了被访问的网站(如,访问https://example.com时收到了给example.com而不是其它组织的证书);或者互联网上相关的节点是值得信任的,或者用户相信本协议的加密层(TLS或SSL)不能被窃听者破坏。
HTTPS是怎么建立连接的?
(1)客户端发送请求到服务端
(2)服务端返回公钥和证书到客户端
(3)客户端接收后会验证证书的安全性,如果通过则会随机生成一个随机数,用公钥对其加密,发送到服务端
(4)服务端接受到这个加密后的随机数后会用私钥对其解密得到真正的随机数,随后用这个随机数当做私钥对需要发送的数据进行对称加密
(5)客户端在接收到加密后的数据使用私钥(即生成的随机值)对数据进行解密并且解析数据呈现结果给客户
(6)SSL加密建立
HTTP 和 HTTPS 的区别?
(1)HTTP的URL由“http://”起始且默认使用端口80;而HTTPS的URL由“https://”起始且默认使用端口443。
(2)HTTP是不安全的,且攻击者通过监听和中间人攻击等手段,可以获取网站帐户和敏感信息等。HTTPS被设计为可防止前述攻击,并在正确配置时被认为是安全的。
八、Web安全
(1)SQL 注入
定义:SQL注入的原因,是将查询参数,直接拼接在 SQL 语句中,然后把用户输入的字符串,当作 “SQL语句” 来执行。
防御:1)采用SQL语句预编译和绑定变量,是防御SQL注入的最佳方法。2)在没有采用SQL语句预编译的场景下,可以严格检查查询参数的数据类型,还可以使用一些安全函数来防御SQL注入。
(2)XSS 攻击
定义:XSS(Cross Site Scripting跨站脚本):XSS定义的主语是“脚本”,是一种跨站执行的脚本,也就是Javascript脚本,指的是在网站上注入Javascript脚本,执行非法操作。
防御:1)对用户表单输入的数据进行过滤,对 Javascript 代码进行转义,然后再存入数据库。 2)在信息的展示页面,也要进行转义,防止 Javascript 在页面上执行。
(3)CSRF 攻击
定义:CSRF(Cross-site request forgery跨站请求伪造):CSRF定义的主语是“请求”,是一种跨站的伪造的请求,指的是跨站伪造用户的请求,模拟用户的操作。
防御:1)所有需要用户登录之后才能执行的操作属于重要操作,这些操作传递参数应该使用 post 方式,更加安全。 2)为防止跨站请求伪造,我们在某次请求的时候都要带上一个csrf_token参数,用于标识请求来源是否合法,csrf_token参数由系统生成,存储在SESSION中。
(4)暴力破解
定义(我的定义,嘿嘿):比如密码之类的,一个个地去试,去破解。
(5)DDOS攻击
定义:对攻击网站发动大量的正常或非正常请求,耗尽目标主机资源或网络资源,从而使被攻击的主机不能为合法用户提供服务,这个就属于DDOS攻击。
防御:对于DDOS攻击,建议买高防的DDOS服务器就可以了。
九、HTTP请求头和应答头
Requests部分
Header | 解释 | 示例 |
---|---|---|
Accept | 指定客户端能够接收的内容类型 | Accept: text/plain, text/html |
Accept-Charset | 浏览器可以接受的字符编码集。 | Accept-Charset: iso-8859-5 |
Accept-Encoding | 指定浏览器可以支持的web服务器返回内容压缩编码类型。 | Accept-Encoding: compress, gzip |
Accept-Language | 浏览器可接受的语言 | Accept-Language: en,zh |
Accept-Ranges | 可以请求网页实体的一个或者多个子范围字段 | Accept-Ranges: bytes |
Authorization | HTTP授权的授权证书 | Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ== |
Cache-Control | 指定请求和响应遵循的缓存机制 | Cache-Control: no-cache |
Connection | 表示是否需要持久连接。(HTTP 1.1默认进行持久连接) | Connection: close |
Cookie | HTTP请求发送时,会把保存在该请求域名下的所有cookie值一起发送给web服务器。 | Cookie: $Version=1; Skin=new; |
Content-Length | 请求的内容长度 | Content-Length: 348 |
Content-Type | 请求的与实体对应的MIME信息 | Content-Type: application/x-www-form-urlencoded |
Date | 请求发送的日期和时间 | Date: Tue, 15 Nov 2010 08:12:31 GMT |
Expect | 请求的特定的服务器行为 | Expect: 100-continue |
From | 发出请求的用户的Email | From: user@email.com |
Host | 指定请求的服务器的域名和端口号 | Host: www.zcmhi.com |
If-Match | 只有请求内容与实体相匹配才有效 | If-Match: “737060cd8c284d8af7ad3082f209582d” |
If-Modified-Since | 如果请求的部分在指定时间之后被修改则请求成功,未被修改则返回304代码 | If-Modified-Since: Sat, 29 Oct 2010 19:43:31 GMT |
If-None-Match | 如果内容未改变返回304代码,参数为服务器先前发送的Etag,与服务器回应的Etag比较判断是否改变 | If-None-Match: “737060cd8c284d8af7ad3082f209582d” |
If-Range | 如果实体未改变,服务器发送客户端丢失的部分,否则发送整个实体。参数也为Etag | If-Range: “737060cd8c284d8af7ad3082f209582d” |
If-Unmodified-Since | 只在实体在指定时间之后未被修改才请求成功 | If-Unmodified-Since: Sat, 29 Oct 2010 19:43:31 GMT |
Max-Forwards | 限制信息通过代理和网关传送的时间 | Max-Forwards: 10 |
Pragma | 用来包含实现特定的指令 | Pragma: no-cache |
Proxy-Authorization | 连接到代理的授权证书 | Proxy-Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ== |
Range | 只请求实体的一部分,指定范围 | Range: bytes=500-999 |
Referer | 先前网页的地址,当前请求网页紧随其后,即来路 | Referer: http://www.zcmhi.com/archives/71.html |
TE | 客户端愿意接受的传输编码,并通知服务器接受接受尾加头信息 | TE: trailers,deflate;q=0.5 |
Upgrade | 向服务器指定某种传输协议以便服务器进行转换(如果支持) | Upgrade: HTTP/2.0, SHTTP/1.3, IRC/6.9, RTA/x11 |
User-Agent | User-Agent的内容包含发出请求的用户信息 | User-Agent: Mozilla/5.0 (Linux; X11) |
Via | 通知中间网关或代理服务器地址,通信协议 | Via: 1.0 fred, 1.1 nowhere.com (Apache/1.1) |
Warning | 关于消息实体的警告信息 | Warn: 199 Miscellaneous warning |
Responses 部分
Header | 解释 | 示例 |
---|---|---|
Accept-Ranges | 表明服务器是否支持指定范围请求及哪种类型的分段请求 | Accept-Ranges: bytes |
Age | 从原始服务器到代理缓存形成的估算时间(以秒计,非负) | Age: 12 |
Allow | 对某网络资源的有效的请求行为,不允许则返回405 | Allow: GET, HEAD |
Cache-Control | 告诉所有的缓存机制是否可以缓存及哪种类型 | Cache-Control: no-cache |
Content-Encoding | web服务器支持的返回内容压缩编码类型。 | Content-Encoding: gzip |
Content-Language | 响应体的语言 | Content-Language: en,zh |
Content-Length | 响应体的长度 | Content-Length: 348 |
Content-Location | 请求资源可替代的备用的另一地址 | Content-Location: /index.htm |
Content-MD5 | 返回资源的MD5校验值 | Content-MD5: Q2hlY2sgSW50ZWdyaXR5IQ== |
Content-Range | 在整个返回体中本部分的字节位置 | Content-Range: bytes 21010-47021/47022 |
Content-Type | 返回内容的MIME类型 | Content-Type: text/html; charset=utf-8 |
Date | 原始服务器消息发出的时间 | Date: Tue, 15 Nov 2010 08:12:31 GMT |
ETag | 请求变量的实体标签的当前值 | ETag: “737060cd8c284d8af7ad3082f209582d” |
Expires | 响应过期的日期和时间 | Expires: Thu, 01 Dec 2010 16:00:00 GMT |
Last-Modified | 请求资源的最后修改时间 | Last-Modified: Tue, 15 Nov 2010 12:45:26 GMT |
Location | 用来重定向接收方到非请求URL的位置来完成请求或标识新的资源 | Location: http://www.zcmhi.com/archives/94.html |
Pragma | 包括实现特定的指令,它可应用到响应链上的任何接收方 | Pragma: no-cache |
Proxy-Authenticate | 它指出认证方案和可应用到代理的该URL上的参数 | Proxy-Authenticate: Basic |
refresh | 应用于重定向或一个新的资源被创造,在5秒之后重定向(由网景提出,被大部分浏览器支持) | Refresh: 5; url= http://www.zcmhi.com/archives/94.html |
Retry-After | 如果实体暂时不可取,通知客户端在指定时间之后再次尝试 | Retry-After: 120 |
Server | web服务器软件名称 | Server: Apache/1.3.27 (Unix) (Red-Hat/Linux) |
Set-Cookie | 设置Http Cookie | Set-Cookie: UserID=JohnDoe; Max-Age=3600; Version=1 |
Trailer | 指出头域在分块传输编码的尾部存在 | Trailer: Max-Forwards |
Transfer-Encoding | 文件传输编码 | Transfer-Encoding:chunked |
Vary | 告诉下游代理是使用缓存响应还是从原始服务器请求 | Vary: * |
Via | 告知代理客户端响应是通过哪里发送的 | Via: 1.0 fred, 1.1 nowhere.com (Apache/1.1) |
Warning | 警告实体可能存在的问题 | Warning: 199 Miscellaneous warning |
WWW-Authenticate | 表明客户端请求实体应该使用的授权方案 | WWW-Authenticate: Basic |
为什么 get 请求不需要设置 “content-type” ,post 请求却需要设置呢?
1. GET 请求不存在请求实体部分,键值对参数放置在 URL 尾部,浏览器把 form 数据转换成一个字串(name1=value1&name2=value2...),然后把这个字串追加到 url 后面,用 ? 分割,加载这个新的 url。因此请求头不需要设置 Content-Type 字段。非 ASCII 码会自动进行编码转换,例如发送请求:www.bilibili.com?hehe=你的我的。值得一提的是,GET 参数的编码方式是无法人为干涉的,这导致了不同浏览器有不同的编码方式,因此最稳妥的方案是人工预编码,人工解码,从而禁止浏览器编码的干涉。
2. POST 请求中 HTTP Header 里的 Content-Type 一般有三种:
- application/x-www-form-urlencoded:数据被编码为名称/值对。这是标准的编码格式。默认行为。它会将表单内的数据转换拼接成 key-value 对(非 ASCII 码进行编码)
- multipart/form-data(一般用来上传文件): 数据被编码为一条消息,页上的每个控件对应消息中的一个部分
- text/plain: 数据以纯文本形式(text/json/xml/html)进行编码,其中不含任何控件或格式字符。postman软件里标的是RAW。(中文不进行编码)
END