http
这道八股文在面试中屡见不鲜,也是屡战屡败,今天卷http
也是让自己重新回顾http
,虽然在实际项目中,你不需要像面试一样被刨根问底,来自灵魂的拷问,但是,高端岗位,高端面试总会让你欲罢不能,说下http
的理解,这道看似简单的菜,但是当你吃的时候,总会耐人寻味。
正文开始....
http是什么
从http
四个字母来讲,它是Hypter transfer protocol
超文本传输协议。
超文本传输协议
,你告诉面试官,它首先是超文本,不是普通文本,然后它是一种传输协议
。下面一张图再次印在脑壳里
首先我们知道http
它是一种计算机通信的协议,它是在计算机之间通信的协议,你可以把它看成计算机之间通信的规范,能处理各种网上信息的媒介。
然后我们知道它能传输,互联网上所有的文本,图片,视频以及文件都是能传输的,我们之所以能看网上的所有任何信息,这些信息都离不开传输
。那么传输就靠它,遵循A->B或者B->A,它是一个双向的通信。在A->B两点之间可以加许多约束,比如加密,安全认证、压缩数据等等,但是始终得遵循http
传输的规范。
最后我们知道它是超文本,既然是超文本
,那么它是一定不同寻常。所有数据文本格式在http
眼里统称为超文本
【文字、图片,视频、文件等】
以上说了那么多,那么http
既然是超文本传输协议,那么它是类似应用软件、操作系统或者是apache
、nginx
、tomact
那样的服务器吗?以上都不是,它是一种计算机通信的规范,是一种动态的存在,与应用软件、操作系统,以及web
服务器息息相关,我们可以用编程语言去操作http
进而操作应用软件、操作系统等等。
在互联网的世界里,http
协议并不是孤立存在的,它在tcp/ip
协议栈的上层,通过ip
协议实现寻址和路由,通过tcp
协议实现可靠的数据传输,DNS
协议实现域名解析,SSL/TLS
实现安全通信,有些其他通信协议甚至是依赖它的,比如websocket
协议、HTTPDNS
,这些协议组成一个协议网,而http
处于中心位置,它们有机组合。
你知道http版本之间有哪些区别吗
通常来讲,问这问题,似乎有点超越我知识边界啊,此时脑子里一片空白,心中已是万马奔腾....
http0.9
版本
只支持GET
请求方式,仅支持请求HTML
格式资源。
http1.0
版本
1、增加了HEAD
、POST
请求方法
2、增加了status
状态码,字符集,内容编码
3、增加了请求头,请求体,响应体,支持长链接keep-alive
4、支持了多种文本格式传输,不仅限html
格式文本
5、引入协议版本号
6、增加了缓存机制
http1.1
版本
1、增加了PUT
、DELETE
、OPTION
等方法
2、增加了缓存管理与控制
3、默认长链接connection:keep-alive
5、运行响应数据分块、利于传输大文件
6、强制要求Host
头,增加管道机制,同时支持多个请求并行发送【把多个请求放到队列中,一个一个请求的同时,接收对应的响应】
7、增加了身份认证机制,新增24个错误码
http2.0
版本 延续了http1.0
所有的特性,增加以下新功能
1、二进制协议,不再是纯文本
2、可以发个多个请求,废除1.1的管道
3、专用的算法压缩头部,减少数据量的传输
4、允许服务器向客户端推送消息
5、增加了安全性,要求安全加密
6、增加了双工模式【客户端发送多个请求,服务端同时处理多个请求】
说下TCP/IP是什么
http
位于TCP/IP上层,准确的说,http
是TCP/IP
协议的子集,TCP/IP协议按层次分层管理
TCP/IP通信传输
三次握手
简单的来说就是发送SYN标识
、确认SYN/ACK标识
、回传ACK标识
域名解析DNS(dommin name system)
首先DNS同属于应用层协议,它是域名->ip之间的解析服务
通常我们访问一个类似www.baidu.com
的网站,这是域名,通过访问域名,浏览器响应的页面在客户端中,在访问域名时,DNS是帮我们解析了该域名的地址,实际上百度的IP地址可能是类似220.181.38.251
这样的ip,这也是服务器的ip
地址。
在DNS解析只是为了让用户不用记住这串ip
,用域名映射了ip
地址,IP协议会在你当前的固定的MAC
地址(相当于电脑端的门牌号)上与ip
地址进行发送数据与接收数据操作。
地址上的一些信息
随便淘宝输入一个地址https://www.taobao.com/?spm=a2107.1.0.0.5c9511d9IYcDK4
了解服务端与客户端
我们快速使用express
搭建一个服务器,并指定ip
访问
npm init -y // 生成package.json
npm i express // 安装express
touch server.js
创建服务端代码
// server.js
const express = require("express");
const app = express();
const PORT = '8081';
app.get('/', (req, res) => {
res.send('hello server')
});
app.listen(PORT, () => {
console.log('server is start' PORT)
})
运行命令node server.js
,打开浏览器访问localhost:8081
,这里的localhost
之所以可以这么访问,是因为我们本地host
映射的本地ip域名就是localhost
,如果你查看你本地的ip
也可以用ip
访问,比如我的本地ip
是192.168.1.6
,具体查看mac
,终端输入ifconfig
即可查看本机的ip
,如果你用ip
访问那么就是http://192.168.1.6:8081
从这段简单的服务端
代码我们可以知道,打开network
我们来仔细回顾下http
到底有哪些信息
General
通用首部字段类型
- 有请求的路由
url
Request URL地址, - 请求方法Request Method
GET
请求, - 响应的状态码
Status
,还有Remote Address
远程地址。 - Referrer Policy:
strict-origin-when-cross-origin
,对于同源的请求,会发送完整的URL作为引用地址
Request URL: http://192.168.1.6:8081/
Request Method: GET
Status Code: 200 OK
Remote Address: 192.168.1.6:8081
Referrer Policy: strict-origin-when-cross-origin
Response Headers
- 有
http
的版本,状态是200
X-Powered-By
:Express
这是可以看出是哪个服务器开发的。Content-Type: text/html;charset=utf-8
对应的网络类型语言和语言编码。Content-Length: 12
报文的实体长度。ETag:W/"c-KpI5DocyxPM9FaJeckcyQoImh1k
服务器返回的一段标识,web
端缓存验证。Connection:keep-alive
设置客户端长链接。Keep-Alive: timeout=5
HTTP/1.1 200 OK
X-Powered-By: Express
Content-Type: text/html; charset=utf-8
Content-Length: 12
ETag: W/"c-KpI5DocyxPM9FaJeckcyQoImh1k"
Date: Wed, 27 Apr 2022 13:04:19 GMT
Connection: keep-alive
Keep-Alive: timeout=5
Request Headers
Accept
服务器返回的语言Accept-Encoding
:gzip, deflate
,默认gzip
与deflate
,表示http
响应是否进行压缩。
Accept-Language
: zh-CN,zh;q=0.9,en;q=0.8
,表示支持的语言
Accept: text/html,application/xhtml xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Cache-Control: no-cache
Connection: keep-alive
Cookie: sensorsdata2015jssdkcross={"distinct_id":"17af9c0b6845ce-07835609215c5b4-35637203-1296000-17af9c0b685d5f","first_id":"","props":{"$latest_traffic_source_type":"url的domain解析失败","$latest_search_keyword":"url的domain解析失败","$latest_referrer":"url的domain解析失败"},"$device_id":"17af9c0b6845ce-07835609215c5b4-35637203-1296000-17af9c0b685d5f"}; _ga=GA1.1.1843623571.1627687795; Hm_lvt_c090ced1a911ebae432278eea5465028=1627687795; _hjid=0262b7cd-3d01-48d6-bf20-77b938e07cbf
Host: 192.168.1.6:8081
Pragma: no-cache
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36
http是无状态的
因为http
是无状态的的协议,它不会对之前的请求和响应进行管理,也就是无法根据之前的请求,判断当前的请求操作。虽然http
是无状态的,也因此减少了服务器资源与CPU
的内存消耗。但是可以通过cookie
记录请求的状态,当一个网站
需要登录后再次访问,不需要登录时,当我们登录后,服务端会在请求头里设置cookie
,当客户端再次请求时,会携带这个之前设置好的cookie
给后端,然后后端会在cookie
设置uid
等之类标识,前端也会根据这个设置标识不用重复登录操作。其实接口的鉴权也是这么这么做的,通常登录后,会在报文的请求头里设置token
,所有接口请求头里都会带cookie
标识给后端做验证,并且会设置当前cookie
字段HttpOnly=true
状态,在前端js
是读取不到的,这是防御xss
攻击的一种手段。
http的一些常用状态码
客户端HTTP
的返回结果,标记服务端处理是否正常。
status
大体分五类
1xx 信息状态码 接受请求正在处理
2xx 成功状态码 请求处理完毕 200
3xx 重定向状态码 需要加以附加操作才能完成请求 302 重定向
4xx 客户端状态码 服务器无法处理请求 404资源无法找到, 403访问资源被服务器拒绝
5xx 服务器错误状态码 服务器处理请求错误 500,503等
安全性
- 请求头cookie部分字段设置
HttpOnly
,Set-Cookie: token=123;HttpOnly,
js是无法读取cookie
设置的属性值的,防止xss利用js劫持cookie X-Frame-Options: DENY / SAMEORGIN
属于http
响应首部,控制网站内容Frame,防止点击劫持,`- X-XSS-Protection: 1 属于
http
响应首部,主要针对跨站脚本攻击, 1:xss过滤设置成无效状态, 0:将xss过滤设置成有效状态
HTTPS
相比较http
,https
主要增强了安全性,http
协议有很多的优点,但是也有缺点
1、首先http
是明文通信,内容没有加密,有可能会被篡改
2、不会验证身份信息,因此可能会遭伪装
3、无法保护请求报文的完整性,报文有可能会被篡改。
因为以上种种,所以有了SSL(Secure Socket Layer)/TSL(Transport Layer Security)
安全套接层/安全传输层协议
证书和签名
https
通常会通过证书手段判断服务器和客户端的真实性,并且SSL
会加密,意味报文不会轻易被窃取,一张图简单描述一下https
本质上https
是套了一层SSL/TSL
协议的外壳,增强了http
协议的安全性
web安全性
主要分为3类
- 主动攻击(SQL注入,OS命令注入攻击)
- 被动攻击(导用户点击,劫持网页,窃取cookie信息,伪造用户信息,xss攻击(跨站脚本攻击))
- 以服务器为目标的主动攻击(增加图片验证码,客户端与服务端同时验证)
- 会话劫持,攻击者通过某种手段拿到了会话ID,伪装ID,达到攻击用户目的(一般是窃取cookie信息)
- 跨站请求伪造(csrf),利用写好的脚本植入当前网站,诱导用户执行脚本
- DOS攻击,客户端发送大量的合法请求,消耗大量服务器资源,造成服务器奔溃。