聊聊HTTP,越详细越好

2022-07-28 12:27:58 浏览数 (1)

http这道八股文在面试中屡见不鲜,也是屡战屡败,今天卷http也是让自己重新回顾http,虽然在实际项目中,你不需要像面试一样被刨根问底,来自灵魂的拷问,但是,高端岗位,高端面试总会让你欲罢不能,说下http的理解,这道看似简单的菜,但是当你吃的时候,总会耐人寻味。

正文开始....

http是什么

http四个字母来讲,它是Hypter transfer protocol超文本传输协议。

超文本传输协议,你告诉面试官,它首先是超文本,不是普通文本,然后它是一种传输协议。下面一张图再次印在脑壳里

首先我们知道http它是一种计算机通信的协议,它是在计算机之间通信的协议,你可以把它看成计算机之间通信的规范,能处理各种网上信息的媒介。

然后我们知道它能传输,互联网上所有的文本,图片,视频以及文件都是能传输的,我们之所以能看网上的所有任何信息,这些信息都离不开传输。那么传输就靠它,遵循A->B或者B->A,它是一个双向的通信。在A->B两点之间可以加许多约束,比如加密,安全认证、压缩数据等等,但是始终得遵循http传输的规范。

最后我们知道它是超文本,既然是超文本,那么它是一定不同寻常。所有数据文本格式在http眼里统称为超文本【文字、图片,视频、文件等】

以上说了那么多,那么http既然是超文本传输协议,那么它是类似应用软件、操作系统或者是apachenginxtomact那样的服务器吗?以上都不是,它是一种计算机通信的规范,是一种动态的存在,与应用软件、操作系统,以及web服务器息息相关,我们可以用编程语言去操作http进而操作应用软件、操作系统等等。

在互联网的世界里,http协议并不是孤立存在的,它在tcp/ip协议栈的上层,通过ip协议实现寻址和路由,通过tcp协议实现可靠的数据传输,DNS协议实现域名解析,SSL/TLS实现安全通信,有些其他通信协议甚至是依赖它的,比如websocket协议、HTTPDNS,这些协议组成一个协议网,而http处于中心位置,它们有机组合。

你知道http版本之间有哪些区别吗

通常来讲,问这问题,似乎有点超越我知识边界啊,此时脑子里一片空白,心中已是万马奔腾....

http0.9版本

只支持GET请求方式,仅支持请求HTML格式资源。

http1.0版本

1、增加了HEADPOST请求方法

2、增加了status状态码,字符集,内容编码

3、增加了请求头,请求体,响应体,支持长链接keep-alive

4、支持了多种文本格式传输,不仅限html格式文本

5、引入协议版本号

6、增加了缓存机制

http1.1版本

1、增加了PUTDELETEOPTION等方法

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上层,准确的说,httpTCP/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访问

代码语言:javascript复制
npm init -y // 生成package.json
npm i express // 安装express

touch server.js 创建服务端代码

代码语言:javascript复制
// 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访问,比如我的本地ip192.168.1.6,具体查看mac,终端输入ifconfig即可查看本机的ip,如果你用ip访问那么就是http://192.168.1.6:8081

从这段简单的服务端代码我们可以知道,打开network我们来仔细回顾下http到底有哪些信息

General通用首部字段类型

  • 有请求的路由urlRequest URL地址,
  • 请求方法Request MethodGET请求,
  • 响应的状态码Status,还有Remote Address远程地址。
  • Referrer Policy:strict-origin-when-cross-origin,对于同源的请求,会发送完整的URL作为引用地址
代码语言:javascript复制
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
代码语言:javascript复制
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,默认gzipdeflate,表示http响应是否进行压缩。

Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,表示支持的语言

代码语言:javascript复制
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大体分五类

代码语言:javascript复制
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攻击,客户端发送大量的合法请求,消耗大量服务器资源,造成服务器奔溃。

0 人点赞