1.自我介绍:除了基本个人信息以外,面试官更想听的是你与众不同的地方和你的优势。 2.项目介绍 3.如何看待前端开发? 4.平时是如何学习前端开发的? 5.未来三到五年的规划是怎样的?
position 的值, relative 和 absolute 分别是相对于谁进行定位的? absolute :生成绝对定位的元素, 相对于最近一级的 定位不是 static 的父元素来进行定位。 fixed (老 IE 不支持)生成绝对定位的元素,通常相对于浏览器窗口或 frame 进行定位。 relative 生成相对定位的元素,相对于其在普通流中的位置进行定位。 static 默认值。没有定位,元素出现在正常的流中 sticky 生成粘性定位的元素,容器的位置根据正常文档流计算得出
如何解决跨域问题
JSONP: 原理是:动态插入 script 标签,通过 script 标签引入一个 js 文件,这个 js 文件载入成功后会执行我们在 url 参数中指定的函数,并且会把我们需要的 json 数据作为参数传入。由于同源策略的限制,XmlHttpRequest 只允许请求当前源(域名、协议、端口)的资源,为了实现跨域请求,可以通过 script 标签实现跨域请求,然后在服务端输出 JSON 数据并执行回调函数,从而解决了跨域的数据请求。优点是兼容性好,简单易用,支持浏览器与服务器双向通信。缺点是只支持 GET 请求。 JSONP:json+padding(内填充),顾名思义,就是把 JSON 填充到一个盒子里
function createJs(sUrl) {
var script = document.createElement('script')
script.type = 'text/javascript'
script.src = sUrl
document.getElementsByTagName('head')[0].appendChild(script)
}
createJs('jsonp.js')
box({
name: 'test'
})
function box(json) {
alert(json.name)
}CORS: 服务器端对于 CORS 的支持,主要就是通过设置 Access-Control-Allow-Origin 来进行的。如果浏览器检测到相应的设置,就可以允许 Ajax 进行跨域的访问。 通过修改 document.domain 来跨子域 将子域和主域的 document.domain 设为同一个主域.前提条件:这两个域名必须属于同一个基础域名!而且所用的协议,端口都要一致,否则无法利用 document.domain 进行跨域主域相同的使用 document.domain。
使用 window.name 来进行跨域 window 对象有个 name 属性,该属性有个特征:即在一个窗口(window)的生命周期内,窗口载入的所有的页面都是共享一个 window.name 的,每个页面对 window.name 都有读写的权限,window.name 是持久存在一个窗口载入过的所有页面中的。使用 HTML5 中新引进的 window.postMessage 方法来跨域传送数据还有 flash、在服务器上设置代理页面等跨域方式。个人认为 window.name 的方法既不复杂,也能兼容到几乎所有浏览器,这真是极好的一种跨域方法。
XML 和 JSON 的区别?
(1) 数据体积方面。 JSON 相对于 XML 来讲,数据的体积小,传递的速度更快些。
(2) 数据交互方面。 JSON 与 JavaScript 的交互更加方便,更容易解析处理,更好的数据交互。
(3) 数据描述方面。 JSON 对数据的描述性比 XML 较差。
(4) 传输速度方面。 JSON 的速度要远远快于 XML。
谈谈你对 webpack 的看法
WebPack 是一个模块打包工具,你可以使用 WebPack 管理你的模块依赖,并编绎输出模块们所需的静态文件。它能够很好地管理、打包 Web 开发中所用到的 HTML、JavaScript、CSS 以及各种静态文件(图片、字体等),让开发过程更加高效。对于不同类型的资源,webpack 有对应的模块加载器。webpack 模块打包器会分析模块间的依赖关系,最后 生成了优化且合并后的静态资源。
webpack 的两大特色: 1.code splitting(可以自动完成) 2.loader 可以处理各种类型的静态文件,并且支持串联操作
webpack 是以 commonJS 的形式来书写脚本滴,但对 AMD/CMD 的支持也很全面,方便旧项目进行代码迁移。 webpack 具有 requireJs 和 browserify 的功能,但仍有很多自己的新特性:对 CommonJS 、 AMD 、ES6 的语法做了兼容对 js、css、图片等资源文件都支持打包串联式模块加载器以及插件机制,让其具有更好的灵活性和扩展性,例如提供对 CoffeeScript、ES6 的支持有独立的配置文件 webpack.config.js 可以将代码切割成不同的 chunk,实现按需加载,降低了初始化时间支持 SourceUrls 和 SourceMaps,易于调试具有强大的 Plugin 接口,大多是内部插件,使用起来比较灵活 webpack 使用异步 IO 并具有多级缓存。这使得 webpack 很快且在增量编译上更加快
说说 TCP 传输的三次握手四次挥手策略
三次握手 为了准确无误地把数据送达目标处,TCP 协议采用了三次握手策略。用 TCP 协议把数据包送出去后,TCP 不会对传送 后的情况置之不理,它一定会向对方确认是否成功送达。握手过程中使用了 TCP 的标志:SYN 和 ACK。
- 发送端首先发送一个带 SYN 标志的数据包给对方。
- 接收端收到后,回传一个带有 SYN/ACK 标志的数据包以示传达确认信息。
- 最后,发送端再回传一个带 ACK 标志的数据包,代表“握手”结束。 若在握手过程中某个阶段莫名中断,TCP 协议会再次以相同的顺序发送相同的数据包。
四次挥手
断开一个 TCP 连接则需要“四次挥手”:
- 第一次挥手:主动关闭方发送一个 FIN,用来关闭主动方到被动关闭方的数据传送,也就是主动关闭方告诉被动关闭方:我已经不 会再给你发数据了(当然,在 fin 包之前发送出去的数据,如果没有收到对应的 ack 确认报文,主动关闭方依然会重发这些数据),但是,此时主动关闭方还可 以接受数据。
- 第二次挥手:被动关闭方收到 FIN 包后,发送一个 ACK 给对方,确认序号为收到序号+1(与 SYN 相同,一个 FIN 占用一个序号)。
- 第三次挥手:被动关闭方发送一个 FIN,用来关闭被动关闭方到主动关闭方的数据传送,也就是告诉主动关闭方,我的数据也发送完了,不会再给你发数据了。
- 第四次挥手:主动关闭方收到 FIN 后,发送一个 ACK 给被动关闭方,确认序号为收到序号+1,至此,完成四次挥手。
TCP 和 UDP 的区别 TCP(Transmission Control Protocol,传输控制协议)是基于连接的协议,也就是说,在正式收发数据前,必须和对方建立可靠的连接。一个 TCP 连接必须要经过三次“对话”才能建立起来 UDP(User Data Protocol,用户数据报协议)是与 TCP 相对应的协议。它是面向非连接的协议,它不与对方建立连接,而是直接就把数据包发送过去! UDP 适用于一次只传送少量数据、对可靠性要求不高的应用环境。
说说你对作用域链的理解
作用域链的作用是保证执行环境里有权访问的变量和函数是有序的,作用域链的变量只能向上访问,变量访问到 window 对象即被终止,作用域链向下访问变量是不被允许的。
创建 ajax 过程
注:(后面相同内容附带代码) (1)创建 XMLHttpRequest 对象,也就是创建一个异步调用对象. (2)创建一个新的 HTTP 请求,并指定该 HTTP 请求的方法、URL 及验证信息. (3)设置响应 HTTP 请求状态变化的函数. (4)发送 HTTP 请求. (5)获取异步调用返回的数据. (6)使用 JavaScript 和 DOM 实现局部刷新.
渐进增强和优雅降级
渐进增强:针对低版本浏览器进行构建页面,保证最基本的功能,然后再针对高级浏览器进行效果、交互等改进和追加功能达到更好的用户体验。优雅降级:一开始就构建完整的功能,然后再针对低版本浏览器进行兼容。常见 web 安全及防护原理
sql 注入原理
就是通过把 SQL 命令插入到 Web 表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的 SQL 命令。总的来说有以下几点:
1.永远不要信任用户的输入,要对用户的输入进行校验,可以通过正则表达式,或限制长度,对单引号和双"-"进行转换等。 2.永远不要使用动态拼装 SQL,可以使用参数化的 SQL 或者直接使用存储过程进行数据查询存取。 3.永远不要使用管理员权限的数据库连接,为每个应用使用单独的权限有限的数据库连接。 4.不要把机密信息明文存放,请加密或者 hash 掉密码和敏感的信息。
XSS 跨站脚本攻击原理及防范
Xss(cross-site scripting)攻击指的是攻击者往 Web 页面里插入恶意 html 标签或者 javascript 代码。比如:攻击者在论坛中放一个看似安全的链接,骗取用户点击后,窃取 cookie 中的用户私密信息;或者攻击者在论坛中加一个恶意表单,当用户提交表单的时候,却把信息传送到攻击者的服务器中,而不是用户原本以为的信任站点。
XSS 防范方法 首先代码里对用户输入的地方和变量都需要仔细检查长度和对”<”,”>”,”;”,”’”等字符做过滤;其次任何内容写到页面之前都必须加以 encode,避免不小心把 html tag 弄出来。这一个层面做好,至少可以堵住超过一半的 XSS 攻击。其次,避免直接在 cookie 中泄露用户隐私,例如 email、密码等等。再次,通过使 cookie 和系统 ip 绑定来降低 cookie 泄露后的危险。这样攻击者得到的 cookie 没有实际价值,不可能拿来重放。如果网站不需要再浏览器端对 cookie 进行操作,可以在 Set-Cookie 末尾加上 HttpOnly 来防止 javascript 代码直接获取 cookie 。最后,尽量采用 POST 而非 GET 提交表单
XSS 与 CSRF(跨站请求伪造)有什么区别吗?
XSS 是获取信息,不需要提前知道其他用户页面的代码和数据包。CSRF 是代替用户完成指定的动作,需要知道其他用户页面的代码和数据包。要完成一次 CSRF 攻击,受害者必须依次完成两个步骤:登录受信任网站 A,并在本地生成 Cookie。在不登出 A 的情况下,访问危险网站 B。
CSRF 的防御 服务端的 CSRF 方式方法很多样,但总的思想都是一致的,就是在客户端页面增加伪随机数。通过验证码的方法 Web Worker 和 webSocket worker 主线程:
1.通过 worker = new Worker( url ) 加载一个 JS 文件来创建一个 worker,同时返回一个 worker 实例。 2.通过 worker.postMessage( data ) 方法来向 worker 发送数据。 3.绑定 worker.onmessage 方法来接收 worker 发送过来的数据。 4.可以使用 worker.terminate() 来终止一个 worker 的执行。
WebSocket 是 Web 应用程序的传输协议,它提供了双向的,按序到达的数据流。他是一个 Html5 协议,WebSocket 的连接是持久的,他通过在客户端和服务器之间保持双工连接,服务器的更新可以被及时推送给客户端,而不需要客户端以一定时间间隔去轮询。
HTTP 和 HTTPS
HTTP 协议通常承载于 TCP 协议之上,在 HTTP 和 TCP 之间添加一个安全协议层(SSL 或 TSL),这个时候,就成了我们常说的 HTTPS。默认 HTTP 的端口号为 80,HTTPS 的端口号为 443。
为什么 HTTPS 安全
因为网络请求需要中间有很多的服务器路由器的转发。中间的节点都可能篡改信息,而如果使用 HTTPS,密钥在你和终点站才有。https 之所以比 http 安全,是因为他利用 ssl/tsl 协议传输。它包含证书,卸载,流量转发,负载均衡,页面适配,浏览器适配,refer 传递等。保障了传输过程的安全性
对前端模块化的认识
AMD 是 RequireJS 在推广过程中对模块定义的规范化产出。 CMD 是 SeaJS 在推广过程中对模块定义的规范化产出。 AMD 是提前执行,CMD 是延迟执行。 AMD 推荐的风格通过返回一个对象做为模块对象,CommonJS 的风格通过对 module.exports 或 exports 的属性赋值来达到暴露模块对象的目的。
Javascript 垃圾回收方法
标记清除(mark and sweep) 这是 JavaScript 最常见的垃圾回收方式,当变量进入执行环境的时候,比如函数中声明一个变量,垃圾回收器将其标记为“进入环境”,当变量离开环境的时候(函数执行结束)将其标记为“离开环境”。垃圾回收器会在运行的时候给存储在内存中的所有变量加上标记,然后去掉环境中的变量以及被环境中变量所引用的变量(闭包),在这些完成之后仍存在标记的就是要删除的变量了
引用计数(reference counting) 在低版本 IE 中经常会出现内存泄露,很多时候就是因为其采用引用计数方式进行垃圾回收。引用计数的策略是跟踪记录每个值被使用的次数,当声明了一个变量并将一个引用类型赋值给该变量的时候这个值的引用次数就加 1,如果该变量的值变成了另外一个,则这个值得引用次数减 1,当这个值的引用次数变为 0 的时候,说明没有变量在使用,这个值没法被访问了,因此可以将其占用的空间回收,这样垃圾回收器会在运行的时候清理掉引用次数为 0 的值占用的空间。在 IE 中虽然 JavaScript 对象通过标记清除的方式进行垃圾回收,但 BOM 与 DOM 对象却是通过引用计数回收垃圾的,也就是说只要涉及 BOM 及 DOM 就会出现循环引用问题。
你觉得前端工程的价值体现在哪
- 为简化用户使用提供技术支持(交互部分)
- 为多个浏览器兼容性提供支持
- 为提高用户浏览速度(浏览器性能)提供支持
- 为跨平台或者其他基于 webkit 或其他渲染引擎的应用提供支持
- 为展示数据提供支持(数据接口)
谈谈性能优化问题
- 代码层面:避免使用 css 表达式,避免使用高级选择器,通配选择器。
- 缓存利用:缓存 Ajax,使用 CDN,使用外部 js 和 css 文件以便缓存,添加 Expires 头,服务端配置 Etag,减少 DNS
- 查找等请求数量:合并样式和脚本,使用 css 图片精灵,初始首屏之外的图片资源按需加载,静态资源延迟加载。
- 请求带宽:压缩文件,开启 GZIP,
代码层面的优化用 hash-table 来优化查找少用全局变量用 innerHTML 代替 DOM 操作,减少 DOM 操作次数,优化 javascript 性能用 setTimeout 来避免页面失去响应缓存 DOM 节点查找的结果避免使用 CSS Expression
避免全局查询避免使用 with(with 会创建自己的作用域,会增加作用域链长度)
多个变量声明合并避免图片和 iFrame 等的空 Src。空 Src 会重新加载当前页面,影响速度和效率尽量避免在 HTML 标签中写 Style 属性
尽量使用 css3 动画,开启硬件加速。适当使用 touch 事件代替 click 事件。避免使用 css3 渐变阴影效果。可以用 transform: translateZ(0)来开启硬件加速。不滥用 Float。Float 在渲染时计算量比较大,尽量减少使用不滥用 Web 字体。Web 字体需要下载,解析,重绘当前页面,尽量减少使用。合理使用 requestAnimationFrame 动画代替 setTimeout CSS 中的属性(CSS3 transitions、CSS3 3D transforms、Opacity、Canvas、WebGL、Video)会触发 GPU 渲染,请合理使用。过渡使用会引发手机过耗电增加 PC 端的在移动端同样适用
什么是 Etag?
当发送一个服务器请求时,浏览器首先会进行缓存过期判断。浏览器根据缓存过期时间判断缓存文件是否过期。情景一:若没有过期,则不向服务器发送请求,直接使用缓存中的结果,此时我们在浏览器控制台中可以看到 200 OK(from cache) ,此时的情况就是完全使用缓存,浏览器和服务器没有任何交互的。
情景二:若已过期,则向服务器发送请求,此时请求中会带上 ① 中设置的文件修改时间,和 Etag 然后,进行资源更新判断。服务器根据浏览器传过来的文件修改时间,判断自浏览器上一次请求之后,文件是不是没有被修改过;根据 Etag,判断文件内容自上一次请求之后,有没有发生变化。
情形一:若两种判断的结论都是文件没有被修改过,则服务器就不给浏览器发 index.html 的内容了,直接告诉它,文件没有被修改过,你用你那边的缓存吧—— 304 Not Modified,此时浏览器就会从本地缓存中获取 index.html 的内容。此时的情况叫协议缓存,浏览器和服务器之间有一次请求交互。
情形二:若修改时间和文件内容判断有任意一个没有通过,则服务器会受理此次请求,之后的操作同只有 get 请求会被缓存,post 请求不会 Expires 和 Cache-Control,Expires 要求客户端和服务端的时钟严格同步。 HTTP1.1 引入 Cache-Control 来克服 Expires 头的限制。如果 max-age 和 Expires 同时出现,则 max-age 有更高的优先级。
Cache-Control: no-cache, private, max-age=0
ETag: abcde
Expires: Thu, 15 Apr 2014 20:00:00 GMT
Pragma: private
Last-Modified: $now // RFC1123 format
Etag 应用
Etag 由服务器端生成,客户端通过 If-Match 或者说 If-None-Match 这个条件判断请求来验证资源是否修改。常见的是使用 If-None-Match。请求一个文件的流程可能如下:
====第一次请求=== 1.客户端发起 HTTP GET 请求一个文件; 2.服务器处理请求,返回文件内容和一堆 Header,当然包括 Etag(例如"2e681a-6-5d044840")(假设服务器支持 Etag 生成和已经开启了 Etag).状态码 200
====第二次请求=== 客户端发起 HTTP GET 请求一个文件,注意这个时候客户端同时发送一个 If-None-Match 头,这个头的内容就是第一次请求时服务器返回的 Etag:2e681a-6-5d0448402.服务器判断发送过来的 Etag 和计算出来的 Etag 匹配,因此 If-None-Match 为 False,不返回 200,返回 304,客户端继续使用本地缓存;流程很简单,问题是,如果服务器又设置了 Cache-Control:max-age 和 Expires 呢,怎么办,答案是同时使用,也就是说在完全匹配 If-Modified-Since 和 If-None-Match 即检查完修改时间和 Etag 之后,服务器才能返回 304.(不要陷入到底使用谁的问题怪圈)
为什么使用 Etag 请求头? Etag 主要为了解决 Last-Modified 无法解决的一些问题。
栈和队列的区别?
栈的插入和删除操作都是在一端进行的,而队列的操作却是在两端进行的。队列先进先出,栈先进后出。栈只允许在表尾一端进行插入和删除,而队列只允许在表尾一端进行插入,在表头一端进行删除栈区(stack)— 由编译器自动分配释放,存放函数的参数值,局部变量的值等。堆区(heap) — 一般由程序员分配释放,若程序员不释放,程序结束时可能由 OS 回收。堆(数据结构):堆可以被看成是一棵树,如:堆排序;栈(数据结构):一种先进后出的数据结构。
快速排序的思想并实现一个快排? “快速排序”的思想很简单,整个排序过程只需要三步:
- 在数据集之中,找一个基准点
- 建立两个数组,分别存储左边和右边的数组
- 利用递归进行下次比较
function quickSort(arr) {
//如果数组长度小于等于1无需判断直接返回即可
if (arr.length <= 1) {
return arr
}
let point = Math.floor(arr.length / 2) //取基准点
let pointNum = arr.splice(point, 1) //取基准点的值,splice(index,1)函数可以返回数组中被删除的那个数arr[index+1]
let left = [] //存放比基准点小的数组
let right = [] //存放比基准点大的数组
//遍历数组,进行判断分配
for (var i = 0; i < arr.length; i++) {
if (arr[i] < pointNum) {
left.push(arr[i]) //比基准点小的放在左边数组
} else {
right.push(arr[i]) //比基准点大的放在右边数组
}
}
//递归执行以上操作,对左右两个数组进行操作,直到数组长度为<=1;
return quickSort(left).concat(pointNum, quickSort(right))
}
console.log(quickSort([32, 45, 37, 16, 2, 87]))// 冒泡排序
function bubbleSort(arr) {
for (let i = 0; i < arr.length; i++) {
for (let j = i + 1; j < arr.length; j++) {
if (arr[i] > arr[j]) {
let temp = arr[i]
arr[i] = arr[j]
arr[j] = temp
}
}
}
return arr
}你觉得 jQuery 或 zepto 源码有哪些写的好的地方
(答案仅供参考) jQuery 源码封装在一个匿名函数的自执行环境中,有助于防止变量的全局污染,然后通过传入 window 对象参数,可以使 window 对象作为局部变量使用,好处是当 jquery 中访问 window 对象的时候,就不用将作用域链退回到顶层作用域了,从而可以更快的访问 window 对象。同样,传入 undefined 参数,可以缩短查找 undefined 时的作用域链。
;(function(window, undefined) {
// 用一个函数域包起来,就是所谓的沙箱
// 在这里var定义的变量属于函数作用域内的局部变量,避免了全局污染
// 把当前沙箱需要的外部变量通过函数参数引进来
// 只要保证参数对内提供的接口一致性,还可以随意替换传进来的参数个数
window.jQuery = window.$ = jQuery
})(window)jquery 将一些原型属性和方法封装在了 jquery.prototype 中,为了缩短名称,又赋值给了 jquery.fn,这是很形象的写法。有一些数组或对象的方法经常能使用到,jQuery 将其保存为局部变量以提高访问速度。 jquery 实现的链式调用可以节约代码,所返回的都是同一个对象,可以提高代码效率。
ES6 的了解
新增模板字符串(为 JavaScript 提供了简单的字符串插值功能)、箭头函数(操作符左边为输入的参数,而右边则是进行的操作以及返回的值 Inputs=>outputs。)、 for-of(用来遍历数据—例如数组中的值。)arguments 对象可被不定参数和默认参数完美代替。
ES6 将 promise 对象纳入规范,提供了原生的 Promise 对象增加了 let 和 const 命令,用来声明变量,增加了块级作用域。let 命令实际上就增加了块级作用域。 ES6 规定,var 命令和 function 命令声明的全局变量,属于全局对象的属性;let 命令、const 命令、class 命令声明的全局变量,不属于全局对象的属性。。。。。还有就是引入 module 模块的概念。
js 继承方式及其优缺点
原型链继承的缺点
一是字面量重写原型会中断关系,使用引用类型的原型,并且子类型还无法给超类型传递参数。借用构造函数(类式继承)借用构造函数虽然解决了刚才两种问题,但没有原型,则复用无从谈起。所以我们需要原型链 + 借用构造函数的模式,这种模式称为组合继承组合式继承。组合式继承是比较常用的一种继承方法,其背后的思路是 使用原型链实现对原型属性和方法的继承,而通过借用构造函数来实现对实例属性的继承。这样,既通过在原型上定义方法实现了函数复用,又保证每个实例都有它自己的属性。
关于 Http 2.0 你知道多少?
HTTP/2 引入了“服务端推(server push)”的概念,它允许服务端在客户端需要数据之前就主动地将数据发送到客户端缓存中,从而提高性能。 HTTP/2 提供更多的加密支持 HTTP/2 使用多路技术,允许多个消息在一个连接上同时交差。它增加了头压缩(header compression),因此即使非常小的请求,其请求和响应的 header 都只会占用很小比例的带宽。
defer 和 async
defer 并行加载 js 文件,会按照页面上 script 标签的顺序执行 async 并行加载 js 文件,下载完成立即执行,不会按照页面上 script 标签的顺序执行
谈谈浮动和清除浮动
浮动的框可以向左或向右移动,直到他的外边缘碰到包含框或另一个浮动框的边框为止。由于浮动框不在文档的普通流中,所以文档的普通流的块框表现得就像浮动框不存在一样。浮动的块框会漂浮在文档普通流的块框上。
说说你对闭包的理解
使用闭包主要是为了设计私有的方法和变量。闭包的优点是可以避免全局变量的污染,缺点是闭包会常驻内存,会增大内存使用量,使用不当很容易造成内存泄露。在 js 中,函数即闭包,只有函数才会产生作用域的概念
闭包有三个特性: 1.函数嵌套函数 2.函数内部可以引用外部的参数和变量 3.参数和变量不会被垃圾回收机制回收
请你谈谈 Cookie 的弊端
cookie 虽然在持久保存客户端数据提供了方便,分担了服务器存储的负担,但还是有很多局限性的。
第一:每个特定的域名下最多生成 20 个 cookie
- IE6 或更低版本最多 20 个 cookie
- IE7 和之后的版本最后可以有 50 个 cookie。
- Firefox 最多 50 个 cookie
- chrome 和 Safari 没有做硬性限制
IE 和 Opera 会清理近期最少使用的 cookie,Firefox 会随机清理 cookie。 cookie 的最大大约为 4096 字节,为了兼容性,一般不能超过 4095 字节。 IE 提供了一种存储可以持久化用户数据,叫做 userdata,从 IE5.0 就开始支持。每个数据最多 128K,每个域名下最多 1M。这个持久化数据放在缓存中,如果缓存没有清理,那么会一直存在。
优点:极高的扩展性和可用性
- 通过良好的编程,控制保存在 cookie 中的 session 对象的大小。
- 通过加密和安全传输技术(SSL),减少 cookie 被破解的可能性。
- 只在 cookie 中存放不敏感数据,即使被盗也不会有重大损失。
- 控制 cookie 的生命期,使之不会永远有效。偷盗者很可能拿到一个过期的 cookie。
缺点:
- Cookie 数量和长度的限制。每个 domain 最多只能有 20 条 cookie,每个 cookie 长度不能超过 4KB,否则会被截掉.
- 安全性问题。如果 cookie 被人拦截了,那人就可以取得所有的 session 信息。即使加密也与事无补,因为拦截者并不需要知道 cookie 的意义,他只要原样转发 cookie 就可以达到目的了。
- 有些状态不可能保存在客户端。例如,为了防止重复提交表单,我们需要在服务器端保存一个计数器。如果我们把这个计数器保存在客户端,那么它起不到任何作用。
浏览器本地存储
在较高版本的浏览器中,js 提供了 sessionStorage 和 localStorage。在 HTML5 中提供了 localStorage 来取代 globalStorage。 html5 中的 Web Storage 包括了两种存储方式:sessionStorage 和 localStorage。
sessionStorage 用于本地存储一个会话(session)中的数据,这些数据只有在同一个会话中的页面才能访问并且当会话结束后数据也随之销毁。因此 sessionStorage 不是一种持久化的本地存储,仅仅是会话级别的存储。而 localStorage 用于持久化的本地存储,除非主动删除数据,否则数据是永远不会过期的。
web storage 和 cookie 的区别
Web Storage 的概念和 cookie 相似,区别是它是为了更大容量存储设计的。Cookie 的大小是受限的,并且每次你请求一个新的页面的时候 Cookie 都会被发送过去,这样无形中浪费了带宽,另外 cookie 还需要指定作用域,不可以跨域调用。
除此之外,Web Storage 拥有 setItem,getItem,removeItem,clear 等方法,不像 cookie 需要前端开发者自己封装 setCookie,getCookie。但是 cookie 也是不可或缺的:cookie 的作用是与服务器进行交互,作为 HTTP 规范的一部分而存在 ,而 Web Storage 仅仅是为了在本地“存储”数据而生。
浏览器的支持除了 IE 7及以下不支持外,其他标准浏览器都完全支持(ie 及 FF 需在 web 服务器里运行),值得一提的是 IE 总是办好事,例如 IE7、IE6 中的 userData 其实就是 javascript 本地存储的解决方案。通过简单的代码封装可以统一到所有的浏览器都支持 web storage。
localStorage 和 sessionStorage 都具有相同的操作方法,例如 setItem、getItem 和 removeItem 等
cookie 和 session 的区别
- cookie 数据存放在客户的浏览器上,session 数据放在服务器上
- cookie 不是很安全,别人可以分析存放在本地的 COOKIE 并进行 COOKIE 欺骗考虑到安全应当使用 session
- session 会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能考虑到减轻服务器性能方面,应当使用 COOKIE
- 单个 cookie 保存的数据不能超过 4K,很多浏览器都限制一个站点最多保存 20 个 cookie
- 所以个人建议:将登陆信息等重要信息存放为 SESSION 其他信息如果需要保留,可以放在 COOKIE 中
