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访问

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访问,比如我的本地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 作为引用地址
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,默认gzipdeflate,表示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=%7B%22distinct_id%22%3A%2217af9c0b6845ce-07835609215c5b4-35637203-1296000-17af9c0b685d5f%22%2C%22first_id%22%3A%22%22%2C%22props%22%3A%7B%22%24latest_traffic_source_type%22%3A%22url%E7%9A%84domain%E8%A7%A3%E6%9E%90%E5%A4%B1%E8%B4%A5%22%2C%22%24latest_search_keyword%22%3A%22url%E7%9A%84domain%E8%A7%A3%E6%9E%90%E5%A4%B1%E8%B4%A5%22%2C%22%24latest_referrer%22%3A%22url%E7%9A%84domain%E8%A7%A3%E6%9E%90%E5%A4%B1%E8%B4%A5%22%7D%2C%22%24device_id%22%3A%2217af9c0b6845ce-07835609215c5b4-35637203-1296000-17af9c0b685d5f%22%7D; _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 信息)
  • 跨站请求伪造(csrx),利用写好的脚本植入当前网站,诱导用户执行脚本
  • DOS 攻击,客户端发送大量的合法请求,消耗大量服务器资源,造成服务器奔溃。
扫二维码,关注公众号
专注前端技术,分享web技术
加作者微信
扫二维码 备注 【加群】
教你聊天恋爱,助力脱单
微信扫小程序二维码,助你寻他/她
专注前端技术,分享Web技术
微信扫小程序二维码,一起学习,一起进步
前端面试大全
海量前端面试经典题,助力前端面试