共计 3650 个字符,预计需要花费 10 分钟才能阅读完成。
计算机网络结构
物理层
定义物理设备标准,起到传输比特流的作用。
数据链路层
提供可靠的通过物理介质传输数据的方法。
通过差错控制、流量控制方法将有差错的物理链路(物理链路容易受到干扰)变为无差错的数据链路
将物理层的比特流数据封装成数据帧传递给上层,将上层的数据帧转换为比特流给物理层。
提供 MAC 地址(物理地址),可作为局域网内一个网卡的唯一标识。
网络层
解决不同子网间的通信问题:逻辑寻址,规定不同的信息交换方式,路由算法,连接服务。
IP 协议
网络上每一个节点都有一个独立的逻辑地址——IP 地址
IP 协议负责将数据包传送到目的地,没有提供一种数据未传达以后的处理机制(这被认为是上层协议需要做的事情),是不可靠的协议。
传输层
提供可靠的端到端的差错和流量控制,保证报文的正确传输
UDP 协议
没有建立连接,直接向对象发包,不可靠但快速高效。应用:ping 命令、实时音视频通信
TCP 协议
三次握手建立连接
发送方给接受方 TCP 数据报,然后等待对方的确认 TCP 数据报,如果没有,就重新发,如果有,就发送下一个数据报。
接受方等待发送方的数据报,如果得到数据报并检验无误,就发送 ACK(确认) 数据报,并等待下一个 TCP 数据报的到来。直到接收到 FIN(发送完成数据报)
四次挥手中止连接
会话层
建立和管理应用程序之间的通信,保证应用程序自动收发包和寻址
表示层
解释不同系统之间的通信语法
应用层
直接面向用户的程序或服务
HTTP 协议
什么是 HTTP 协议?
基于 TCP/IP 协议基础的一个应用层协议,用于从 Web 服务器传输超文本到本地浏览器的传送协议,由请求和响应构成。
HTTP 协议的特点
无状态:请求相互独立,通信状态不被保存
HTTP 报文的组成
HTTP 报文包括请求报文和响应报文两大部分,其中请求报文由请求行(request line)、请求头(header)、空行和请求体四个部分组成。而响应报文由状态行、响应头部、空行和响应体四个部分组成。
HTTP 请求方式
GET, HEAD, POST, PUT, DELETE,OPTIONS
HEAD:获取报头。
OPTIONS:获取请求资源的选项、需求或服务器支持,并非资源请求。ajax 请求跨域资源时,使用 OPTIONS 方法发送嗅探请求,以判断是否有对指定资源的访问权限。
GET 和 POST 的区别
GET 安全性低,会被缓存
GET 请求在 URL 中显示参数,POST 请求在 send 中传递参数
状态码
1xx:表示请求已接收,继续处理
2xx:成功,操作被成功接收并处理
3xx:重定向,需要进一步的操作以完成请求
4xx:客户端错误,请求有语法错误或请求无法实现
5xx:服务端错误,服务器端错误 – 服务器未能实现合法的请求
200 请求正常处理
204 请求正常处理但没有资源返回
301 永久性重定向
302 临时性重定向
304 指采用 GET 方法的请求报文中包含 if-matched,if-modified-since,if-none-match,if-range,if-unmodified-since 任一个首部)服务器端允许请求访问资源,但因发生请求未满足条件的情况后,直接返回 304Modified
400 请求报文中有语法错误
401 表示未授权
403 请求被服务器拒绝
404 服务器上无法找到请求的资源
500 服务器在执行时发生错误
503 服务器暂时处于超负载或正在进行停机维护
请求 API
Ajax
var xhr = null;
if (window.XMLHttpRequest) {
xhr = new XMLHttpRequest();
xhr.open(“POST”,”test.html”,true);
xhr.setRequestHeader(“Content-type”,”application/x-www-form-urlencoded”);
xhr.send(“fname=Henry&lname=Ford”);
xhr.onreadystatechange = function () {
if (xhr.readyState === 4 && xhr.status === 200) {
console.log(xhr.responseText);
}
}
xhr.onerror = function (e) {
console.log(e)
}
}
readyState
0:未初始化,尚未调用 open
1:已经调用 open,尚未调用 send
2:已经 send,但尚未收到响应
3:已接收到部分响应
4:已收到所有响应
error 事件
Network error,只有发生网络层的错误才会出发 error 事件,应用层的错误不会进入 error
onload 事件
当请求成功完成时触发,此时 xhr.readyState=4
onabort 事件
调用 xhr.abort() 后触发
withCredentials
在跨域请求中,客户端必须手动设置 xhr.withCredentials=true,且服务器端也必须允许亲贵能携带认证信息(即响应头中包含 Access-Control-Allow-Credentials:true),这样浏览器才会自动将 cookie 加在请求头中。另外,要特别注意一点,一旦跨域请求能够携带认证信息,服务器端一定不能将 Access-Control-Allow-Origin 设置为 *,而必须设置为请求页面的域名。
XMLHttpRequest 的具体介绍
Fetch
Fetch API 基于 Promise 设计,fetch() 返回一个 Promise 对象
fetch(url).then(response => response.json())
.then(data => console.log(data))
.catch(e => console.log(“Oops, error”, e))
Fetch 原生支持率并不高,需要引入各种 polyfill
由于 IE8 是 ES3,需要引入 ES5 的 polyfill: es5-shim, es5-sham
引入 Promise 的 polyfill: es6-promise
引入 fetch 探测库:fetch-detector
引入 fetch 的 polyfill: fetch-ie8
可选:如果你还使用了 jsonp,引入 fetch-jsonp
可选:开启 Babel 的 runtime 模式,现在就使用 async/await
Fetch polyfill 的基本原理是探测是否存在 window.fetch 方法,如果没有则用 XHR 实现。这也是 github/fetch 的做法,但是有些浏览器(Chrome 45)原生支持 Fetch,但响应中有中文时会乱码,老外又不太关心这种问题,所以我自己才封装了 fetch-detector 和 fetch-ie8 只在浏览器稳定支持 Fetch 情况下才使用原生 Fetch。这些库现在 每天有几千万个请求都在使用,绝对靠谱!
Fetch 常见坑
Fetch 请求默认是不带 cookie 的,需要设置 fetch(url, {credentials: ‘include’})
服务器返回 400,500 错误码时并不会 reject,只有网络错误这些导致请求不能完成时,fetch 才会被 reject。
引用自传统 Ajax 已死,Fetch 永生
axios
基于 Promise 的 HTTP 封装库,可用于浏览器和 node 环境
浏览器中使用 XMLHttpRequest
node.js 中使用 http 模块
支持 Promise API
可拦截请求和响应
转换请求和响应数据
可取消请求
自动转换 JSON 数据
为客户端提供 XSRF 支持
axios 项目仓库 & 文档
跨域
什么是跨域
跨域的解决方法
缓存
强缓存
不会发出请求,直接从缓存中读取数据
Expires
设置过期时间,缺点使用浏览器时间判断,浏览器时间会随客户端设置修改
Cache-Control
设置相对时间,以秒为单位
Cache-Control 优先级大于 Expires
协商缓存
发出请求,与服务端配合判断资源是否过期,需要与 Cache-Control 共同使用
如果命中协商缓存,服务端返回 304 并通知浏览器从本地缓存读取资源
Last-Modified 和 If-Modified-Since
记录和比较资源的修改时间,存在的问题:1. 时间误差 2. 资源修改和时间修改可能不一致
ETag 和 If-None-Match
服务端通过哈希算法根据文件内容计算出哈希值
记录和比较资源的哈希值
ETag 优先级大于 Last-Modified
用户行为对缓存的影响
地址栏访问,链接跳转是正常用户行为,将会触发浏览器缓存机制;
F5 刷新,浏览器会设置 max-age=0,跳过强缓存判断,会进行协商缓存判断;
ctrl+F5 刷新,跳过强缓存和协商缓存,直接从服务器拉取资源。
其他响应头
no-cache
是否使用缓存需要经过协商缓存来验证决定
no-store
所有内容都不会被缓存,即不使用强制缓存,也不使用协商缓存
public
所有内容都将被缓存(客户端和代理服务器都可缓存)
private
所有内容只有客户端可以缓存
请求优化
资源压缩合并
非核心代码异步加载
利用浏览器缓存
使用 CDN
预解析 DNS
页面性能优化办法有哪些