Part
1
浏览器存储
浏览器存储数据有诸多益处,最主要的一点是能快速访问(网页)数据。
目前主流的浏览器端数据存储方法有:Cookies,Local Storage,Session Storage,IndexedDB(不常用)。
还有一些不推荐使用的技术如 FlashCookie,GoogleGear,UserData(IE),Web SQL(W3C 已废弃其标准的制定)。
除此之外,缓存也是浏览器的一种存储方式,其技术有:Application Cache(已废弃)、Service Workers (详情可见 PWA - 渐进式 WEB 应用)。
Cookie
由于 http 协议是无状态的,一旦客户端和服务器的数据交换完毕,就会断开连接,再次请求,会重新连接,这就说明服务器单从网络连接上是没有办法知道用户身份的。怎么办呢?那就给每次新的用户请求时,给它颁发一个身份证(独一无二)吧,下次访问,必须带上身份证,这样服务器就会知道是谁来访问了,针对不同用户,做出不同的响应。而 Cookie 的功能就是用于存储这些唯一标识,每次与服务器通信时,都会把这些数据给带上。
Cookie操作流程示意图
![]()
![]()
当我们首次访问某网站时,服务器会在报文头中使用 Set-Cookie 字段给我们分配一个或多个标识,浏览器会将其自动保存。
![]()
在之后浏览器对该服务器请求时,将会自动带上 Cookie 数据,跟随着请求头中传送到服务器。
1Cookie的属性
Cookie 由变量名和值组成,类似 Javascript 变量。其属性里既有标准的 Cookie 变量,也有用户自己创建的变量,属性中变量是用“变量=值”形式来保存。Cookie 就是一串字符串,格式就是键值对,分号隔开,三个属性可有可无。
NAME 为该 Cookie 名称
Expires:有效日期(默认关闭浏览器后失效, -1为马上删除)
Domain: 有效域名 (默认服务器的域名)
Path:有效路径(默认为 / )
2
cookie的增删改查
document.cookie方法
![]()
Cookie 技术比较古老,其以字符串的方式存储数据,用分号分隔一对键值。它也没有提供简便的 AP 让我们进行操作。增上改查都可以调用 document.cookie,该方法基本不会覆盖整个 cookie 而是覆盖对应的值:
增/改:
document.cookie= 'NAME=VALUE;Expires=DATE;
Path=PATH;Domain=DOMAIN_NAME;
删:
document.cookie= 'NAME=VALUE;Expires = -1'
查:
document.cookie
一般我们都会将增删改查方法封装起来,方便调用。另外,Cookie 采用同源政策,每个域名可存储 4KB 数据(因浏览器不同而变化,部分浏览器还限制了 Cookie 的个数)。
在过去的开发中,我们经常把很多非服务器必要的数据存放在 Cookie,导致每次请求都带上这些数据,浪费流量,很不符合现代的开发思想。
Web Storage
Web Storage 是 HTML5 中提出的标准,主要目的是克服 Cookie 的一些限制,当数据需要被严格控制在客户端上时,无需持续的将数据发回服务器。
WebStorage 提供两种类型的 API:localStorage 和 sessionStorage,两者的区别看名字就有大概了解, localStorage 在本地永久性存储数据,除非显式将其删除或清空,sessionStorage 存储的数据只在会话期间有效,关闭浏览器则自动删除。两个对象都有共同的 API。
![]()
Api:
保存数据:localStorage.setItem(key,value)
读取数据:localStorage.getItem(key)
删除单个数据:localStorage.removeItem(key)
删除所有数据:localStorage.clear()
得到某个索引的 key:localStorage.key(index)
Storage 也是采取同源政策,若需要跨域获取,可以使用 postMessage 接口。
Local Storage 与 Session Storage 两者的区别:
两者完全相同,唯独不同在于,Session Storage仅在同一个窗口生效,当关闭窗口便会清空,而 Local storage,除非手动清空,不然就永久存在。
IndexedDB
IndexedDB 是一个为了能够在客户端存储可观数量的结构化数据,并且在这些数据上使用索引进行高性能检索的 API。
IndexedDB 分别为同步和异步访问提供了单独的 API ,异步 API 方法调用完后会立即返回,同步 API 还没有在任何浏览器中得以实现。它原本是要和 WebWorkers 一起使用的。
因使用场景较少,目前前端开发比较少会用到,就不详细说了。
IndexedDB 的异步 api
![]()
![]()
目前前端开发者主要用到的浏览器存储方式是 Local Storage、Session Storage,而 Cookie 除了给服务器认证用户标识外,多用于互联网的精准广告定向技术中。
虽然本地存储技术有着极大的便捷性,但它们也存在风险,例如 XSS、CSRF 攻击,当然我们也有一定的应对策略去应对。
Part
2
HTML5 拖放
拖拽:Drag
释放:Drop
因此两个都动作合起来就是一个拖放事件,拖放 API 是 HTML5 新标准中的新特性。
![]()
在拖放过程中,涉及两个对象
源对象,指的是我们鼠标点击的一个事物,这里可以是一张图片,一个 DIV ,一段文本等等。
目标对象,指的是我们拖动源对象后移动到一块区域,源对象可以进入这个区域,可以在这个区域上方悬停(未松手),可以释松手释放将源对象放置此处(已松手),也可以悬停后离开该区域。
![]()
在 HTML5 中,所有元素只要加上 draggable="true" 属性,即可被拖动。
拖动我!
注意:图片、链接、被选中的文字是默认可拖动的,不需要设置 draggable。
拖放事件是一个复杂的过程,要完成一个最简单的拖放事件,我们除了要将元素设置为可拖动外,还要目的地对象允许被释放。
拖拽 API 总共就是这七个函数,其触发顺序为:
dragstart -> drag(不断触发) -> dragenter -> dragover(不断触发) -> dragleave / drop -> dragend
dragover 事件的默认行为是拒绝接受任何被拖放的元素。因此,我们要阻止浏览器这种默认行为。
dragOver (ev) {
ev.preventDefault() // 阻止浏览器默认行为
}
这样,我们就能把源对象拖放到目标对象中,但是触发的事件需要自己写在 drop 中,我们可以通过回调参数,获取到源对象和目标对象,进行数据处理。
拖放的 API
dataTransfer 对象
每个拖放事件都会回调一个 DragEvent 对象的参数,它派生于 MouseEvent,具有 Event 对象的所有功能,并增加了 dataTransfer,它是用于记录和设置拖放事件的对象。
![]()
通过 effectAllowed 和 dropEffect 共同设置拖放时指针的图标
dragStart (ev) {
// 指定拖动时被允许的效果,可设置
//move,copy,link,copyLink,copyMove,linkMove,all,none ev.dataTransfer.effectAllowed = 'all'
}
dragOver (ev, effectIndex) {
ev.preventDefault() // 阻止浏览器默认行为
ev.dataTransfer.dropEffect = 'move' // 改变指针图标, 可设置move,copy,link
}
使用 setDragImage 方法设置拖拽时的背景图片,接收三个参数(图片路径,相对x位移,相对y位移)
dragStart (ev) {
// 设置拖拽时背景图片
const img = new Image()
img.src = '/static/img/bgy.png'
ev.dataTransfer.setDragImage(img, 120, 10)
}
我们从外部把文件(这里以图片为例)拖动到浏览器中,可以从 dataTransfer.files 中获取到,并进行 dom 操作添加到页面指定位置中。
drop (ev) {
ev.preventDefault() // 浏览器默认打开拖进来的图片
let files = ev.dataTransfer.files
Array.from(files).forEach((file) => {
const fr = new FileReader()
file && fr.readAsDataURL(file)
fr.onload = function () {
if (fr.result.includes('data:image'))
{
const img = new Image()
img.src = fr.result
img.style.width = '20px'
document.querySelector('.blue').appendChild(img)
}
}
})
}
另外,其实 dataTransfer 对象中还有 setData,getData 方法,用于存放数据,但是其实这里有点小坑,个人建议用外部变量去存储更为便捷。
百果科技研发团队
致力于提供更好的技术
长按识别二维码
关注我们
|
|