发表日期:2018-07 文章编辑:小灯 浏览次数:1309
在用户没有与因特网连接时,可以正常访问站点和应用,在用户与因特网连接时,更新用户机器上的缓存文件;
原理:
HTML5 的离线存储是基于一个新建的.appcache 文件的缓存机制(不是存储技术),通过这个文件上的解析清单离线存储资源,这些资源就会像cookie一样被存储了下来。之后当网络在处于离线状态下时,浏览器会通过被离线存储的数据进行页面展示;
如何使用:
1. 页面头部像下面一样加入一个 manifest 的属性;
2. 在 cache.manifest 文件的编写离线存储的资源;
CACHE MANIFEST#v0.11 CACHE: js/app.js css/style.css NETWORK: resource/logo.png FALLBACK: //offline.html
3. 在离线状态时,操作 window.applicationCache 进行需求实现
在线的情况下,浏览器发现 html 头部有 manifest 属性,它会请求 manifest文件,如果是第一次访问 app,那么浏览器就会根据 manifest 文件的内容下载相应的资源并且进行离线存储。如果已经访问过 app 并且资源已经离线存储了,那么浏览器就会使用离线的资源加载页面,然后浏览器会对比新的 manifest 文件与旧的 manifest 文件,如果文件没有发生改变,就不做任何操作,如果文件改变了,那么就会重新下载文件中的资源并进行离线存储;离线的情况下,浏览器就直接使用离线存储的资源;
调用 localstorge、cookies 等本地存储方式
方法一:使用localStorage
使用localStorage.setItem(key,value);添加内容
使用storage事件监听添加、修改、删除的动作
window.addEventListener("storage",function(event) { $("#name").val(event.key+”=”+event.newValue); });
方法二、使用cookie+setInterval
<input id="name"> <input type="button" id="btnOK" value="发送">
// 页面1 $(function(){ $("#btnOK").click(function(){ varname=$("#name").val(); document.cookie="name="+name; }); });
// 页面2 //获取Cookie的内容 function getKey(key) { return JSON.parse("{\"" + document.cookie.replace(/;\s+/gim, "\",\"").replace(/=/gim, "\":\"") + "\"}")[key]; } //每隔1秒获取Cookie的内容 setInterval(function() { console.log(getKey("name")); }, 1000);
1. Adobe Flash Socket 2. ActiveX HTMLFile (IE)3. 基于 multipart 编码发送 XHR4. 基于长轮询的 XHR
通过 visibilityState 的值检测页面当前是否可见,以及打开网页的时间等;在页面被切换到其他后台进程的时候,自动暂停音乐或视频的播放;
Page Visibility(页面可见性) API介绍、微拓展
防止恶意注册和暴力破解 所谓恶意注册和暴力破解都是用软件进行的。 人工注册再快,也需要一项一项输入资料,速度很慢,对服务器基本没有影响。如果没有验证码可以使用软件注册的话,可以同时运行成千上万个线程,一次能注册成千上万个用户,让服务器的数据库很快变得臃肿不堪,运行效率下降。 如果一个无聊的人或竞争对手对某网站怀有敌意,那么这种方法很容易就能让对方瘫痪。
1. map+area或者svg 2. border-radius 3. 纯js实现, 需要求一个点在不在圆上简单算法、获取鼠标坐标等等;
<div style="height:1px;overflow:hidden;background:black"></div>
hasOwnProperty不会去查找原型
声明方式 | 变量提升 | 作用域 | 初始值 | 重复定义 |
---|---|---|---|---|
const | 否 | 块级 | 需要 | 不允许 |
let | 否 | 块级 | 不需要 | 不允许 |
var | 是 | 函数级 | 不需要 | 允许 |
变量提升:const 和 let 必须先声明再使用,不支持变量提升
作用域:const,let 支持块级作用域,有效避免变量覆盖
块级作用域:在外层不能直接访问内层变量
const 定义常量,该常量不能赋值,但该常量的属性可以赋值
全局变量不再设置为顶层对象(window)的属性,有效避免全局变量污染
符合预期的 for 循环
初始值:const 声明的变量必须设置初始值,且不能重复赋值。
重复定义:const 和 let 不支持重复定义
// 判断null,typeof null的结果为object function isNull (obj) { if (!obj && typeof obj !== "undefined" && obj != 0) { return true } return false }console.log(isNull(null))
function isUndefind (obj) { return typeof obj === 'undefined' }console.log(isUndefind(undefined)) // true
// null == undefined function isNullOrUndef (obj) { return obj == undefined }console.log(isNullOrUndef(null)) // true console.log(isNullOrUndef(undefined)) // truefunction isUndefOrNull (obj) { return obj == null }console.log(isUndefOrNull(null)) // true console.log(isUndefOrNull(undefined)) // true
for (var i = 0; i < 5; i++) { setTimeout(function () { console.log(i) }, 1000) } // 5 // 5 // 5 // 5 // 5
以上代码输出和我们预期的不符,主要是因为var只有函数作用域和全局作用域,而for循环并不是一个函数体。最终循环结束时,i为5,而setTimeout并不会立即执行,而是会先进入setTimeout队列,等待执行,当执行队列时,获取到的i都为5
// 使用闭包修改 for(var i = 0; i < 5; i++) { (function (i) { setTimeout(function () { console.log(i) }, 1000) })(i) } // 0 // 1 // 2 // 3 // 4
// 用promise改写 for(var i = 0; i < 5; i++) { new Promise(function (resolve, reject) { resolve(i) }).then(function (i) { setTimeout(function () { console.log(i) }, 1000) }) } // 0 // 1 // 2 // 3 // 4
// 使用es6的let改写,因为let具有块级作用域 for(let i = 0; i < 5; i++) { setTimeout(function () { console.log(i) }, 1000) }
是的。
getElementById是dom节点的复制
querySelector是dom节点的引用
JavaScript中的每一个Function都有call和apply方法
共同点
三者都可以显示改变函数this指向
不同点
apply只接受两个参数,包括新的this指向对象和一个数组参数
call可以接受多个参数,包括新的this指向对象,以及多个调用参数
bind可以和call一样接受多个参数,但是因为bind是返回的仍然是一个函数,所以可以直接传参,也可以在后续调用的时候再进行传参
/*apply()方法*/ function.apply(thisObj[, argArray])/*call()方法*/ function.call(thisObj[, arg1[, arg2[, [,...argN]]]]);
apply妙用
// 让Math.max支持传入数组 var arr = [3, 11, 5]; var max = Math.max.apply(null, arr); console.log(max); // 11var arr1 = [1, 2, 3]; var arr2 = [4, 5, 6];// 合并两个数组,并返回新数组长度 var len = Array.prototype.push.apply(arr1, arr2); console.log(len); // 6
另外:bind是属于引用绑定,call和apply是属于直接绑定
当我们向两种地图对象分别发出“展示地 图”的消息时,会分别调用它们的 show 方法,就会产生各自不同的执行结果。对象的多态性提示我们,“做什么”和“怎么去做”是可以分开的,即使以后增加了其他地图,renderMap 函数不需要做任何改变,如下所示:
var googleMap = { show: function () { console.log('开始渲染谷歌地图'); } }; var bdMap = { show: function () { console.log('开始渲染百度地图'); } }; var renderMap = function( map ){ if ( map.show instanceof Function ){ map.show();} }; renderMap( googleMap ); // 输出:开始渲染谷歌地图renderMap( bdMap ); // 输出:开始渲染百度地图
另外:ES7提出了“函数绑定”(function bind)运算符,用来取代call、apply、bind调用,函数绑定运算符是并排的两个双冒号(::),双冒号左边是一个对象,右边是一个函数。该运算符会自动将左边的对象,作为上下文环境(即this对象),绑定到右边的函数上面。
首先要明确一点,原型链是指对象的原型链,所以原型链上的所有节点都是对象,不能是字符串、数字、布尔值等原始类型。
另外,规范要求原型链必须是有限长度的(从任一节点出发,经过有限步骤后必须到达一个终点。显然也不能有环。)
那么,应该用什么对象作为终点呢?很显然应该用一个特殊的对象。
好吧,Object.prototype
确实是个特殊对象,我们先假设用它做终点。那么考虑一下,当你取它的原型时应该怎么办?即
Object.prototype.__proto__;
应该返回什么?
取一个对象的属性时,可能发生三种情况:
如果属性存在,那么返回属性的值。
如果属性不存在,那么返回undefined。
不管属性存在还是不存在,有可能抛异常。
我们已经假设Object.prototype
是终点了,所以看起来不能是情况1。另外,抛出异常也不是好的设计,所以也不是情况3。那么情况2呢,它不存在原型属性,返回undefined怎么样?也不好,因为返回undefined一种解释是原型不存在,但是也相当于原型就是undefined。这样,在原型链上就会存在一个非对象的值。
所以,最佳选择就是null。一方面,你没法访问null的属性,所以起到了终止原型链的作用;另一方面,null在某种意义上也是一种对象,即空对象,因为null一开始就是为表示一个“空”的对象存在的。这样一来,就不会违反“原型链上只能有对象”的约定。
所以,“原型链的终点是null”虽然不是必须不可的,但是却是最合理的。
点击穿透现象有3种:
点击穿透问题:点击蒙层(mask)上的关闭按钮,蒙层消失后发现触发了按钮下面元素的click事件。蒙层的关闭按钮绑定的是touch事件,而按钮下面元素绑定的是click事件,touch事件触发之后,蒙层消失了,300ms后这个点的click事件fire,event的target自然就是按钮下面的元素,因为按钮跟蒙层一起消失了
跨页面点击穿透问题:如果按钮下面恰好是一个有href属性的a标签,那么页面就会发生跳转,因为 a标签跳转默认是click事件触发 ,所以原理和上面的完全相同
另一种跨页面点击穿透问题:这次没有mask了,直接点击页内按钮跳转至新页,然后发现新页面中对应位置元素的click事件被触发了,和蒙层的道理一样,js控制页面跳转的逻辑如果是绑定在touch事件上的,而且新页面中对应位置的元素绑定的是click事件,而且页面在300ms内完成了跳转,三个条件同时满足,就出现这种情况了
解决方案
只用touch事件
把所有click事件换成touch事件(touchstart, touchend, tap)
只用click
缺点是会带来300ms的延迟
tap后延迟300ms再隐藏mask
pointer-events
mask隐藏后,给按钮下面元素添加pointer-events:none;300ms后去掉样式,缺点是用户手速快的话会发现点击没有反应
fastclick库
XMLHttp upload API
从输入URL到页面渲染出来的过程
JSONP
使用script标签的src不受跨域限制的特点,允许用户传递一个callback参数给服务端,然后服务端返回数据时会将这个callback参数作为函数名来包裹住JSON数据,这样客户端就可以随意定制自己的函数来自动处理返回数据了。
优点:
它不像XHR对象实现ajax请求那样受到同源政策的限制,它的兼容性更好,XHR在进行ajax请求时,为了兼容IE,还需创建ActiveX对象。并且在请求完毕之后可以通过回调函数的方式将结果回传
缺点:
它只支持get请求而不支持post等其它类型的HTTP请求;它只支持跨域HTTP请求这种情况,不能解决不同域的两个页面之间如何进行JavaScript调用问题
CORS
CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)。它允许浏览器向跨源(协议 + 域名 + 端口)服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。
CORS允许在下列场景中使用跨域 HTTP 请求:
概述:
跨域资源共享标准新增了一组 HTTP 首部字段,允许服务器声明哪些源站有权限访问哪些资源。另外,规范要求,对那些可能对服务器数据产生副作用的 HTTP 请求方法(特别是 GET 以外的 HTTP 请求,或者搭配某些 MIME 类型的 POST 请求),浏览器必须首先使用 OPTIONS 方法发起一个预检请求(preflight request),从而获知服务端是否允许该跨域请求。服务器确认允许之后,才发起实际的 HTTP 请求。在预检请求的返回中,服务器端也可以通知客户端,是否需要携带身份凭证(包括 Cookies 和 HTTP 认证相关数据)。
简单请求:
某些请求不会触发 CORS 预检请求,我们称这样的请求为简单请求。满足下列条件,即为简单请求。
Fetch规范定义了对 CORS 安全的首部字段集合,不得人为设置该集合之外的其他首部字段。该集合为:
Content-Type 的值仅限于下列三者之一:
请求中的任意XMLHttpRequestUpload 对象均没有注册任何事件监听器;
XMLHttpRequestUpload 对象可以使用 XMLHttpRequest.upload 属性访问。
请求中没有使用 ReadableStream 对象。
注意: 这些跨域请求与浏览器发出的其他跨域请求并无二致。如果服务器未返回正确的响应首部,则请求方不会收到任何数据。因此,那些不允许跨域请求的网站无需为这一新的 HTTP 访问控制特性担心。
预检请求
与前述简单请求不同,“需预检的请求”要求必须首先使用 OPTIONS 方法发起一个预检请求到服务器,以获知服务器是否允许该实际请求。"预检请求“的使用,可以避免跨域请求对服务器的用户数据产生未预期的影响。
当请求满足下述任一条件时,即应首先发送预检请求:
附带身份凭证的请求
var invocation = new XMLHttpRequest(); var url = 'http://bar.other/resources/credentialed-content/';function callOtherDomain(){ if(invocation) { invocation.open('GET', url, true); invocation.withCredentials = true; invocation.onreadystatechange = handler; invocation.send();} }
第 7 行将 XMLHttpRequest 的 withCredentials 标志设置为 true,从而向服务器发送 Cookies。因为这是一个简单 GET 请求,所以浏览器不会对其发起“预检请求”。但是,如果服务器端的响应中未携带 Access-Control-Allow-Credentials: true ,浏览器将不会把响应内容返回给请求的发送者。
withCredentials附带身份凭证的请求与通配符
如果客户端请求设置withCredentials=true时,服务器端不能设置Access-Control-Allow-Origin 的值为“*”,否则请求将会失败,必须设置对应的域名。
HTTP请求首部字段
HTTP请求响应字段
HTTP访问控制(CORS)
Xss
Xss(跨站脚本攻击),全称Cross Site Scripting,恶意攻击者向web页面中植入恶意js代码,当用户浏览到该页时,植入的代码被执行,达到恶意攻击用户的目的。
Xss攻击的危害
盗取各类用户账号
窃取有商业价值的资料
非法转账操作
强制发送电子邮件
控制受害者机器向其它网站发起攻击
等等...
原因分析
原因:没有对客户端提交的数据进行校验分析,导致恶意代码被植入。
根本解决:不要相信任何客户端提交的任何数据!!!
Xss攻击的分类
前提是易受攻击的网站有一个HTML页面采用不安全的方式从document.location或document.URL或document.referrer获取数据(或者任何其他攻击者可以修改的对象),所以应该避免直接从document.location或document.URL或document.referrer获取数据。
Xss的漏洞修复
CSRF
CSRF(Cross-site request forgery跨站请求伪造)是一种依赖web浏览器的、被混淆过的代理人攻击。
CSRF漏洞修复
Xss和Csrf介绍
缺点
nodejs是单线程,这意味着Node只能利用一个处理器来工作。但多数服务器都有多个核。好在nodejs提供了cluster模块,可以把任务分配给子进程。每个子进程有些特殊能力,比如能与其他子进程共享socket连接。当用cluster时,主进程不会参与每个具体的事务中,主进程管理所有的子进程,但当子进程与I/O操作交互时,它们是直接进程操作的,不需要通过主进程。
var cluster = require('cluster'); var http = require('http'); var numCPUs = require('os').cpus().length;if (cluster.isMaster) { //创建工作进程 for (var i = 0; i < numCPUs; i++) { cluster.fork(); }cluster.on('death', function(worker) { console.log('worker' + worker.pid + 'died'); }); } else { //工作进程创建http服务 http.Server(function(req, res) { res.writeHead(200); res.end("Hello world\n"); }).listen(8000); }
cluster工作的原理是每一个Node进程要么是主进程,要么成为工作进程。当一个主进程调用cluster.fork()方法时,它会创建于主进程一模一样的子进程,除了两个让每个进程可以检查自己是父/子进程的属性以外。在主进程cluster.isMaster会返回true,而cluster.isWorker()会返回false,在工作进程中则相反。
除了共享socket外,还能利用cluster做更多事情,因为它是基于child_process模块的,这个模块会提供一系列属性,其中最有用一些可以检查子进程健康状态,在上面例子中,当子进程死亡时,主进程会用console.log()输出死亡进程,既然监测到了死亡进程,那么我们可以在这个子进程死亡时,再重新创建一个新的子进程。
cluster.on('death', function(worker) { console.log('worker' + worker.pid + 'died'); cluster.fork(); });
nodejs:使用多处理器
使用createReadStream读取信息,encoding:binary
通过HttpRequest的Range 请求http头文件中的断点信息,如果没有则为undefined,格式(range: bytes=232323-),并返回206编码(206一般为只要请求部分数据时的响应)
stub是用于模拟一个组件或模块的函数或程序。在测试用例中,简单的说,你可以用stub去模拟一个方法,从而避免调用真实的方法,使用stub你还可以返回虚构的结果。你可以配合断言使用stub。
举个例子,在一个读取文件的场景中,当你不想读取一个真正的文件时
var fs = require('fs'); var readFileStub = sinon.stub(fs, 'readFile', function(path, cb) { return cb(null, 'filecontent'); }); expect(readFileStub).to.be.called; readFileStub.restore();
在单元测试中:Stub是完全模拟一个外部依赖,而Mock常用来判断测试通过还是失败
CSS盒子模型:由四个属性组成的外边距(margin)、内边距(padding)、边界(border)、内容区(width和height);
二者都是用来隐藏元素的显示效果的,但区别是: * display: none不再占据页面空间 * visibility: hidden依然占据页面空间
优先级就近原则
同权重以最近者为准 载入样式以最后载入的样式为准;
同权重下:内联样式表(标签内部) > 嵌入样式表(当前文件) > 外部样式表(外部文件)
!import > id > class > tag
Import比内联样式优先级高
层叠重要度层次
带有important的用户样式
带有important的作者样式
作者样式
用户样式
浏览器/用户代理应用的样式
权重分为a b c d ,4个等级,每个等级以10为基数分别是
内联样式(或行内样式)a=1
b = ID选择器个数
c = 类、伪类和属性选择器的个数
d = 元素选择器和伪元素选择器的个数
-webkit-font-smoothing: antialiased;
日期:2019-09 浏览次数:6082
日期:2019-09 浏览次数:4089
日期:2019-09 浏览次数:4893
日期:2019-09 浏览次数:9895
日期:2019-09 浏览次数:10036
日期:2019-09 浏览次数:3880
日期:2019-09 浏览次数:3494
日期:2019-09 浏览次数:3253
日期:2019-09 浏览次数:2973
日期:2019-09 浏览次数:3405
日期:2019-09 浏览次数:6702
日期:2019-09 浏览次数:3105
日期:2019-09 浏览次数:3594
日期:2019-09 浏览次数:3231
日期:2019-09 浏览次数:3285
日期:2019-09 浏览次数:3541
日期:2019-09 浏览次数:5151
日期:2019-09 浏览次数:2842
日期:2019-09 浏览次数:3906
日期:2019-09 浏览次数:3338
日期:2019-09 浏览次数:3536
日期:2019-09 浏览次数:3558
日期:2019-09 浏览次数:3062
日期:2019-09 浏览次数:3854
日期:2019-09 浏览次数:4955
日期:2019-09 浏览次数:4788
日期:2019-09 浏览次数:3001
日期:2019-09 浏览次数:8344
日期:2019-09 浏览次数:4101
日期:2019-09 浏览次数:3338
Copyright ? 2013-2018 Tadeng NetWork Technology Co., LTD. All Rights Reserved.