zoukankan      html  css  js  c++  java
  • IndexedDB 是一个运行在浏览器上的非关系型数据库。

    一文梳理Web存储,从cookie,WebStorage到IndexedDB

     

    前言

    HTTP是无状态的协议,网络早期最大的问题之一是如何管理状态。服务器无法知道两个请求是否来自同一个浏览器。cookie应运而生,开始出现在各大网站,然而随着前端应用复杂度的提高,Cookie 也渐渐演化为了一个“存储多面手”,承载了 自身仅有的4KB 内存所不能承受的压力。在这样的背景下,web Storage应运而生,专门用于浏览器存储。但web Storage也仅仅是cookie的扩展,只能用于存储少量的简单数据,当遇到大规模的、结构复杂的数据时,Web Storage 也爱莫能助。这时候,就不得不其强大的IndexedDB了,一个运行在浏览器上的非关系型数据库。本文从cookie讲起,Web Storage过渡,IndexedDB结尾,梳理一下web 存储的体系与知识,希望在帮助作者梳理知识体系的同时也能帮助到广大前端ers!

    由于http是无状态的协议,一旦客户端和服务器的数据交换完毕,就会断开连接,再次请求,会重新连接,服务器单从网络连接上无法知道用户身份。怎么办呢?那就给每次新的用户请求时,给它颁发一个身份证(独一无二)吧,下次访问,必须带上身份证,这样服务器就会知道是谁来访问了,针对不同用户,做出不同的响应,这就是Cookie的原理。

    Cookie 的本职工作并非本地存储,而是“维持状态”。它是浏览器存储在用户机器的一个小文本文件大小不能超过4k,并且一些浏览器甚至会限制cookie的数量。Cookie是纯文本,没有可执行代码。储存一些服务器需要的信息,每次请求站点,会发送相应的cookie,这些cookie可以用来辨别用户身份信息等作用。

    cookie的编码方式为encodeURI()。

    cookie类型

    cookie按照过期时间分为两类:会话cookie和持久cookie。

    会话cookie是一种临时cookie,对标session,当用户退出浏览器,会话cookie就会被删除。默认情况下,即不设置过期时间,设置的cookie为会话cookie。持久cookie则会储存在硬盘里,保留时间更长,不以浏览器的关闭为转移,通常是持久性的cookie会维护某一个用户周期性访问服务器的配置文件或者登录信息。

    cookie的属性

    domain(cookie的域)

    产生Cookie的服务器可以向set-Cookie响应首部添加一个domain属性来控制哪些站点可以看到那个cookie,例如下面:

    Set-Cookie:name="losstie";domain="m.baidu.com"
    

    如果用户访问m.baidu.com就会发送这个cookie,不是则不会。

    path(cookie的路径 )

    path 参数告诉浏览器 cookie 的路径。默认情况下,cookie 属于当前页面。

    secure

    设置了属性secure,cookie只有在https协议加密情况下才会发送给服务端。但是这并不是最安全的,由于其固有的不安全性,敏感信息也是不应该通过cookie传输的。

    HttpOnly

    禁止javascript操作cookie(为避免跨域脚本(xss)攻击,通过javascript的document.cookie无法访问带有HttpOnly标记的cookie。)

    SamSite

    Cookie 的SameSite属性用来限制第三方 Cookie,从而减少安全风险。它可以设置三个值:

    • Strict 完全禁止第三方 Cookie,跨站点时,任何情况下都不会发送 Cookie。换言之,只有当前网页的 URL 与请求目标一致,才会带上 Cookie。
    • Lax 规则稍稍放宽,大多数情况也是不发送第三方 Cookie,但是导航到目标网址的 Get 请求除外。导航到目标网址的 GET 请求,只包括三种情况:链接,预加载请求,GET 表单
    • None Chrome 计划将Lax变为默认设置。这时,网站可以选择显式关闭SameSite属性,将其设为None。不过,前提是必须同时设置Secure属性(Cookie 只能通过 HTTPS 协议发送),否则无效。

    cookie操作

    通过docuemnt.cookie可以设置和获取Cookie的值

    /* cookie */
    function set(key, value){
        document.cookie = key + "=" + value;
    }
    
    function get(key){
        var all = document.cookie;
        var s = all.indexOf(key)+key.toString().length+1;
        var e = all.indexOf(";",s);
        return all.substring(s,e);
    
    }
    
    function remove(key){
        var e = "expires=" + new Date(1970,1,1); // 标注过去的时间
        document.cookie = key + "=;" + e;
    }
    

    第三方cookie

    通常cookie的域和浏览器地址的域匹配,这被称为第一方cookie。第三方cookie就是cookie的域和地址栏中的域不匹配,这种cookie通常被用在第三方广告网站。用于跟踪用户的浏览记录,并且根据收集的用户的浏览习惯,给用户推送相关的广告。

    cookie的劣势

    • Cookie 不够大,体积不能超过4k,当 Cookie 超过 4KB 时,它将面临被裁切的命运。这样看来,Cookie 只能用来存取少量的信息。
    • 每次都会携带在http头中,过量的cookie会损耗性能。
    • cookie是紧跟域名的,同一个域名下的所有请求,都会携带 Cookie。
    • 不够安全,服务器没法分辨用户和攻击者,攻击者可以读取网络上的其他用户的信息,包含HTTP Cookie的全部内容,以便进行中间的攻击。使用跨站点脚本技术可以窃取cookie等。

    Web Storage

    Internet Explorer 8+, Firefox, Opera, Chrome, 和 Safari支持Web 存储。

    Web Storage 是 HTML5 专门为浏览器存储而提供的数据存储机制。它又分为 Local Storage 与 Session Storage。localStorage与sessionStorage保存的数据,以“键值对”的形式存在,并都是以文本格式保存。

    localStorage与sessionStorage的区别

    两者的区别在于生命周期作用域的不同。

    • 生命周期: Local Storage 是持久化的本地存储,存储在其中的数据永远不会过期,只能是手动删除。Session Storage 是临时性的本地存储,它是会话级别的存储,当会话结束(页面被关闭)时,存储内容也随之被释放。
    • 作用域:Local Storage、Session Storage 和 Cookie 都遵循同源策略。但 Session Storage 在遵循同源策略的前提下,还需要在同一窗口。只要它们不在同一个浏览器窗口中打开,那么它们的 Session Storage 内容便无法共享。

    方法

    不管是 localStorage,还是 sessionStorage,可使用的API都相同。以localStorage为例:

    • 保存数据:localStorage.setItem(key,value);
    • 读取数据:localStorage.getItem(key);
    • 删除单个数据:localStorage.removeItem(key);
    • 删除所有数据:localStorage.clear();
    • 得到某个索引的key:localStorage.key(index);
    module.exports = {
        set:set,
        get:get,
        remove:remove,
        removeAll:removeAll,
        each:each
    }
    
    
    function set(key ,val){
        localStorage.setItem(key, JSON.stringify(val));
    };
    
    function get(key){
        return JSON.parse(localStorage.getItem(key));
    };
    
    function remove(key){
        localStorage.removeItem(key);
    };
    
    
    function removeAll(){
        localStorage.clear();
    };
    
    
    function each(fn){
        pluck(localStorage, function(val, key){
            fn(val, key);
            return false;
        });
    }
    
    
    function pluck(obj, fn){
        if(isList(obj)) {
            for(var i = 0; i<obj.length;i++){
                if(fn(obj[i], i)) {
                    return obj[i];
                }
            }
        } else {
            for(var key in obj) {
                if(obj.hasOwnProperty(key)){
    
                    if(fn(obj[key], key)){
    
                        return obj[key];
                    }
                }
            }
        }
    }
    
    function isList(val) {
    	return (val != null && typeof val != 'function' && typeof val.length == 'number')
    }
    
    function isFunction(val) {
    	return val && Object.prototype.toString.call(val) === '[object Function]'
    }
    
    function isObject(val) {
    	return val && Object.prototype.toString.call(val) === '[object Object]'
    }
    
    

    Web Storage 特点

    • 存储容量大: Web Storage 根据浏览器的不同,存储容量可以达到 5-10M 之间。Chrome、FireFox、Edge 都是 5M(IE 忽略)。
    • 仅位于浏览器端,不与服务端发生通信。

    应用场景

    localStorage:

    • 缓存静态资源,比如图片内容丰富的电商网站会用它来存储 Base64 格式的图片字符串或者存储一些不经常更新的 CSS、JS 等静态资源。
    • 作为前端 DB 的存储介质

    sessionStorage:

    • 用来存储生命周期和它同步的会话级别的信息。比如存储用户输入的内容,当页面刷新的时候可以立刻显示出刷新前的内容

    IndexedDB

    IndexedDB 是一个运行在浏览器上的非关系型数据库。理论上来说,IndexedDB 是没有存储上限的(一般来说不会小于 250M)。它不仅可以存储字符串,还可以存储二进制数据。

    IndexedDB特点

    • 键值对储存,IndexedDB 内部采用对象仓库(object store)存放数据。
    • 异步,ndexedDB 操作时不会锁死浏览器,用户依然可以进行其他操作(与 LocalStorage 形成对比,后者的操作是同步的)。
    • 支持事务,只要有一步失败,整个事务就都取消,数据库回滚到事务发生之前的状态,不存在只改写一部分数据的情况。
    • 同源限制,每一个数据库对应创建它的域名。网页只能访问自身域名下的数据库,而不能访问跨域的数据库。
    • 存储空间大,一般来说不少于 250MB,甚至没有上限。
    • 支持二进制储存,仅可以储存字符串,还可以储存二进制数据(ArrayBuffer 对象和 Blob 对象)。

    常见操作

    IndexedDB大部分操作并不是常用的调用方法,返回结果的模式,而是请求——响应的模式。

    • 建立打开IndexedDB ----window.indexedDB.open("testDB")

    • 关闭IndexedDB----indexdb.close()

    • 删除IndexedDB----indexedDB.deleteDatabase(indexdb)

    应用场景

    在 IndexedDB 中,我们可以创建多个数据库,一个数据库中创建多张表,一张表中存储多条数据——这足以 hold 住复杂的结构性数据。

    • 不需要网络连接的离线纯应用,比如Todolist这类用来记录待办任务类型的应用。
    • 需要存储大量数据的应用,比如图书馆管理系统这类存储大量数据的应用;
    • 配合service work构建pwa应用,用于缓存网络请求。

    cookie/webStorage/IndexedDB区别

    小结

    浏览器存储、缓存技术的出现和发展,为前端应用带来了无限的转机,页面越发复杂,功能越发强大。可以说,现代前端应用,尤其是移动端应用,之所以可以发展到在体验上叫板 Native 的地步,web存储功不可没(还有缓存)。

    拓展学习

    浏览器数据库 IndexedDB 入门教程-阮一峰

    深入了解浏览器存储--从cookie到WebStorage、IndexedDB

    Cookie 的 SameSite 属性-阮一峰

    我遇过的最难的Cookie问题

    这一次带你彻底了解Cookie

  • 相关阅读:
    37. Sudoku Solver(js)
    36. Valid Sudoku(js)
    35. Search Insert Position(js)
    34. Find First and Last Position of Element in Sorted Array(js)
    33. Search in Rotated Sorted Array(js)
    32. Longest Valid Parentheses(js)
    函数的柯里化
    俞敏洪:我和马云就差了8个字
    vue路由传值params和query的区别
    简述vuex的数据传递流程
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/13371002.html
Copyright © 2011-2022 走看看