1. cookie的弊端:
cookie虽然在持久保存客户端数据提供了方便,分担了服务器存储的负担,但还是有很多局限性的。
第一:每个特定的域名下最多生成20个cookie
1.IE6或更低版本最多20个cookie
2.IE7和之后的版本最后可以有50个cookie。
3.Firefox最多50个cookie
4.chrome和Safari没有做硬性限制
IE和Opera 会清理近期最少使用的cookie,Firefox会随机清理cookie。
cookie的最大大约为4096字节,为了兼容性,一般不能超过4095字节。
IE 提供了一种存储可以持久化用户数据,叫做 userData,从IE5.0就开始支持。每个数据最多128K,每个域名下最多1M。这个持久化数据放在缓存中,如果缓存没有清理,那么会一直存在。
优点:极高的扩展性和可用性
1.通过良好的编程,控制保存在cookie中的session对象的大小。
2.通过加密和安全传输技术(SSL),减少cookie被破解的可能性。
3.只在cookie中存放不敏感数据,即使被盗也不会有重大损失。
4.控制cookie的生命期,使之不会永远有效。偷盗者很可能拿到一个过期的cookie。
缺点:
1.Cookie
数量和长度的限制。每个domain最多只能有20条cookie,每个cookie长度不能超过4KB,否则会被截掉。
2.安全性问题。如果cookie被人拦截了,那人就可以取得所有的session信息。即使加密也与事无补,因为拦截者并不需要知道cookie的意义,他只要原样转发cookie就可以达到目的了。
3.有些状态不可能保存在客户端。例如,为了防止重复提交表单,我们需要在服务器端保存一个计数器。如果我们把这个计数器保存在客户端,那么它起不到任何作用。
2. Cookie和Session区别
1、cookie 数据存放在客户的浏览器上,session 数据放在服务器上。
2、cookie 不是很安全,别人可以分析存放在本地的 cookie 并进行cookie欺骗 考虑到安全应当使用 session。
3、session 会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能 考虑到减轻服务器性能方面,应当使用 cookie。
4、单个 cookie 保存的数据不能超过 4K,很多浏览器都限制一个站点最多保存 20 个 cookie。
3.简单说一下浏览器本地存储是怎样的(storage)
html5中的Web Storage包括了两种存储方式:sessionStorage和localStorage。
1.Storage
1.1 Session Storage
- session临时回话,从页面打开到页面关闭的时间段 ,窗口的临时存储,页面关闭,本地存储消失
- 临时存储就是存储一下,其他页面并不会共享
1.2 Local Storage
- 域内安全、永久保存。即客户端或浏览器中来自同一域名的所有页面都可访问localStorage数据且数据除了删除否则永久保存,但客户端或浏览器之间的数据相互独立。
- 永久存储(可以手动删除数据)
- 多个页面可以共享
2.storage的特点
- 永久存储
- 存储量限制 ( 5M ) 客户端微型数据库
- 客户端完成,不会请求服务器处理
- SessionStorage数据是不共享、 LocalStorage共享
- 浏览器不统一,并且在IE8以下不兼容
- 储存的值限定是字符串类型,需要我们通过JSON 对象去转换
- 存储内容多的话会消化内容空间,会导致变卡
4.web storage和cookie的区别
(1) 存储空间不同
-
Web Storage能提供5MB的存储空间不同的浏览器提供的大小稍有不同
-
Cooki e仅4KB 存储空间 。
-
Web Storage 每个域(包括子域)有独立的存储空间,各个存储空间是完全独立的,因此不会造成数据混乱。
- 与服务器交互
-
Web Storage 中的数据则仅仅是存在本地,不会与服务器发生任何交互。
-
Cookie 的内容会随着请求一并发送的服务器(带宽浪费)。
- 接口
-
Web Storage 提供更多丰富易用的接口,拥有 setItem , getItem , removeItem , clear 等方法,操作数据更方便。
-
Cookie 需要前端开发者自己封装 setCookie , getCookie 。
- 跨域问题
- cookie不可以跨域调用
5.基础DOM操作?
-
创建新节点
createElement(); createTextNode(); //创建文本节点 doucument.createDocumetFragment() //创建文档碎片,只能在document下创建
2.添加,移除,替换,插入
appedChild(); removeChild(); replaceChild(); insertBefore();//在已有的子节点前插入一个新的子节点
3.获取元素
- document.getElementById() 通过id获取元素(IE7以下不区分大小写,会获取name属性)
- element.getElementsByTagName() 通过标签名获取元素
- element.getElementsByName() 注意,只用部分标签可用,通过name属性获取元素(表单,表单元素,img,iframe);
- element.getElementsByClassName() 通过class获取元素(ie8及以下ie版本中没有,可以多个class一起写)
- element.querySelector() 选到指定选择器下的第一个元素(ie7及以下没有)
- element.querySelectorAll() 选到指定选择器的所有元素(ie7及以下没有)
6.如何实现浏览器多个标签页面之间的通信?
调用 localstorge、cookies 等本地存储方式
7.线程与进程的区别?
- 一个程序至少有一个进程,一个进程至少有一个线程;
- 程序的运行会产生进程;
- 在程序运行时,进程拥有一块独立的内存空间,而多个线程之间共享内存,所以cpu切换一个线程花费要远远小于切换一个进程花费.
- 进程是操作系统资源分配和独立调度的基本单位,线程是程序执行的最小单位;
- 进程有着两个属性,但是本身需要加载很多的资源,很多进程之间互相切换,需要很大的消耗(时间和空间开销);
- 进程实现的操作系统的并发,多个程序之间的并发问题;线程实现的是进程内部的并发(河流和支流问题);
8.如何对网站的文件和资源进行优化?
- 减少http请求的次数,将css,js,图片的资源各自合并;
- 文件最小化/文件压缩
- 使用 CDN 托管
- 缓存的使用(多个域名来提供缓存)
- 避免在css中使用表达式
- 将css,js都放在外部文件中
- 避免重定向
- 将css放在页面的最上面
9.列举减少页面加载时间的方法?
- 优化图片
- 图像格式的选择(GIF:提供的颜色较少,可用在一些对颜色要求不高的地方)
- 优化CSS(压缩合并css,如 margin-top, margin-left…)
- 网址后加斜杠(如www.campr.com/目录,会判断这个目录是什么文件类型,或者是目录。)
- 标明高度和宽度(如果浏览器没有找到这两个参数,它需要一边下载图片一边计算大小,如果图片很多,浏览器需要不断地调整页面。这不但影响速度,也影响浏览体验。
当浏览器知道了高度和宽度参数后,即使图片暂时无法显示,页面上也会腾出图片的空位,然后继续加载后面的内容。从而加载时间快了,浏览体验也更好了)
- 减少http请求(合并文件,合并图片)
10.什么是 FOUC(无样式内容闪烁)?你如何来避免 FOUC?(不会)
11.null和undefined的区别?
- null是一个空对象(typeof检数据类型),undefined是一个全局变量的特殊属性;
- null转为数值为0.undefined转为数值是NAN;
- null是JavaScript的保留关键字,但是undefined不是;
- 当变量已经被定义但还未声明的时候他的值就位undefined;
- 如果一个变量后面会用来存储对象,那么最好初始化为null;
12. new操作符做了什么事情?
var Func = function() {}
var func = new Func();
new总共经过了四个阶段:
-
创建一个空对象
var obj = new Object();
-
设置原型链
obj.__proto__ = Func.protoType
-
让Func中的this指向obj,并执行Func函数体
var result =Func.call(obj);
-
判断Func的返回值类型,若为值类型 则返回obj,若为引用类型 则返回这个引用类型的对象
if (typeof(result) == "object"){ func=result; } else{ func=obj;; }
13.对JSON的了解?
JSON是一种特殊的字符串,这个字符串可以被任意的语言识别,并且可以转换为任意语言中的对象,JSON在开发中主要用来数据交互.
JSON和js对象的格式一样,只不过JSON字符串中的属性名必须加双引号
var json = '{"name":"why";"age""18}'
JSON分为json对象{}和json数组[]
var obj = '{"name":"wuwei","age":18}'
// 这叫`JSON`对象
var arr = '[1,2,3,"hello",true]';
// 这叫`JSON`数组
JSON中允许的值:
- 字符串
- 数组
- 布尔值
- null
- 对象(只能是普通对象,不能是函数)
- 数组
将JSON数据转化为字符串
JSON.parse(json)
将js对象转为JSON对象
JSON.stringfy(obj)
14.js延迟加载的方法?
defer和async,下面分别解释了他们的用法: defer:用于开启新的线程下载脚本文件,并使脚本在文档解析完成后执行。 async:HTML5新增属性,用于异步下载脚本文件,下载完毕立即解释执行代码。
正常的网页加载流程?
- 一边下载HTML网页,一边开始解析;
- 接续过程中碰到script标签
- 暂停解析,网页渲染的控制权转交给JavaScript 引擎
- 如果script标签引用了外部脚本,就下载该脚本,否则就直接执行;
- 执行完毕,控制权移交给渲染引擎,继续向下解析HTML网页
如果外部的加载时间很长(比如一直玩法完成加载),就会造成网页长时间失去响应,浏览器就会呈现假死状态,这被称为"阻塞效应".
为了避免这种情况的发生,比较好的做法就是将script标签放在页面的地步,而不是头部,这样做会有两个好处:
- 遇到脚本失去响应,网页的主体部分已经渲染完毕,用户至少可以看到页面,而不是一个空白的页面
- 在DOM 结构生成之前就调用DOM,JavaScript就会报错,如果脚本在网页尾部加载,就不会存在这个问题,这是的DOM结构已经生成了.
1.defer属性
<script src = "a.js" defer></script>
<script src = "a.js" defer></script>
defer的运行流程如下:
- 浏览器开始解析HTML网页;
- 向下解析过程,发现带有defer属性的script标签
- 浏览器继续向下解析HTML网页,同时并行下载script标签中的外部脚本
- 浏览器完成解析HTML网页,此时再执行下载的脚本
注:只有在DOM文档解析完毕之后,才会执行a.js和b.js
IE独有,可以让内部script标签里的代码异步.
2.async属性
<script src="a.js" async></script>
<script src="b.js" async></script>
acync的运行流程如下:
- 浏览器开始解析HTML网页
- 解析过程中碰到带有async属性的script标签
- 浏览器继续向下解析HTML网页,同时并行下载script标签中的外部脚本
- 脚本下载完成,浏览器暂停解析HTML网页,开始执行下载的外部脚本
- 脚本执行完毕,浏览器恢复解析HTML网页
注:在加载完js文件之后就会立即执行,只能加载外部的js文件,内嵌的js不能使用
总之,如果脚本之间没有依赖关系,就使用async属性,如果脚本之间有依赖关系,就使用defer属性。如果同时使用async和defer属性,后者不起作用,浏览器行为由async属性决定。
- 动态创建DOM的方式.创建script标签,插入在DOM中,在js文件加载完毕之后callBack 能够实现按需加载
15.如何解决跨域问题?
1.同源策略
同源策略(same origin policy)是一种约定,它是浏览器最核心也是最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响.
可以说web是构建在同源策略的基础之上的,浏览器只是针对同源策略的一种实现.
同源策略是由Netspace提出的一个著名的安全策略,现在所有支持JavaScript的浏览器都会使用这个策略,所谓同源是指:域名,协议,端口均相同
ajax是不能跨域的.
1.cors解决跨域
cors要在后台(服务器中设置响应头)
res.setHeader("Access-Control-Allow-Origin","*")
-
jsonp
JSON(JavaScript Object Notation)和JSONP(JSON with Padding )长得虽然差不多,但是两个是完全不相同的东西.JSON是一种数据交换的格式,而JSONP是一种被开发人员创造出来的一种非官方的跨域数据交换格式.
var btn = document.getElementById('btn'); var text = document.getElementById('text'); var box = document.getElementById('box') text.oninput = function () { var script = document.createElement('script'); script.src = 'https://www.baidu.com/sugrec?prod=pc&wd=' + this.value + '&cb=callback'; document.body.appendChild(script) } var ul = document.createElement('ul'); function callback(json) { var data = json.g || []; var len = data.length < 5 ? data.length : 5; ul.innerHTML = ''; data.forEach((item, i) => { if (i < 5) { console.log(item) ul.innerHTML += `<li> <a href='https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&rsv_idx=1&tn=baidu&wd=${item.q}&oq=wuwei&rsv_pq=e7dc2584000228ca&rsv_t=dda6iiIYXdFazi91l%2Fk3IyQMCXIamUeu2cfM8gS%2BOJOxEoTR6xA%2Bp3b%2FsO0&rqlang=cn&rsv_enter=0' target='_self'>${item.q}</a> </li>`; console.log(ul) } }) box.appendChild(ul) } btn.onclick = function () { location.href = 'https://www.baidu.com/s?ie=utf-8&f=8&rsv_bp=1&rsv_idx=1&tn=baidu&wd=' + text.value + '&oq=wuwei&rsv_pq=e7dc2584000228ca&rsv_t=dda6iiIYXdFazi91l%2Fk3IyQMCXIamUeu2cfM8gS%2BOJOxEoTR6xA%2Bp3b%2FsO0&rqlang=cn&rsv_enter=0' }
3.JQuery的jsonp
text.oninput = function () { $.ajax({ url: 'https://www.baidu.com/sugrec', data: { prod: "pc", wd: this.value, cb: "callback" }, dataType: 'jsonp', jsonpCallback: 'callback', success: function (data) { console.log(data) } }) }
16.document.write和innerHTML的区别?
- document.write()重绘的是整个页面的内容
<!doctype html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>无标题</title>
<script type="text/javascript" src="js.js"></script>
</head>
<body>
<p>原有内容</p>
<div id="testdiv">原有内容</div>
</body>
<script>
const id = document.querySelector('#testdiv');
console.log(id)
id.onclick = function() {
document.write("现有内容");
}
</script>
</html>
2.innerHTML重绘的是所属元素的内容
<!doctype html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>无标题</title>
<script type="text/javascript" src="js.js"></script>
</head>
<body>
<p>原有内容</p>
<div id="testdiv">原有内容</div>
<script>
const box = document.querySelector('#testdiv');
console.log(box)
box.onclick = function() {
box.innerHTML=`<h2>现有内容</h2>`
}
</script>
</body>
</html>
document.write是直接写入到页面的内容流,如果在写之前没有调用document.open, 浏览器会自动调用open。每次写完关闭之后重新调用该函数,会导致页面被重写。
innerHTML则是DOM页面元素的一个属性,代表该元素的html内容。你可以精确到某一个具体的元素来进行更改。如果想修改document的内容,则需要修改document.documentElement.innerElement。
innerHTML很多情况下都优于document.write,其原因在于其允许更精确的控制要刷新页面的那一个部分。
17.call(),apply()的作用?
call,apply,bind都是用来改变this指向的函数
call 与 apply 的不同点:
- 两者传入的列表形式不一样
- call可以传入多个参数;
- apply只能传入两个参数,所以其第二个参数往往是作为数组形式传入
多说无用,来看代码
var name="小可爱",
age=18
var obj={
name:'彭昱畅',
age:25,
abc:function() {
console.log(this.name+"的年龄是"+this.age)
}
}
var obj_a={
name:"高欢欢",
age:20
}
obj.abc() //此时this指向她挂载的对象obj
obj.abc.call() //此时,没有传入参数,this指向的是Windows
obj.abc.call(obj_a) //传入参数obj_a后,this指向的是obj_a
obj.abc.apply() //不传参数,this指向的是Window
obj.abc.apply(obj_a) //this指向obj_a
obj.abc.bind()()//不传参数,this指向的是Window
obj.abc.bind(obj_a)()//this指向obj_a
function baz(a,b) {
console.log(this,a,b)
}
baz.call(obj_a,2,3) //调用call()方法后this指向传入的第一个参数,后面的参数直接传入,第二个第三个之间用逗号分开
baz.apply(obj_a,[1,2]) //apply方法和call的作用完全一样,但除第一个参数外其余参数要以数组的形式传入
baz.bind(obj_a,1,2)() //返回的是一个函数,必须调用才能执行
baz.bind(obj_a,[1,2])()
从上面的结果来看:
call、 bind、 apply 这三个函数的第一个参数都是this的指向对象,第二个参数差别就来了:
call 的参数是直接放进去的,第二第三第n个参数全都用逗号分隔。
apply的所有参数都必须放在一个数组里面传进去。
bind除了返回函数以外,它的参数和call 一样。
18.那些操作会造成内存泄露?
内存泄露是指你用不到(访问不到)的变量,依然占居着内存空间,不能被再次利用起来。
垃圾回收器定期扫描对象,并计算引用了每个对象的其他对象的数量。如果一个对象的引用数量为 0(没有其他对象引用过该对象),或对该对象的惟一引用是循环的,那么该对象的内存即可回收。
产生内存泄露的操作?
- setTimeout 的第一个参数使用字符串而非函数的话,会引发内存泄漏。
- 控制台日志
- 循环(在两个对象彼此引用且彼此保留时,就会产生一个循环)