json jsonp
- json是一种数据格式;
- jsonp是一种数据调用格式,带callback的json就是jsonp
- 利用script标签没有跨域限制的“漏洞”来达到与第三方通讯的目的。当需要通讯时,本站脚本创建一个script元素,地址指向第三方的API网址,并提供一个回调函数来接收数据(函数名可约定,或通过地址参数传递)。第三方产生的响应为json数据的包装(故称之为jsonp,即json padding),形如:callback({“name”:”hax”,”gender”:”Male”}) 这样浏览器会调用callback函数,并传递解析后json对象作为参数。本站脚本可在callback函数里处理所传入的数据。主要是利用了html标签的src属性没有同源限制,也就是支持跨域
domready onroad
- 首先要清楚dom文档加载的步骤为:1.解析html结构;2.加载外部脚本和样式表文件;3解析并执行脚本;4.dom树构建完成;5.加载图片等外部文件;6.页面加载完毕。domready(也叫DOMContentLoaded ),在第4步完成后触发;图片onload是在第5步完成后触发;页面onload是第6步完成后触发。由此可见三者执行顺序为:domready→图片load→页面load。
- domready和onload事件区别,前者:在DOM文档结构准备完毕后就可以对DOM进行操作;后者:整个document文档(包括图片等加载信息)加载完成后才能对DOM进行操作。关键区别就在于后者需要等待图片等资源加载完毕后才执行
js事件(捕获 冒泡)
- dom2级事件
- 事件流:从页面接收事件的顺序,主要分为事件冒泡流和事件捕获流
- 事件冒泡:事件从嵌套层次最深的最具体的元素接收,然后逐级向上传播到不具体的节点;事件捕获则反之
- 三个阶段:捕获阶段、目标阶段、冒泡阶段
事件处理程序:dom0级、dom2级:addEventListener、removeEventListener
1
2
3btn.addEventListener("click", function(){
alert(this.id);
}, false);true代表在捕获时调用,false代表在冒泡时调用,这样可以添加多个事件处理程序
- 一般都是将事件处理程序添加到冒泡阶段,兼容性更好
- 事件委托(事件代理)
作用域链是在定义时还是执行时创建的?
- 执行环境中所有的变量和函数都保存在变量对象中,由解析器在后台使用
- 每个函数都有自己的执行环境
- 当代码在一个环境中执行时,会创建变量对象的一个作用域链,这说明函数定义时没有作用域链存在,只有调用时有
- 作用域链最前端是当前执行代码的变量对象,如果环境是函数,则变量对象是活动对象
- 作用:标识符解析
原生ajax post请求
- XMLHttpRequest对象
- open方法,接收三个参数:get或post、请求Url、是否异步发送
send方法
1
2
3
4
5
6
7xhr.open("get", "example.txt", false);
xhr.send(null);
if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){
alert(xhr.responseText);
} else {
alert("Request was unsuccessful: " + xhr.status);
}发送异步请求,需要检测XHR对象的readyState属性,这个属性一变化,就会触发readystatechange事件
1
2
3
4
5
6
7
8
9
10
11
12var xhr = createXHR();
xhr.onreadystatechange = function(){
if (xhr.readyState == 4){ // 4代表已经接收到全部响应数据
if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){
alert(xhr.responseText);
} else {
alert("Request was unsuccessful: " + xhr.status);
}
}
};
xhr.open("get", "example.txt", true);
xhr.send(null);
异步script加载方式
- 脚本加载会导致DOM构建停止,出现白屏,所以一般都是把脚本放在body标签底部位置进行加载
除了底部加载脚本这个方法,还有其他方法解决阻塞问题?
- defer属性
- 渲染文档的时候,异步下载资源,但不会立即执行,会等到所有元素解析完再执行
- 兼容性问题,只被Internet Explorer 4+和Firefox 3.5+支持,不是理想方案
- async属性
- 在渲染文档是异步下载资源
- defer和async的区别
- defer按顺序执行,async乱序
- defer下载完后不会立即执行;而async下载完后会立即执行,因此执行过程中也会阻塞元素渲染
动态脚本加载,是非阻塞Javascript下载中最常用的模式,因为它可以跨浏览器,而且简单易用
1
2
3
4var script = document.createElement ("script");
script.type = "text/javascript";
script.src = "file1.js";
document.body.appendChild(script);用XHR对象下载代码,并注入到页面
- defer属性
基本类型值 引用类型值
- undefined null boolean string number object symbol这七种数据类型
- 基本数据类型是按值访问的,存放在栈内存中
- 引用类型值是按引用访问的,存放在堆内存中
- typeof能够返回 undefined null boolean string number object function
- 如何检测一个数组是数组?
- instanceof
- 原型链方式 数组.proto.constructor===Array
- Object.prototype.toString.call(数组)
- Array.isArray()
内存泄漏
- 如果闭包的作用域链中保存着一个HTML 元素,那么就意味着该元素将无法被销毁
- 需要解除对DOM对象的引用
xss跨站脚本
- 反射型(非持久型)
- 对于 xss 反射型攻击,主要是诱使用户点击恶意的链接或者访问存在漏洞的内容,可以有如下方式:
- 攻击者可以将恶意链接直接发送给受信任用户,发送的方式有很多种,比如 email, 网站的私信、评论等
- 攻击者可以购买存在漏洞网站的广告,将恶意链接插入在广告的链接中
- 对于 xss 反射型攻击,主要是诱使用户点击恶意的链接或者访问存在漏洞的内容,可以有如下方式:
- 存储型(持久型)——>>>输入检查
- 将一段恶意代码写在评论中,等待其他用户浏览评论时,就自动执行了js代码(获取cookie,并传输给攻击者的服务器);
- 基于DOM ——>>>输出检查
- 通过恶意脚本修改DOM结构
- 如何防范?
- HttpOnly 防止劫取 Cookie
- 输入检查,对用户输入进行检查、过滤和转义
- 输出检查,在变量输出到html页面时,将其进行编码或转义
- 反射型(非持久型)
csrf跨站请求伪造
- 劫持受信任用户向服务器发送非预期请求
- 攻击者借助受害者的cookie骗取服务器的信任
- 涉及到浏览器的cookie策略
- cookie有两种:会话期cookie和持久性cookie,后者可以指定过期时间
- 攻击者放了一个链接,这个链接指向一些删除操作,主要目的是改变服务器的数据
如何防范?
- 验证码
referer check
- 在http请求头中的referer字段,表示该请求的来源地址
对每一个删帖请求,验证其referer值,如果该值指向其他网站,那就有可能是跨站伪请求
1
2
3
4if (req.headers.referer !== '正确的站点地址') {
res.write('csrf 攻击');
return;
}检查referer,还能防止图片盗链
- 当referer为空时, 返回正确的图;当referer不为空, 且host命中我的目标网站时, 返回正确的图;当referer不为空, 但host未能命中我的目标网站时, 返回错误的图
- 添加token验证
- 基本思路是在请求中添加一些攻击者无法伪造的信息,这些信息也不能存储在cookie中。在请求中添加一个类似随机数的token,服务器建立拦截器来验证