1.赫夫曼树
2.跨域
- 同源
- 同源策略:是一种约定,也是浏览器最核心也最基本的安全功能。
- 同源:域名、协议、端口相同,也就是在一个域里。
- 非同源受到的限制:cookie不能读取、dom无法获得、ajax请求不能发送。
- 分类
- DOM同源策略:禁止对不同源页面的DOM进行操作。主要的场景是iframe跨域的情况,不同域名的iframe是限制互相访问的。
- Ajax同源策略:禁止使用XHR对象向不同源的服务器地址发起HTTP请求。
跨域:一个域的页面去请求另一个域的资源 如何解决?
- 跨域解决方式
- JSONP:利用script标签 src 属性没有跨域限制的漏洞,包含回调函数和json数据
- 优点:兼容性好,简单易用;
- 缺点:仅支持GET方法,一般支持老式浏览器,不安全可能会遭受XSS攻击。
- CORS(跨站资源共享):支持所有的请求方法,只服务端设置Access-Control-Allow-Origin即可,前端无须设置,若要带cookie请求:前后端都需要设置。
- 客户端,我们还是正常使用xhr对象发送ajax请求。唯一需要注意的是,我们需要设置我们的xhr属性withCredentials为true,不然的话,cookie是带不过去的哦,设置: xhr.withCredentials = true;
- 服务器端,需要在 response header中设置如下两个字段: Access-Control-Allow-Origin: http://www.yourhost.com Access-Control-Allow-Credentials:true
- JSONP:利用script标签 src 属性没有跨域限制的漏洞,包含回调函数和json数据
- document.domain+iframe: 主域名相同情况下,将子域和主域document.domain设为同一个主域,前提条件:这两个域名必须属于同一个基础域名,而且所用的协议,端口都要一致
- Websocket:web sockets是一种浏览器的API,它的目标是在一个单独的持久连接上提供全双工、双向通信。(同源策略对web sockets不适用)。
- 原理
- 在JS创建了web socket之后,会有一个HTTP请求发送到浏览器以发起连接
- 取得服务器响应后,建立的连接会使用HTTP升级从HTTP协议交换为web sockt协议。只有在支持web socket协议的服务器上才能正常工作。
- 原生WebSocket API使用起来不太方便,我们使用Socket.io,它很好地封装了webSocket接口,提供了更简单、灵活的接口,也对不支持webSocket的浏览器提供了向下兼容。
- 原理
- window.name + iframe: 在一个窗口(window)的生命周期内,窗口载入的所有的页面都是共享一个window.name的,每个页面对window.name都有读写的权限,window.name是持久存在一个窗口载入过的所有页面中的。 name 值在不同的页面(甚至不同域名)加载后依旧存在,并且可以支持非常长的 name 值(2MB)。
- postMessage:(HTML5新增)
- a.com/index.html中的代码
<iframe id="ifr" src="b.com/index.html"></iframe>
<script type="text/javascript">
window.onload = function() {
var ifr = document.getElementById('ifr');
var targetOrigin = 'http://b.com';
// 若写成'http://b.com/c/proxy.html'效果一样
// 若写成'http://c.com'就不会执行postMessage了
ifr.contentWindow.postMessage('I was there!', targetOrigin);
};
</script>
- b.com/index.html中的代码
window.addEventListener('message', function(event){
// 通过origin属性判断消息来源地址
if (event.origin == 'http://a.com') {
alert(event.data); // 弹出"I was there!"
alert(event.source); // 对a.com、index.html中window对象的引用 // 但由于同源策略,这里event.source不可以访问window对象
}
}, false);
3.setTimeout定时器原理
- Js线程读到定时器时,此时会执行浏览器线程,跳过定时器继续执行后面的代码,将定时器任务放入事件队列中,等待js引擎空闲后的调用
- 在setTimeout内部,this绑定采用默认绑定规则,也就是说,在非严格模式下,this会指向window;而在严格模式下,this指向undefined
for (var i = 0; i < 5; i++) {
console.log(i);
setTimeout(function timer() {
console.log(i);
}, i * 1000);
} //依次输出:0, 1, 2, 3, 4 接着输出5个5
- javascript是单线程语言,只有主线程上的所有同步任务执行完毕,主线程才会读取任务队列上的异步任务。for循环属于同步任务,而定时器属于异步任务。所以会在for循环结束之后才开始执行定时器的代码。因此会输出5个5。