前端网络:http,cors,https

581 阅读25分钟

1.一个网址中我们能得到什么信息

一个完整的网址包含了:协议;域名;解析名;端口号;根目录;访问的文件路径;访问的文件名;参数;锚点。

协议://用户名:密码@主机名:端口号/路径?查询参数=值#标志

www.example.com:80/foo?source=…

协议      域名                        端口 路径   查询         锚点

1.可以知道网址的性质:

常见的有com,net,cn,com.cn

.net是网络服务公司,为个人或是商业提供服务也是国际域名

.com是提供商业服务的网站

.cn是中国的域名

.com.cn是中国的公司域名

.com注册管理在美国  .cn注册管理在中国

.com(商业结构)  .net(从事互联网服务的机构) .org(非盈利性组织)

.com.cn(国内商业机构).net.cn(国内互联网机构) .org.cn(国内非盈利性组织)

.gov(国家政府机构)

2.可以读出这个网址的级别

一级域名:baidu.com

二级域名:zhidao.baidu.com

2.跨域

  • 跨域是什么,为社么要跨域
  • 浏览器的同源策略是什么
  • 跨域的原理是什么
  • 解决跨域的方法有哪些

当两个域有相同的协议(如http),相同端口,相同的host(如www.baidu.com),则认为它们是相同的域(协议,域名,端口都必须要一致),否则就是跨域

**同源策略:**同源策略是一种约定,它时浏览器最核心也是最基本的安全功能,如果缺少了同源                   策略,则一些机密网站的数据就不能够得到保护

                  它约定请求的url地址,必须与浏览器的url地址处于同域上,也就是协议,域名,                      端口都相同,如果不同就会报错

为什么要有跨域资源限制访问:

从DOM同源策略和XMLHttpRequest同源策略分析:

如果没有DOM同源策略,也就是说不同域的iframe之间可以相互访问,那么黑客可以这么攻击

  1. 做一个假网站,里面用iframe嵌套一个银行网站
  2. 把iframe宽高调整到页面全部,这样用户进来除了域名,别的和银行网站没有任何差别
  3. 这是如果用户输入账号密码,我们的主网站可以跨域访问到银行的dom节点,就可以拿到用户的账户密码了

如果XMLHttpRequest同源策略,那么黑客可以进行CSRF(跨站请求伪造)攻击:

  1. 用户登录了自己的银行页面,银行页面向用户的cookie中添加用户标识
  2. 用户浏览了恶意页面,执行了页面中恶意AjAX请求代码
  3. 恶意页面向银行页面发起Ajax请求,请求默认把银行页面对应的cookie也同时发送过去了
  4. 银行页面从发送的cookie中提取用户标识,验证用户无误,response中返回请求数据,此时数据就泄露了
  5. 而且由于Ajax在后台执行,用户无法感知这一过程。

可以从服务器和客户端两个方面分析

  • 对于服务器,当收到一个请求时,会检查该请求来源,如果来源的客户端页面自己无法识别,而且服务器的数据又是比较敏感的,则可能做出限制或者拒绝访问(例如黑客对服务器的攻击)
  • 对于客户端,浏览器的同源策略可限制对跨域资源的访问,若其与服务器的域不相同,则浏览器可能进行限制甚至拒绝访问(如,黑客通过让你访问它的服务器数据来攻击你的客户端页面)

跨域解决方案

  1. 通过jsonp跨域
  2. document.domain + iframe 跨域
  3. location.hash + iframe
  4. window.name + iframe 
  5. postMessage
  6. 跨域资源共享(cors)
  7. nginx代理跨域
  8. nodejs中间件代理跨域
  9. weSocket协议跨域
  • 通过jsonp实现

  • 通常为了减轻web服务器的负载,我们把js,css,img等静态资源分离到另一台独立域名的服务器上,在html页面中在通过相应的标签从不同域名下加载静态资源,而被浏览器允许,基于此原理,我们可以通过动态创建script,在请求一个带参网址实现跨域通信

    <script>
      var script = document.createElement('script')
    script.type="text/javascript"
    script.src="http://domain2.com/login?user=admin&callback=onBack"
    document.head.appendChild(script)
    function onBack(res){
        ....
    }</script>
    
  • 跨域资源共享(CORS)

       CORS,跨域资源共享,它需要浏览器和服务器同时支持,目前所有浏览器支持该功能,           ie10以下不支持

        要实现CORS通信,主要是在服务器,也就是获得数据的一方做处理

         CORS基本的流程

  • 浏览器将请求分为两类,一类是简单请求,一类是复杂请求,满足下列条件的就是简单请求,否则是复杂请求

    //条件: // 1、请求方式:HEAD、GEt、POST // 2、请求头信息: Accept Accept-Language content-language last-event-id content-type application/x-www-form-urlencoded或multipart/form-data或text/plain

    // 同时满足以上两个条件时,则是简单请求,否则为复杂请求        

  • 简单请求和复杂请求的区别: 简单请求:一次请求,非简单请求:两次请求,在发送数据之前会先发第一次请求做预检,只有预检通过以后再发一次请求作为数据传输

  • 关于预检:

    请求方式:OPTIONS
    预检其实做检查,检查如果通过则允许传输数据,检查不通过则不再发送真正想要发送的信息
    如何预检
         如果复杂请求时put等请求,则服务端需要设置允许莫请求,否则预检不通过
          Access-Control-Request-Method
    如果复杂请求设置了请求头,则服务端需要设置允许某请求头,否则预检不通过
          Access-Control-Request-Headers: X-PINGOTHER, Content-Type
    
  • 普通跨域请求:只服务端设置Access-Control-Allow-Origin即可,前端无须设置

    简单请求:
        客户端正常请求
        服务端需要设置Access-Control-Allow-Origin :'值'
    复杂请求:
        客户端:contentType:'application/json'
        服务端:Access-Control-Allow-Headers: 'Content-Type'
               Access-Control-Allow-Origin: 'http://www.example.com'
    
  • 带cookie请求:前后端都需要设置字段,另外需注意:所带cookie为跨域请求接口所在域的cookie,而非当前页

           前端设置:需要带cookie时需要设置withCredentials

           后端设置:Access-Control-Allow-Credentials:true  // 后端允许发送cookie

                            Access-Control-Allow-Origin: www.example.com // 允许访问的                               域

  • jsonp和CORS的优缺点

    // 1.jsonp的主要优势在于对浏览器的支持较好;虽然目前著浏览器支持CORS,但IE10以下不支持CORS
    // 2.jsonp只能由于获取资源(类似于GET请求);CORS支持所有类型的HTTP请求,功能完善
    // 3.JSOP的错误处理机制不完善,没办法进行错误处理;CORS可以通过onerror事件监听错误,并且浏览器控制台会看到报错信息利于排查
    // 4.jsonp只会发一次请求,对于复杂请求,会发送两次请求
    
  • nginx代理跨域

  • nginx配置解决iconfont跨域,浏览器跨域访问js,css,img等常规静态资源被同源策略许可但iconfont字体文件(eot|otf|ttf|woff|svg)例外,此时可在nginx的静态资源服务其中加入nginx配置

    location/ { add_header Access-Control-Allow-Origin *; }

  • nginx反向代理接口跨域 

               跨域原理:同源策略时浏览器的安全策略,不是HTTP协议的一部分。服务器端调用                                  HTTP接口只是使用HTTP协议,不会执行JS脚本,不需要同源策略,也                                    就不存在跨域问题

                实现思路:通过nginx配置一个代理服务器(域名与domain1相同,端口不同)做                                     跳板机,反向代理访问domain2接口,并且可以顺便修改cookie中的                                       domain信息,方便当前域cookie写入,实现跨域登录

                 nginx具体配置:

// proxy服务器
server{
    listen 81;
    server_name www.domain1.com;
    location / {
        proxy_pass http://www.domain2.com:8080; # 反向代理
        proxy_cookie_domain www.domain2.com www.domain1.com; #修改cookie域名
         index index.html index.htm;
        # 当前webpack-dev-server等中间件代理接口访问nginx时,此时五浏览器参与,故没有同源限制,下面的跨域配置可不启用
        add_header Access-Constrol-Allow-Origin http://www.domain1.com; #当前端只跨域不带cookie时,可为*
        add_header Access-Control-Allow-Credentials true;
    }
}

3.cookie,localStorage,sessionStorage

  • 存储大小不同

    // localStorage的大小一般为5M
    // sessionStorage  5M
    // cookies    4k
    
  • 有效期不同

    localStorage 永久有效,除非删除
    sessionStorage 当下有效
    cookies 设置的有效期内有效
    
  • 服务器端的通信

    localStorage 不参与服务端通信
    sessionStorage 不参与
    cookies参与服务端通信,被携带在http的头信息中
    

4.xhr的readyState的值的意义

xhr.readyState
0:请求未初始化,还没有调用open()
1.请求已经建立,但是还没有发送,还没有调用send()
2:请求已发送,正在处理中(通常现在可以从响应中获取内容头)
3:请求在处理中,通常响应中已有部分数据可用了,没有全部完成
4:响应已完成,可以获取并使用服务器的响应了

var xhr = new XMLHttpRequest()
xhr.open("GET","http://www.baidu.com",true)
xhr.onreadystatechange = function(){
    if((xhr.readyState ===4)&& (xhr.status == 200)){
        var result = xhr.response
    }
}
xhr.send(null)

5.cors跨域请求

// nginx
server{
    //1 授权的访问源
    add_header Access-Control-Allow-Origin * always; 
    //2 额外允许请求动词
    add_header Access-Control-Allow-Methods GET,PUT,POST,HEAD,OPTIONS always; 
    //3 额外允许携带的请求头
    add_header Access-Control-Allow-Headers Keep-Alive,Content-Type,Range always;
    //4 额外允许访问的响应头
    add_header Access-Control-Expose-Headers Content-Range,Content-Lenght,Accept-Ranges always;
    //5 预检的有效期
    add_header Access-Control-Max-Age 86400;    //6 是否允许携带cookie  在前端请求时需要 设置xhr.withCredentials = true;
    // 当为true时,不允许Access-Control-Allow-Origin 为*否则报错
    add_header Access-Control-Allow-Credentials true;
}

6.预检请求 preflight request

// 出现于预检中,是浏览器自动发起的请求
//  出现于预检请求中,通知服务器在真正的请求中会采用哪些请求头
Access-Control-Request-Headers: Content-Type; 
//  出现于预检请求中,通知服务器真正的请求中会使用那种http请求
 Access-Control-Requst-Methods: POST;
Origin:https://foo.example.com

返回

Access-Control-Allow-Origin:https://foo.example.com
Access-Control-Allow-Methods:POST,GET,OPTIONS;
Access-Control-Max-Age:86400;

6.https中设置证书(nginx)

server{
    ssl_certificate_key /xxx/xxxx/xxxx/cert.key;
    ssl_session_timeout 30m;
    ssl_certificate /xxx/xxx/xxx/cert.crt;
    listen 9029 ssl;
}

7. 从输入URL到页面加载发生了什么?

1:浏览器进程发出URL请求给网络进程

2:网络进程接收到URL请求之后,便发起网络请求,然后服务器返回HTTP数据到网络进程,网络进程解析HTTP出来响应头数据,并将其转发给浏览器进程

3:浏览器进程接收到网络进程的响应头数据之后,发送CommitNavigation消息到渲染进程,发送CommitNavigation时会携带响应头、等基本信息。

4:渲染进程接收到CommitNavigation消息之后,便开始准备接收HTML数据,接收数据的方式是直接和网络进程建立数据管道

5:最后渲染进程会像浏览器进程“确认提交”,这是告诉浏览器进程,说我已经准备好接受和解析页面数据了

6:最后浏览器进程更新页面状态

  1. DNS解析
  2. TCP连接
  3. 发送http请求
  4. 服务器处理请求并返回HTTP报文
  5. 浏览器解析渲染页面
  6. 连接结束

优化:

  • 浏览器直接缓存数据
  • DNS优化 DNS缓存,DNS负载均衡(DNS重定向-CDN)
  • 内容压缩
  • 减少浏览器回流重绘

8.https是采用 非对称加密+对称加密相结合的方式来进行加密

(1)服务器拥有一个公钥A,一个私钥B

(2)浏览器向服务器发起请求,服务器就把公钥A明文传输给浏览器

(3)浏览器拿到公钥A后,随机生成一密钥X,然后用公钥A进行加密传输给服务器

(4)服务器拿到后,用私钥B进行解密得到密钥X

(5)这时候浏览器和服务器手头上都有密钥X,之后就会用这个密钥X来进行对称性加解密

9.状态码

  • 1**  信息,服务器收到请求,需要请求者继续执行操作
  • 2**  成功,操作被成功接收并处理
  • 3** 重定向,需要进一步的操作已完成请求
  • 4** 客户端错误,请求包含语法错误或无法完成请求
  • 5** 服务器错误,服务器在处理请求的过程中发生了错误

301: 永久移动,请求的资源已被永久的移动到新的URI,返回信息会包括新的URI,浏览器会自动定向到新URI,今后任何新的请求都应使用新的URI代替

302: 临时移动,资源只是临时被移动.客户端应继续使用原有URI

303 查看其他地址,与301类似,使用GET和POST请求查看

304: 未修改,所请求的资源未被修改,服务器返回此状态码时,不会返回任何资源,客户端通常会访问缓存的资源

305: 使用代理,所请求的资源必须通过代理访问

10.http通信传输

客户端输入URL回车,DNS解析域名得到服务器的IP地址,服务器在80端口监听客户端请求,端口通过TCP/IP协议建立连接。HTTP属于TCP/IP模型中的运用层协议,所以通信的过程其实是对应数据的入栈和出栈。

发送端:没通过一层增加一个首部

应用层(Http数据http报文)

->传输层(TCP首部)

->网络层(IP首部)

->链路层(以太网首部)

**应用层:**负责向用户提供一组应用程序,比如HTTP、FTP、DNS等

**传输层:**负责端到端的通信,比如TCP、UDP等

**网络层:**负责网络包的封装、寻址和路由,比如IP、ICMP等

**链路层:**负责网络包在物理网络中的传输,比如MAC寻址、错误侦测以及通过网卡传输网络帧等。

传输层在应用程序数据前面增加了 TCP 头;
网络层在 TCP 数据包前增加了 IP 头;
而网络接口层,又在 IP 数据包前后分别增加了帧头和帧尾。

接收端:没通过一层则删除一个首部

链路层(以太网首部)->网络层(IP首部)->传输层(TCP首部)->应用层(Http数据http报文)

报文从运用层传送到运输层,运输层通过TCP三次握手和服务器建立连接,四次挥手释放连接。

11.get和post的区别

  1.  get在浏览器回退时时无害的,而post会再次提交请求
  2. get产生的URL地址可以被bookmark,而post不可以
  3. get请求会被浏览器主动cache,而post不会,除非手动设置
  4. get请求只能进行URL编码,而post支持多种编码方式
  5. get请求参数会被万众保留在浏览器历史记录里,而post中的参数不会被保留
  6. get请求在URL中传送的参数是有长度限制的,而post没有
  7. 对参数的数据类型,get只接受ASCII字符,而post没有限制
  8. get比post更不安全,因为参数直接暴露在URL上,所以不能用来传递敏感信息
  9. get参数通过URL传递,post放在request body中

其实get和post本质上没有区别

get和post是HTTP协议中的两种发送请求的方法,HTTP的底层是tcp/ip,所以get和post底层也是tcp/ip,也就是说,get/post都是tcp链接。get和post能做的事情是一样的。你要给get加上 request body,给post带上url参数,技术上是完全行得通的。

因此上面的区别都是HTTP协议的规范。HTTP协议是行为准则,而TCP才是get和post实现的基本。

不同的浏览器和服务器对get/post的行为规范

浏览器通常会限制url的长度2k字节,服务器最多处理64k的url,如果你使用get请求,在request body中添加了数据,不同的服务器处理方式也是不同的,有的会读出数据,有的直接忽略。

GET和POST本质上就是TCP链接,并无差别。但是由于HTTP的规定和浏览器/服务器的限制,导致他们在应用过程中体现出一些不同。

get和post还有一个重大区别,简单说,get产生一个TCP数据包,post产生两个TCP数据包

对于get请求浏览器会把http header和data 一并发送出去,服务器响应200(返回数据)

而对于post,浏览器先发送header,服务器响应100continute,浏览器在发送data,服务器响应200(返回数据)

Firefoxpost请求只会发送一次

12.cookie,session,token

因为http是一个无状态协议,不会及以上一次请求,比如一些登录功能的请求,每次都需重新识别区分用户,而cookie、session和token的发明都能够明确服务端在为哪个客户端服务。

cookie:

1.cookie是保存在客户端本地的数据,是一个很小的文本文件

2.新用户访问,客户端浏览器发送httprequest给服务端

3.服务端生成cookie给浏览器

4.浏览器,将服务器发送的cookie以键值对形式保存至本地

5.在浏览器上,再一次请求同一个网站,把该cookie发送给服务器,服务器检查到请求有cookie,则知道之歌用户之前有过交互

6.cookie是存储在客户端上,所以浏览器加入了一些限制确保cookie不会被恶意使用,只允许被创建的的域对cookie进行读写;cookie的过期时间一般在关闭浏览器就会自动删除,当然也可以进行一些设置使其有效期更长一些;同时不会占太多磁盘空间,浏览器最多允许存放300个cookie,每个文件大小在4kb的限制,同时每个鱼的cookie的数量最多20个,如果达到上限,浏览器就会自动随机对cookie文件进行删除

session:

1.session会话的意思,session是保存在服务器端的数据

2.当用户打开访问服务器时,此时服务器就会产生一次session,并且为客户端分配一个session_id,客户端保存下来,之后客户端每次请求时都带着这个session_id,可以理解为客户端篡改也没用,因为服务端保存了这个session_id,会对请求的session_id进行校验

3.服务器使用session把用户的信息临时保存在了服务器上一般是内存,硬盘,或者数据库,用户离开后session会被销毁

token:

1.token的意思是令牌,是用户的身份验证方式

2.当用户第一次登录后,服务器生成一个token,并将此token返回给客户端,客户端保存此token

3.之后请求只需带上这个token前来请求数据即可,无需再次带上用户名和密码

4.服务端收到请求,然后去验证客户端请求里面带着的token,如果验证成功,就像客户端返回数据

5.同时token也可以设置有效期,可以在每次请求时验证token及有效期token是无状态、可扩展在服务端的内存中是不存储的,支持移动设备,跨程序调用,更加安全

cookie,session,token的区别

1.cookie数据存放在客户端的浏览器中,session数据放在服务器上

2.cookie的大小及文件数量是有限制的

3.cookie是不安全的,可以分析存放在本地 的cookie通过模拟请求来刷接口,当然真正实现中肯定会有防篡改机制,如果用只有客户端和服务端知道的密钥生成签名,但由于cookie是明文,所以一般不会放敏感信息。

4.session保存在服务端,相对安全,同时只需要客户端保存一个session_id,能够解决cookie存在的安全性问题

5.session是存储在服务器的文件,如果web服务器做了负载均衡,那么下一个操作请求到了另一台服务器的时候session会丢失

6.token可以避免CSRF攻击,token的状态是存储在客户端,token可以是无状态的,顶多是失效后,重新登录,同时可以在多个服务间共享。

13.COOKIE & SESSION

1、存储位置不同
cookie的数据信息存放在客户端浏览器上。
session的数据信息存放在服务器上。
2、存储容量不同
单个cookie保存的数据<=4KB,一个站点最多保存20个Cookie。
对于session来说并没有上限,但出于对服务器端的性能考虑,session内不要存放过多的东西,并且设置session删除机制。
3、存储方式不同
cookie中只能保管ASCII字符串,并需要通过编码方式存储为Unicode字符或者二进制数据。
session中能够存储任何类型的数据,包括且不限于string,integer,list,map等。
4、隐私策略不同
cookie对客户端是可见的,别有用心的人可以分析存放在本地的cookie并进行cookie欺骗,所以它是不安全的。
session存储在服务器上,对客户端是透明对,不存在敏感信息泄漏的风险。
5、有效期上不同
开发可以通过设置cookie的属性,达到使cookie长期有效的效果。
session依赖于名为JSESSIONID的cookie,而cookie JSESSIONID的过期时间默认为-1,只需关闭窗口该session就会失效,因而session不能达到长期有效的效果。
6、服务器压力不同
cookie保管在客户端,不占用服务器资源。对于并发用户十分多的网站,cookie是很好的选择。
session是保管在服务器端的,每个用户都会产生一个session。假如并发访问的用户十分多,会产生十分多的session,耗费大量的内存。
7、浏览器支持不同
假如客户端浏览器不支持cookie:
cookie是需要客户端浏览器支持的,假如客户端禁用了cookie,或者不支持cookie,则会话跟踪会失效。关于WAP上的应用,常规的cookie就派不上用场了。
运用session需要使用URL地址重写的方式。一切用到session程序的URL都要进行URL地址重写,否则session会话跟踪还会失效。
假如客户端支持cookie:
cookie既能够设为本浏览器窗口以及子窗口内有效,也能够设为一切窗口内有效。
session只能在本窗口以及子窗口内有效。
8、跨域支持上不同
cookie支持跨域名访问。
session不支持跨域名访问。 

14.前端路由的两种模式:hash模式和history模式

单页面应用利用了Javascript动态变换网页内容,避免了页面重载;路由则提供了浏览器地址的变化,网页内容也跟随变化,两者结合起来则为我们提供了体验良好的单页面web应用

前端路由实现方式

路由需要实现三个功能:

  1. 当浏览器地址变化时,切换页面
  2. 点击浏览器后退、前进按钮网页内容跟随变化
  3. 刷新浏览器,网页加载当前路由对应内容

在单页面web网页中,单纯的浏览器地址改变,网页不会重载,如单纯的hash网址改变网页不会改变,因此我们的路由主要时通过监听事件,并利用js实现动态改变网页内容,有两种实现方式:

  • hash模式:监听浏览器地址hash值变化,执行相应的js切换网页;
  • history模式:利用historyAPI实现url地址改变,网页内容改变;

最大的区别是最明显的就是hash会在浏览器地址后面增加#号,而history可以自定义地址

hash模式

使用window.location.hash 属性及窗口的onhashchange事件,可以实现监听浏览器地址hash值变化,执行相应的js切换网页。

  1. hash指的是地址中#号以及后面的字符,也成为散列值。hash也称作锚点,本身是用来做页面跳转定位的
  2. 散列值是不会随请求发送到服务器端的,所以改变hash,不会重新加载页面
  3. 监听window的hashchange事件,当散列值改变时,可以通过location.hash来获取和设置hash值
  4. location.hash指的变化会直接反应到浏览器地址栏

触发hashchange事件的几种情况

  • 浏览器地址栏散列值的变化(包括浏览器的前进、后退)会触发window.location.hash值的变化,从而触发onhashchange事件
  • 当浏览器地址栏中url包含哈希如www.baidu .com/#home,这时按下输入,浏览器发送www.baidu.com/请求至服务器,请求完毕…
  • 当只改变浏览器地址栏URL的哈希部分,这时按下回车,浏览器不会发送任何请求至服务器,这是发生的只是设置散列值新修改的哈希值,并触发onhashchange事件
  • html中a标签属性href可以设置为页面的元素ID如#top,当点击该链接时页面跳转至该id元素所在区域,同时浏览器自动设置window.location.hash属性,地址栏中的哈希值也会发生改变,并触发onhashchange事件

history模式

  • window.history属性指向history对象,他表示当前窗口的浏览历史。当发生改变时,只会改变页面的路径,不会刷新页面
  • history对象保存了当前窗口访问过的所有页面网址。通过history.length可以得出当前窗口一共访问过几个网址
  • 由于安全原因,浏览器不允许脚本读取这些地址,但是允许在地址之前导航
  • 浏览器工具栏的前进和后退按钮,其实就是对history对象进行操作

属性

history对象主要有两个属性

  • History.length:当前窗口访问过的网址数量(包括当前网页)

  • History.state:History堆栈最上层的状态值

    // 当前窗口访问过多少个网页 histoy.length // History history.state //undefined

方法

  • History.back():移动到上一个网址,等同于点击浏览器的后退键。对于第一个访问的网址,该方法无效
  • History.forward():移动到下一个网址,等同于点击浏览器的前进键,对于最后一个访问的网址,该方法无效
  • History.go():接受一个整数作为参数,以当前网址为基准,移动到参数指定的网址。如果参数超过实际存在的网址范围,该方法无效,如果不设置参数,默认参数为0,相当于刷新当前页面

注意:移动以前访问过的页面时,页面通常是从浏览器缓存中加载,而不是重新要求服务器发送新的网页

History.pushState()

该方法用于在历史中添加一条记录。pushState()方法不会触发页面刷新,只是导致History对象变化,地址栏不会有变化

该方法接受三个参数,依次为:

  •  object:是一个对象,通过 pushState 方法可以将该对象内容传递到新页面中。如果不需要这个对象,此处可以填 null。 
  • title:指标题,几乎没有浏览器支持该参数,传一个空字符串比较安全。 
  • url:新的网址,必须与当前页面处在同一个域。不指定的话则为当前的路径,如果设置了一个跨域网址,则会报错。 

注意:如果pushState的URL参数设置了一个新的锚点值(hash值),并不会触发hashchange事件,反过来,如果URL的锚点变了,则会在history对象中创建一条记录

pushState 想要插入一个跨域的网址,导致报错。这样设计的目的是,防止恶意代码让用户以为他们是在另一个网站上,因为这个方法不会导致页面跳转。

History.replaceState()

该方法用来修改 History 对象的当前记录,用法与 pushState() 方法一样。

假定当前网页是 example.com/example.html。

popState事件

每当history对象出现变化时,就会触发popState事件

注意:

  • 仅仅调用pushState()方法或replaceState()方法,并不会触发该事件
  • 只有用户点击浏览器倒退按钮和前进按钮,或者使用javaScript调用History.back()、history.forword(),history.go()方法时才会触发
  • 另外,该事件只针对一个文档,如果浏览历史的切换,导致加载不同的文档,该事件也不会触发
  • 页面第一次加载的时候,浏览器不会触发popstate事件

使用的时候,可以为popstate事件指定回调函数,回调函数的参数是一个event事件对象,他的state属性指向当前的state对象

window.addEventListener('popstate', function(e) {
	//e.state 相当于 history.state
	console.log('state: ' + JSON.stringify(e.state));
	console.log(history.state);
});

history 致命的缺点就是当改变页面地址后,强制刷新浏览器时,(如果后端没有做准备的话)会报错,因为刷新是拿当前地址去请求服务器的,如果服务器中没有相应的响应,会出现 404 页面。

总结:

  • hash模式主要时通过监听hashchange事件获得hash值的改变,从而改变网页的内容
  • history模式主要是通过监听popstate事件获得history对象的改变,从而改变网页的内容

TCP

TCP 三次握手和四次挥手 javaguide.cn/cs-basics/n…

  1. 客户端向服务端发送信息 客户端进入 syn_send状态
  2. 服务端收到信息并向客户端发送信息 服务端进入 syn_recv状态
  3. 客户端收到服务端发送的信息然后发送信息给服务端 然后客户端和服务端都进入 established状态
  • 第一次握手:Client 什么都不能确认;Server 确认了对方发送正常,自己接收正常

  • 第二次握手:Client 确认了:自己发送、接收正常,对方发送、接收正常;Server 确认了:对方发送正常,自己接收正常

  • 第三次握手:Client 确认了:自己发送、接收正常,对方发送、接收正常;Server 确认了:自己发送、接收正常,对方发送、接收正常