这篇文章历时两天,内容依据于前端面试官常问的一些面试题
不足之处还望见谅
如果您觉得对您有帮助的话,还望不要吝啬您的赞哟^_^
1.HTTP/TCP/IP/port 概览
老规矩,先从一个故事开始
龚先生穿越到了异界,发现这个异界很奇怪,只能用飞鸽传信而且还有几个规定【协议】
首先,有一个内容规定,规定每封信只能有四行字【这就是HTTP,至于具体哪四行,待会儿我们说】
,但具体信是怎么传输过去的,HTTP不管
所以又定一个传输规定,必须要用鸽子来送信,而且还必须要把信绑到鸽子的脚上【这个传输规定就是TCP】
但是,鸽子在天空中飞,来来回回得有个目的地吧,我们还需要一个飞行目的地规定给鸽子分配目的地【这就是IP】
但问题又来了,你给别人飞鸽传信,那个人发展起来了,搞了一个有n个部门大公司,每个部门都有自己独特的服务,但现在ip对应的是人家公司地址,你想把信传到人家公司的XX部门,要求具体的服务,咋办呢
这个时候,人家公司就把每个部门都设置了不重复的编号,方便鸽子判断【不同的编号就是port】
听了这个故事,你对下面的图应该会容易理解了
总结一下
HTTP —— 规定如何书写内容
TCP —— 规定如何传输
IP —— 规定如何连接
Port —— 对应IP的不同服务
相关面试题
1.TCP 和 UDP 的区别是什么
// 简答:TCP可靠、面向连接、相对 UDP 较慢;
// UDP 不可靠,不面向连接、相对 TCP 较快。
2.TCP 的三次握手指的是什么
// 1. 客户端:我要连接你了,可以吗
// 2. 服务端:嗯,我准备好了,连接我吧
// 3. 客户端:那我连接你咯。
// 4. 开始后面步骤
2.HTTP详解
2.1 HTTP的工作模型
HTTP的工作模型是请求/响应
模型
你可以理解为客户端【浏览器,Client】
向服务器【Server】
发送一个请求服务器【Server】
向客户端【浏览器,Client】
返回一个响应
2.2 我们来看一下HTTP的工作流程
第一步:浏览器与服务器建立连接,请求服务器资源
第二步:发送HTTP请求
浏览器向服务器发送一个文本形式的请求报文,共有四个部分【就是我们在故事里说的每封信有四行字】
格式如下
1.请求行【一行】【三个部分】
GET /a HTTP/1.1
POST /a HTTP/1.1
请求方式 请求路径 协议与版本号
2.请求头【多行】
Key:Value
关于userAgent:每一个浏览器都是用户的代理者,用户通过浏览器来上网
3.空行【回车】
目的是要和第四部分隔开
4.请求体【message body】【任何字符串,但要符合content-Type】
username=blues&password=123
注:get请求一般省略3和4
GET方式实例如下【请求百度首页】
// 1.请求行【一行】【三个部分】
GET / HTTP/1.1
// 2.请求头【多行】
Host: www.baidu.com
Connection: keep-alive
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.162 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
// GET请求可以不写第三部分和第四部分
第三步:服务器接受请求及其附带参数并根据自身逻辑返回响应
1.响应行
HTTP/1.1 200(status code) OK(status message)
HTTP/1.1 404(status code) Not Found(status message)
2.响应头
key:value
关于Content-Type:响应文本的类型,编码方式
关于Date:格林美治时间 —— GMT
3.空行
4.响应体
任何字符串
第四步:浏览器解析响应体内容
2.3 HTTP请求的常见方式
2.3.1 GET方式
用于请求服务器发送某个资源
如何发一个GET请求
// 2.1 <link rel="stylesheet" href="style.css">
// 2.2 <img src="1.png">
// 2.3 <script src=".router.js">
// 2.4 地址栏输入URL,回车
2.3.2 POST方式
用于向服务器发送数据
比如,表单提交
2.3.3 HEAD方式
和GET类似,不过服务器只会响应一些信息,而不会响应具体的内容主要用于测试
2.3.4 PUT方式
和POST类似,不过是向服务器写入数据
2.3.5 GET 和 POST 的区别
参数
GET的参数写在请求头中,POST写在请求体中安全
POST比GET安全参数长度限制
GET的长度限制在1024个字节,POST的长度限制在4~10Mb功能区别
2.3.1和2.3.2写了
2.4 HTTP的状态码
共有五大类
1xx:指示信息
—— 用于指定客户端某些响应的动作
2xx:成功
—— 表示请求已被成功接
3xx:重定向
—— 要完成请求必须进行更进一步的操作
4xx:客户端错误
—— 指出客户端错误
5xx:服务器端错误
—— 指出服务器端错误
常见状态码
200 | OK | 请求成功 | 一般用于GET与POST请求 |
301 | Moved Permanently | 永久重定向 | 请求的资源已被永久的移动到新URI,返回信息会包括新的URI,浏览器会自动定向到新URI。今后任何新的请求都应使用新的URI代替 |
302 | Found | 临时移动 | 与301类似。但资源只是临时被移动。客户端应继续使用原有URI |
403 | Forbidden | 被拒绝 | 服务器理解请求客户端的请求,但是拒绝执行此请求 |
404 | Not Found | 未找到 | 服务器无法根据客户端的请求找到资源(网页)。通过此代码,网站设计人员可设置"您所请求的资源无法找到"的个性页面 |
3.URL的组成形式
协议类型://<主机名>.<域名>:<端口编号>/<路径>/<文件名>?<查询字符串>#<哈希>
- 协议类型:对于web来说,最常见的有
http
和https
- <主机名>.<域名>:可以是
IP地址
或者域名
- <端口编号>:就是
port
,方便找到对应的服务 - /<路径>/<文件名>:资源存放的目录和资源名
- ?<查询字符串>:GET请求最常用的参数传递方式,如
?username=blues&age=16
- <哈希>:现在被很多MVVM框架用作了
路由功能
4.HTTP缓存
4.1 Cache-control
在server可以进行响应头部
设置
respond.setHeader("Cache-control","max-age=300");
Cache-control:max-age={有效时间}
有效时间内,会直接使用本地缓存
超过有效期,则从服务器拉取数据
4.2 ETag
由Http1.1推出
服务器会通过某种算法,给资源计算得出一个唯一标志符
(比如md5标志)
在把资源响应给客户端的时候,会在响应头
加上“ETag: 唯一标识符”
一起返回给客户端
客户端会保留该 ETag 字段,并在下一次请求时将其一并带过去给服务器
服务器只需要比较客户端传来的ETag跟自己服务器上该资源的ETag是否一致,就能很好地判断资源相对客户端而言是否被修改过了
客户端是如何把标记在资源上的 ETag 传回给服务器的呢?
请求报文中有两个首部字段【请求头内的字段】可以带上 ETag 值:
⑴ If-None-Match: ETag-value
示例为 If-None-Match: "5d8c72a5edda8d6a:3239"
告诉服务端如果 ETag 没匹配上需要重发资源数据,
若匹配上了则直接回送304 和响应报头即可。
⑵ If-Match: ETag-value
告诉服务器如果没有匹配到ETag,或者收到了“*”值而当前并没有该资源实体
则应当返回412(Precondition Failed) 状态码给客户端
若匹配上了则服务器直接忽略该字段。
4.3 Cache-control 和 ETag的区别
类型 | 优势 | 劣势 |
---|---|---|
Cache-Control | 1、HTTP 1.1 产物,以时间间隔标识失效时间。2、比Expires多了很多选项设置。 | 1、HTTP 1.1 才有的内容,不适用于HTTP 1.0 。2、存在版本问题,到期之前的修改客户端是不可知的。 |
ETag | 1、可以更加精确的判断资源是否被修改,可以识别一秒内多次修改的情况。2、不存在版本问题,每次请求都回去服务器进行校验。 | 1、计算ETag值需要性能损耗。2、分布式服务器存储的情况下,计算ETag的算法如果不一样,会导致浏览器从一台服务器上获得页面内容后到另外一台服务器上进行验证时发现ETag不匹配的情况。 |
5.题外话:浏览器本地储存
5.1 Cookie
主要用于Browser和Server通信
cookie在通信过程中的作用:
- 该规范要求服务器在响应HTTP请求时,带上设置好的cookie字段(
Cookie一般在Server端被设置
) - 如果浏览器本地有cookie,那么浏览器每次请求时,会
根据Cookie记录的域名
,带上对应的cookie字段
,发送请求
前端获取和设置cookie:
只能通过document.cookie
来获取和修改(一般前端无需修改cookie)
不要用cookie来存储:
- Cookie的主要作用就是用来
识别用户身份
【判断该用户之前是否已经访问过】,而非储存数据
- Cookie的大小最多为
4kB
- browser每次发送请求会带上cookie,cookie过大会浪费带宽
5.2 LocalStorage
在上一节中,我们提到了Cookie不应该用来储存数据
那么用户的偏好数据
比如搜索记录等数据应该存放在哪里呢——LocalStorage
1.LocalStorage是window下的一个API
// 使用setItem设置
let searchHistory = ['吉他','前端']
window.localStorage.setItem('搜索记录',searchHistory)
// 请自行测试并自行查看
2.LocalStorage大小一般在5Mb左右
3.LocalStorage只能存储字符串,即便你储存的是一个数组,也会被转化为字符串
window.localStorage.getItem('搜索记录') // "吉他,前端"
// 解决方案 —— 使用JSON.stringnify将数组 字符串化
let jsonArr = JSON.stringify(searchHistory)
console.log(jsonArr) // "["吉他","前端"]"
window.localStorage.setItem('搜索记录',jsonArr)
JSON.parse(window.localStorage.getItem('搜索记录')) // ["吉他", "前端"]
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。