一、什么是跨域?
因为浏览器同源策略,凡是发送请求url的协议、域名、端口三者之间任意一与当前页面地址不一样即为跨域。存在跨域的状况:
网络协议不一样,如http协议访问https协议。
端口不一样,如80端口访问8080端口。
域名不一样,如qianduanblog.com访问baidu.com。
子域名不一样,如abc.qianduanblog.com访问def.qianduanblog.com。
域名和域名对应ip,如www.a.com访问20.205.28.90.
二、跨域请求资源的方法:
(1)、porxy代理
定义和用法:proxy代理用于将请求发送给后台服务器,经过服务器来发送请求,而后将请求的结果传递给前端。
实现方法:经过nginx代理;
注意点:一、若是你代理的是https协议的请求,那么你的proxy首先须要信任该证书(尤为是自定义证书)或者忽略证书检查,不然你的请求没法成功。
(2)、CORS 【Cross-Origin Resource Sharing】
定义和用法:是现代浏览器支持跨域资源请求的一种最经常使用的方式。
使用方法:通常须要后端人员在处理请求数据的时候,添加容许跨域的相关操做。以下:javascript
res.writeHead(200, { "Content-Type": "text/html; charset=UTF-8", "Access-Control-Allow-Origin":'http://localhost', 'Access-Control-Allow-Methods': 'GET, POST, OPTIONS', 'Access-Control-Allow-Headers': 'X-Requested-With, Content-Type' });
(3)、jsonp
定义和用法:经过动态插入一个script标签。浏览器对script的资源引用没有同源限制,同时资源加载到页面后会当即执行(没有阻塞的状况下)。
特色:经过状况下,经过动态建立script来读取他域的动态资源,获取的数据通常为json格式。
实例以下:html
<script> function testjsonp(data) { console.log(data.name); // 获取返回的结果 } </script> <script> var _script = document.createElement('script'); _script.type = "text/javascript"; _script.src = "http://localhost:8888/jsonp?callback=testjsonp"; document.head.appendChild(_script); </script>
缺点:
一、这种方式没法发送post请求(这里)
二、另外要肯定jsonp的请求是否失败并不容易,大多数框架的实现都是结合超时时间来断定。前端
Undefined、Null、Boolean、Number、String
这个题目的意义在哪里?我想,应该是对于一些特定的业务逻辑,好比在注册一个“通知”的事件,在与Native交互以后,假设这个交互是在入口级别的页面里,那么如何发送给具体某个业务呢?事件应该是最简单的一种方式,在某个具体的业务中注册一个事件,而后在与Native交互完,拿到某些数据后,而后触发这个事件。java
咱们来一步一步实现一个最简单的事件类Event,不考虑任何其余复杂的状况。假设在这个Event类的内部有一个this._events = [] 数组来维系整个事件系统,咱们分别实现on,off,emit三个方法便可。nginx
on(注册一个事件):json
Event.prototype.on = function(type,fun){ let cbs = this._events[type]; cbs ? cbs.push(fun) : this._events[type] = []; if (!cbs) { this._events[type].push(fun) } }
这里为何要将this._events设计为二维数组?由于事件能够是多个,可是事件名可能相同。这个逻辑意图很是的明显,根据type参数从this._events中获取是否存在。若是不存在,建立一个type为key的数组,并将事件句柄程序push到数组中。后端
off(注销一个事件):跨域
Event.prototype.off = function(type,fun){ let cbs = this._events[type]; //事件列队中无事件 if (!cbs) { return this; } //删除全部的事件 if (!event && !fun) { this._events = {}; return this; } //只有事件名称时 if (event && !fun) { this._events[type] = null; return this; } //删除某个事件队列中的某个事件 let cb; let i = cbs.length; while(i--){ cb = cbs[i]; if (cb === fun || cb.fun === fun) { cbs.splice(i,1); break; } } }
虽然注销事件方法的逻辑可能相比之下稍许多了些,但它的实现也很是简单,只要只存在事件组key名的状况,或者删除某个事件队列中的某个事件句柄程序便可。数组
emit(触发一个事件):浏览器
Event.prototype.emit = function(type){ let cbs = this._events[type]; let args = tools.toArray(arguments,1); if (cbs) { let i = 0; let j = cbs.length; for(;i<j;i++){ let cb = cbs[i]; cb.apply(this,args); } } }
逻辑依然很是简单,经过事件名从this._events获取相应的事件句柄程序数组,而后将arguments转成数组,(这里考虑的是可能会传入参数)若是事件句柄程序数组存在,进行循环,再讲args参数apply给每个取出来的事件句柄程序。
一个网页从请求到最终显示的完整过程通常能够分为以下7个步骤: (1)在浏览器中输入网址; (2)发送至DNS服务器并得到域名对应的WEB服务器IP地址; (3)与WEB服务器创建TCP链接; (4)浏览器向WEB服务器的IP地址发送相应的HTTP请求; (5)WEB服务器响应请求并返回指定URL的数据,或错误信息,若是设定重定向,则重定向到新的URL地址; (6)浏览器下载数据后解析HTML源文件,解析的过程当中实现对页面的排版,解析完成后在浏览器中显示基础页面; (7)分析页面中的超连接并显示在当前页面,重复以上过程直至无超连接须要发送,完成所有数据显示。
Web Storage有两种形式:LocalStorage(本地存储)和sessionStorage(会话存储)。 这两种方式都容许开发者使用js设置的键值对进行操做,在在从新加载不一样的页面的时候读出它们。这一点与cookie相似。 (1)与cookie不一样的是:Web Storage数据彻底存储在客户端,不须要经过浏览器的请求将数据传给服务器,所以x相比cookie来讲可以存储更多的数据,大概5M左右。 (2)LocalStorage和sessionStorage功能上是同样的,可是存储持久时间不同。 LocalStorage:浏览器关闭了数据仍然能够保存下来,并可用于全部同源(相同的域名、协议和端口)窗口(或标签页); sessionStorage:数据存储在窗口对象中,窗口关闭后对应的窗口对象消失,存储的数据也会丢失。 注意:sessionStorage 均可以用localStorage 来代替,但须要记住的是,在窗口或者标签页关闭时,使用sessionStorage 存储的数据会丢失。 (3)使用 local storage和session storage主要经过在js中操做这两个对象来实现,分别为window.localStorage和window.sessionStorage. 这两个对象均是Storage类的两个实例,天然也具备Storage类的属性和方法。