网络

123 阅读13分钟

跨域

同源策略:域名、协议、端口

同源政策的目的,是为了保证用户信息的安全,防止恶意的网站窃取数据。

Cookie、LocalStorage 和 IndexDB 无法读取

Dom无法读取

Ajax请求无法发送

一级域名相同,二级域名不同,可以设置document.domain来共享Cookie

window.postMessage可以垮窗口通信,不管是不是同源

发送
var popup = window.open('http://bbb.com', 'title');
popup.postMessage('Hello World!', 'http://bbb.com');

```
接收
window.addEventListener('message', function(e) {
  console.log(e.data);
},false);

```
回复
window.addEventListener('message', receiveMessage);
function receiveMessage(event) {
  if (event.origin !== 'http://aaa.com') return;
  if (event.data === 'Hello World') {
      event.source.postMessage('Hello', event.origin);
  } else {
    console.log(event.data);
  }
}

跨域的解决方案

特别说明:在跨域问题上,仅仅是通过“URL的首部”来识别而不会根据域名对应的IP地址是否相同来判断。“URL的首部”可以理解为“协议, 域名和端口必须匹配”

跨域并不是请求发不出去,请求能发出去,服务端能收到请求并正常返回结果,只是结果被浏览器拦截了

1、jsonp 利用script标签没有跨越限制的漏洞,但是一定要对方服务器支持,并且只支持GET请求方式,不安全可能会遭受XSS攻击

<script> var script = document.createElement('script'); script.type = 'text/javascript'; // 传参一个回调函数名给后端,请求资源成功后把资源返回并调用handleCallback script.src = 'http://www.domain2.com:8080/login?user=admin&callback=handleCallback'; document.head.appendChild(script); // 回调执行函数 function handleCallback(res) { alert(JSON.stringify(res)); } </script>

2、CORS CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)。

CORS分为简单请求和非简单请求,只要同时满足 请求方式:GET HEAD POST 头信息:Accept Accept-Language Content-Language Last-Event-ID Content-Type只限于 application/x-www-form-urlencoded multipart/form-data text-plain

简单请求会在请求头上增加一个Origin字段

响应头上会增加

Access-Control-Allow-Origin:请求时Origin字段的值,代表允许跨越的域名,可以设置为*

Access-Control-Allow-Credentials:是否允许携带Cookie,如果是true,浏览器还需要设置 xhr.withCredentials = true; 如果要发送Cookie,Access-Control-Allow-Origin就不能设为星号,必须指定明确的、与请求网页一致的域名

Access-Control-Expose-Headers:该字段可选。CORS请求时,XMLHttpRequest对象的getResponseHeader()方法只能拿到6个基本字段:Cache-ControlContent-LanguageContent-TypeExpiresLast-ModifiedPragma。如果想拿到其他字段,就必须在Access-Control-Expose-Headers里面指定。上面的例子指定,getResponseHeader('FooBar')可以返回FooBar字段的值。

非简单请求

非简单请求的CORS请求,会在正式通信之前,增加一次HTTP查询请求,称为"预检"请求(preflight)。浏览器会先询问服务器,当前网页所在的域名是否在服务器的许可名单中,一级可以使用哪些HTTP方法和头部信息,只有得到明确的肯定答复,才会发出正式的请求,请求方法为OPTIONS

非简单请求请求头上会增加 Origin字段以及

Access-Control-Request-Method:该字段是必须的,用来列出浏览器的CORS请求会用到哪些HTTP方法

Access-Control-Request-Headers:该字段是一个逗号分隔的字符串,指定浏览器CORS请求会额外发送的头信息字段

非简单请求的响应头上会增加

Access-Control-Allow-Origin:允许跨域请求的源,可以设置为*

Access-Control-Allow-Methods:该字段必需,它的值是逗号分隔的一个字符串,表明服务器支持的所有跨域请求的方法。注意,返回的是所有支持的方法,而不单是浏览器请求的那个方法。这是为了避免多次"预检"请求。

Access-Control-Allow-Credentials

Access-Control-Max-Age:预检请求的有限期,单位为秒,在此期间不会再发出预检请求

3、PostMessage

4、Websocket

5、Node中间件代理

6、Nginx反向代理

7、document.domain 只适用于二级域名相同的情况下

8、location.hash

9、window.name 浏览器窗口有window.name属性。这个属性的最大特点是,无论是否同源,只要在同一个窗口里,前一个网页设置了这个属性,后一个网页可以读取它。

Http

http0.9 只有GET请求

http1.0 无状态、无连接 增加了POST HEAD方法 队头堵塞(head of line blocking):一个请求必须在上一个响应到达才能发送

http1.1

长连接,connection:keep-alive,可以保持连接不断开,不用重复建立TCP连接;

管线化,一个TCP连接可以发送多个请求,但是还是未能解决对头阻塞,请求1 请求2 响应1 响应2,如果响应1很慢,还是会阻塞;

增加了缓存相关,Cache-Control, If-Modified-Since, If-None-Match;

增加了 PUT、DELETE、OPTIONS、PATCH 等新的方法

http2.0 多路复用 二进制分帧 头部压缩 服务端推送

所有的Http2.0通信都在一个TCP连接上完成,这个链接可以承载任意流量的双向数据流,每个数据流以消息的形式发送,而消息以一个或多个帧组成,这些帧可以乱序发送,然后再根据每个帧头部的流标识符stream_id重新封装

五层网络模型 应用层 传输层 网络层 链路层 物理层

Cookie

cookie存储在客户端,cookie是服务器发送到用户浏览器并保存到本地的一小块数据,它在浏览器下次向同一服务器再次发起请求时被携带并发送到服务器上。一级二级域名之间允许共享使用cookie

  • NameSize 故名思意

  • Value:保存用户登录状态,应该将该值加密,不能使用明文

  • Path:可以访问此 Cookie 的路径。比如 juejin.cn/editor ,path是/editor,只有/editor这个路径下的才可以读取 Cookie

  • httpOnly:表示禁止通过 JS 访问 Cookie,减少 XSS 攻击。

  • Secure:只能在 https 请求中携带

  • SameSite:规定浏览器不能在跨域请求中携带 Cookie 减少 CSRF 攻击

  • Domain:域名,跨域或者 Cookie 的白名单,允许一个子域获取或操作父域的 Cookie,实现单点登录的话会非常有用

  • Expires/Max-size:指定时间或秒数的过期时间,没设置的话就和 Session 一样关闭浏览器就失效

Https

概念:超文本传输安全协议(英语:Hypertext Transfer Protocol Secure,缩写:HTTPS,常称为HTTP over TLS,HTTP over SSL或HTTP Secure)是一种通过计算机网络进行安全通信的传输协议。HTTPS经由HTTP进行通信,但利用SSL/TLS来加密数据包。HTTPS开发的主要目的,是提供对网站服务器的身份认证,保护交换数据的隐私与完整性。

为什么要有HTTPS: HTTP协议采用明文传输信息,存在信息窃听、信息篡改和信息劫持的风险,而协议TLS/SSL具有身份验证、信息加密和完整性校验的功能,可以避免此类问题发生。

HTTP + tls/ssl = HTTPS

作用:

对数据进行加密,并建立一个信息安全通道,来保证传输过程中的数据安全

对网站服务器进行真实身份认证

工作原理:非对称加密、对称加密、散列函数

利用非对称加密实现身份认证和密钥协商,对称加密算法采用协商的密钥对数据加密,基于散列函数验证信息的完整性

加密解决了信息窃听问题

数字签名解决了信息篡改问题

数字证书解决了信息劫持问题

image.png

区别

  • HTTPS比HTTP更加安全,对搜索引擎更友好,利于SEO,谷歌、百度优先索引HTTPS网页;

  • HTTPS需要用到SSL证书,而HTTP不用;

  • HTTPS标准端口443,HTTP标准端口80;

  • HTTPS基于传输层,HTTP基于应用层;

  • HTTPS在浏览器显示绿色安全锁,HTTP没有显示;

缓存

网络方面的缓存分为三块:DNS缓存HTTP缓存CDN缓存,HTTP缓存又称为浏览器缓存

DNS缓存:找到域名对应的服务器IP地址,再发送请求

递归查询

image.png

在这里任何一步找到就会结束查找流程(整个过程客户端只发出一次查询请求),如果都没有找到,那么就向13根发起解析请求,这就叫迭代查询

image.png

先去DNS根域名(.)服务器查询属于哪个顶级域名,然后根据顶级域名去查询权威域名,拿到IP地址后就可以发起请求。

HTTP缓存:就是将http请求回来的资源缓存在本地,之后再加载直接从缓存拿,从而响应更快

image.png

强缓存

第一次请求时服务器会返回Expires和Cache-Control,Expires指的是资源到期绝对时间,这个时间指的是服务器时间,如果浏览器时间修改了,缓存会失效。

Expires是http1.0的,Cache-Control是http1.1的,主要是为了兼容性,Cache-Control优先级更高

Cache-Control常见的字段:

max-age 缓存有效期 max-stale 缓存过期后的多少秒内依然可用 min-fresh 缓存到期还剩多少秒,就不可以用了 no-cacha 走协商缓存 no-store 不缓存 public 可以被任何终端缓存

强缓存的缺点是缓存过期后,不管资源有没有更新,都会发起请求

协商缓存

第一次请求时,服务器还会返回Last-Modified字段,该资源的最后修改时间,然后在再次请求时再把这个时间通过if-Modified-since传给服务器,服务器对比这两个时间,返回200或者304

Last-Modified的缺点

本地打开了缓存资源,Last-Modified时间会被修改,不能命中协商缓存

Last-Modified只能以秒计,在不可感知的时间内修改了资源,还是会命中协商缓存,无法返回更新后的资源

如果资源周期性变换,然后又修改回去了,还是会被命中协商缓存

针对以上,ETag 出现了,表示这个文件的唯一标识,只有资源的内容变化了,才会更新。再次请求时带上if-none-match字段

Etag的精准度要高于Last-Modified,优先级也更高,但是性能更低,会需要服务器付出额外开销。

优先查找强缓存,没有命中才走协商缓存

启发式缓存:响应中没有ExpiresCache-Control:max-ageCache-Control:s-maxage,并且也不包含其他缓存相关的限制,那么就用Date - Last-Modified的时间乘以10%作为缓存时间

max(0,(Date - Last-Modified)) % 10

实际工作中对于频繁变动的资源,一般设置Cache-Control:no-cache,走协商缓存。不频繁变动的资源配置一个很大的max-age

缓存存放位置

Service-Worker Memory-Cache内存 Disk-Cache 磁盘 Push-Cache

使用 Ctrl+F5 强制刷新页面时,会对本地缓存文件直接过期,然后跳过强缓存和协商缓存,直接请求服务器

点击刷新或 F5 刷新页面时,对本地缓存文件过期,然后带If-Modifed-SinceIf-None-Match发起协商缓存验证新鲜度

浏览器输入URL回车,浏览器查找 Disk Cache,有则使用,没有则发送网络请求

输入URL到页面显示

DNS解析 这里就会涉及到DNS解析的全过程,包括递归查询,迭代查询

建立TCP连接 这个主要说明三次握手的详细过程,以及为啥要三次不是两次

发送HTTP请求

服务器处理请求并返回 这里就要说http缓存

断开连接 这里主要说四次挥手的详细过程

解析HTML,构建 DOM 树

解析 CSS ,生成 CSS 规则树

合并 DOM 树和 CSS 规则,生成 render 树

布局 render 树( Layout / reflow ),负责各元素尺寸、位置的计算

绘制 render 树( paint ),绘制页面像素信息

三次握手

image.png

刚开始客户端处于CLOSED状态、服务端处于LISTEN状态

第一次握手,客户端给服务端发送SYN=1报文 seq=x初始化序列号,此时客户端处于SYN_SEND状态

第二次握手,服务端给客户端发送SYN=1 ACK=1报文 seq=y初始化序列号,ack=x+1确认号,此时服务端处于SYN_RCVD状态

第三次握手,客户端给服务端发送ACK=1报文,seq=x+1序列号,ack=y+1确认号,此时客户端处于ESTABLISHED状态,服务端在收到ACK报文后也将处于ESTABLISHED状态,双方建立连接

为什么需要三次握手:三次握手才能确认双方的接收,发送能力。

半连接队列:在进行第二次握手后,双方还未建立连接,服务端此时处于SYN_RCVD状态,服务器会把此时的请求连接放到一个队列里面,称为半连接队列。

三次握手可以携带数据吗:因为第一二次握手双方还未确认对方的接收能力,如果携带大量数据的话,会遭受到攻击。

SYN攻击:客户端短时间内伪造大量不存在的ip,并向客户端不断发送SYN包,服务端回复包,并等待客户端确认,因为是不存在的ip,客户端会不断地重发直至超时,这些伪造的SYN包将长时间占用半连接队列,导致正常的SYN请求因为队列满了而被丢包。

四次挥手

image.png

刚开始客户端和服务都处于ESTABLISHED状态

第一次挥手,客户端发出FIN=1报文 seq=u序列号,此时客户端处于FIN_WAIT1状态

第二次挥手,服务端发出ACK=1报文 seq=v序列号 ack=u+1确认号,此时服务端处于CLOSE_WAIT,客户端处于FIN_WAIT2状态

第三次挥手,服务端发出FIN=1 ACK=1报文 seq=w序列号 ack=u+1确认号,此时服务器处于LASK_ACK状态

第四次挥手,客户端发出ACK=1报文,seq=u+1序列号 ack=w+1确认好,客户端此时处于TIME_WAIT状态,需要等待2MSL才会进入CLOSED,此时服务端进入CLOSED状态

为什么需要四次挥手:保证数据的完整性,因为第二次握手或服务端报文还未全部发送完成。

MSL:报文段最大生存时间

为什么需要等待2MSL:为了保证客户端发送的ACK报文能顺利到达服务器,因为这个ACK报文可能会丢失,从而导致处于LAST_ACK的服务端接收不到对FIN_ACK的确认报文,服务器超时会重传FIN_ACK报文,接着客户端会重传ACK报文,并重启等待时间。如果不等待2MSL,那么服务端可能会无法正常关闭。