HTML5本地存储

2023-11-18

1.背景

  • 在HTML4.01中,想要在浏览器中存储用户的数据时,我们一般只能用Cookie来实现,不过Cookie有很多限制
    • 大小限制:最大4KB
    • 数量限制:每个站点只允许存储20个Cookie,如果想要存储更多Cookie,则要把旧的Cookie删除掉
    • 性能浪费:每次HTTP请求都要携带Cookie,即使不会使用到Cookie
    • 是否支持跨域:需要遵守浏览器的“同源策略(域名、端口、协议一致)”,本身不支持跨域,如果要跨域,需要特殊处理
  • 因为Cookie的种种限制,HTML5为我们提供了3种全新的存储方法

2.localStorage(本地存储)

  • 用于永久存储客户端的少量数据
  • 所用到的方法(五种)

setItem(key,value)

保存数据

getItem(key)

获取数据

removeItem(key)

移出数据

clear()

移出全部数据

key(n)

获取第n个值,n为整数

  • 特点:(必须认真记忆)
    • 每个域名可以保存5MB数据
    • 关闭浏览器该存储方式存储的内容不会丢失
    • 该存储方式存储的数据是永久的,不会丢失,除非自行删除
    • 不同浏览器的localStorage数据是不可以共用的
    • 该存储方式的存储数据存储在本地电脑中,而不是存储在服务器中
    • localStorage和sessionStorage都是window对象下的子对象
    • 本身不支持跨域共享数据,如果要跨域,需要特殊处理
  • 用途:
    • 留言板
    • 存储些不用跟服务器交互的简单数据

3.sessionStorage(窗口存储)

  • 用于临时保存客户端的少量数据
  • 该存储方式所用的方法跟localStorage一模一样
  • 特点:
    • 该存储方式存储的内容在关闭窗口的时候就会被清除,不会永久存储
    • localStorage和sessionStorage都是window对象下的子对象
    • 通过跳转的页面可以共享sessionStorage值
  • 用途:
    • 存储

4.indexedDB(数据库)

  • 用于永久保存客户端的大量数据
  • 该数据库是HTML5新增的一种存储在客户端本地的NoSQL数据库,用于在本地存储大量数据
  • indexedDB是“对象型数据库”,而不是“关系型数据库”,它的功能相对于传统的数据库来说会简单很多
  • HTML5标准废除了 Web SQL Database
  • 使用:
    • 创建数据库(open方法来创建或打开数据库,包含两个事件)
      • 第一个参数为数据库名字,第二个参数为数据库版本号(版本号可以随意取)
      • onerror事件:请求失败时触发的事件
      • onsuccess事件:请求成功时触发的事件
      • 通过e.target.result可以获取到IDBDatabase对象(就是刚创建的数据库),增删改查都是基于这个对象来完成的
<script>
    let request = window.indexedDB.open('stu','1.1');  // 创建数据库
    request.onerror = function(){  // 创建失败事件 
      console.log('创建数据库失败')
    }

    request.onsuccess = function(e){ // 创建成功事件
      console.log('创建数据库成功')
      let db = e.target  // e.target 指向该请求(也就是指向创建的数据库)
      console.log(db.result); // 获取IDBDatabase对象,这个对象很重要,我们可以通过该对象可以获取数据库的各种信息如,数据库名、版本号等
    }
  </script>

TIP:

区别e.target和this

当一个元素里面包裹了子元素,那么点击子元素会触发“冒泡”,这个时候this指向绑定的父元素,而非子元素

而就算存在“冒泡”行为,但是e.target依旧指向点击的那个子元素

总结:用e.target会指向点击的那个元素,而this则不一定,可能会指向别的元素

如下图

    • 删除数据库(使用indexedDB对象的deleteDatabase()方法)
      • 有一个参数,该参数为想要删除的数据库的名字
      • 跟open方法一样,deleteDatabase方法会有两个事件(onerror、onsuccess事件)

5.操作“对象仓库”(表)

  • SQL中,有库就有表,但是indexedDB是没有表这个说法的,而是“对象仓库(Object Store)”来代替
  • 时刻记住:indexedDB中,“对象仓库”就是一张表
  • 创建一张“表”
    • 在indexedDB中,我们可以通过IDBDatabase对象的createObjectStore()方法来创建“对象仓库”(也就是“表”)
    • 一个事件(onupgradeneeded事件)
      • 请求对象request除了有onerror和onsuccess事件外,还有一个onupgradeneeded事件,它表示版本号更新时触发的事件。对于对象仓库的创建,我们一般都在这个事件里面完成
    • 在这个事件里面要做的事情
      • 获取IDBDatabase对象(通过e.target.result)
      • 利用db.objectStoreNames.contains("对象仓库名")来判断,新建的“对象仓库”是否已经存在
      • 如果存在,则报存在,如果不存在,利用db.createObjectStore("对象仓库名",{keyPath:"主键名"})创建“对象仓库”
      • 利用我们实现准备好的数据,进行数据存储
<script>
    let request = window.indexedDB.open('wtu','1.0');
    request.onerror = function(){
      console.log('创建数据库失败');
    }
    request.onsuccess = function(){
      console.log('创建数据库成功');
    }
    request.onupgradeneeded = function(e){   // request的第三个事件,用于创建一个“对象仓库”,也就是一张表
      let db = e.target.result  // 获取 IDBDatabase对象
      // 如果数据库中不包含该对象仓库,也就是没有这张表,则创建新的对象仓库,也就是新建一张表
      if(!db.objectStoreNames.contains('stu_01')){ // db.objectStoreNames.contains('对象仓库')  // contains检测对应字符串里面是否包含指定字符串或者字符
        // 创建表的格式:db.createObjectStore('对象仓库名',{keyPath:'主键名'})
        let store = db.createObjectStore('stu_o1',{keyPath:'id'})   // 注意:这个keyPath的p是大写
        for(let i = 0;i < store.length;i++){
          let addRequest = store.add(data[i]);
          // addRequest对象也有两个事件
          addRequest.onerror = function(){
            console.log('创建对象仓库失败');
          }
          addRequest.onsuccess = function(){
            console.log('创建对象仓库成功')
          }
        }
      }else{
        console.log('该对象仓库已经存在')
      }
    }
  </script>

6.对象仓库的“增删改查”

  • 当我们要使用对象仓库来进行增删查改的时候,我们都需要开始一个事务,事务就是“一组操作步骤”
  • 记住一点:凡是涉及对象仓库的增删查改,都是使用事务来处理的
  • 凡是对象仓库的增删改查都是在请求成功(request.onsuccess)里面进行操作
  • 增(add)
    • 增(add)与创建对象仓库很类似,但是很不一样
    • 增加数据使用的是transcation()方法,开启事务来执行,而创建新表使用的是createObjectStore()方法
 <script>
    let data = [
      {
        id:1004,
        name:'zs',
        sex:'男'
      },
      {
        id:1005,
        name:'ls',
        sex:'女'
      },
      {
        id:1006,
        name:'kangkang',
        sex:'男'
      }
    ]
    let request = window.indexedDB.open('stu','1.0');
    request.onerror = function(){
      console.log('创建数据库失败');
    }
    request.onsuccess = function(e){
      // 1.获取IDBDatabase对象,记住一切indexedDB都是基于这个对象,所以必须先获取
      let db = e.target.result
      // 2.开启事务(格式:db.transaction(['对象仓库名'],'事务模式'))  事务模式有两种:1.read 只读 2.readwrite 读写
      let transaction = db.transaction(['stu_o2'],'readwrite');
      // 3.连接到对象仓库
      let store = transaction.objectStore('stu_o2');
      // 4.添加新数据
      for(let i = 0;i < data.length;i++){
        let dataRequest = store.add(data[i])
        dataRequest.onerror = function(){
          console.log('添加失败')
        }
        dataRequest.onsuccess = function(){
          console.log('添加成功')
        }
      }
    }
  </script>
  • 删(delete)

let request = window.indexedDB.open('stu','1.0');
request.onerror = function(){
  console.log('创建数据库失败');
}
request.onsuccess = function(e){
  // 1.获取IDBDatabase对象,记住一切indexedDB都是基于这个对象,所以必须先获取
  let db = e.target.result
  // 2.开启事务(格式:db.transaction(['对象仓库名'],'事务模式'))  事务模式有两种:1.read 只读 2.readwrite 读写
  let transaction = db.transaction(['stu_o2'],'readwrite');
  // 3.连接到对象仓库
  let store = transaction.objectStore('stu_o2');
  let dataRequest = store.delete(1001)
  dataRequest.onerror = function(){
    console.log('删除数据失败');
  }
  dataRequest.onsuccess = function(){
    console.log('删除数据成功')
  }
}
  • 查(get)
let request = window.indexedDB.open('stu','1.0');
request.onerror = function(){
  console.log('创建数据库失败');
}
request.onsuccess = function(e){
  // 1.获取IDBDatabase对象,记住一切indexedDB都是基于这个对象,所以必须先获取
  let db = e.target.result
  // 2.开启事务(格式:db.transaction(['对象仓库名'],'事务模式'))  事务模式有两种:1.read 只读 2.readwrite 读写
  let transaction = db.transaction(['stu_o2'],'readwrite');
  // 3.连接到对象仓库
  let store = transaction.objectStore('stu_o2');
  let dataRequest = store.get(1002) 
  dataRequest.onerror = function(){
    console.log('查询数据失败');
  }
  dataRequest.onsuccess = function(){
    console.log(this.result)
  }
}
  • 改(put)
let request = window.indexedDB.open('stu','1.0');
request.onerror = function(){
  console.log('创建数据库失败');
}
request.onsuccess = function(e){
  // 获取IDBDatabase对象,记住一切indexedDB都是基于这个对象,所以必须先获取
  let db = e.target.result
  // 开启事务(格式:db.transaction(['对象仓库名'],'事务模式'))  事务模式有两种:1.read 只读 2.readwrite 读写
  let transaction = db.transaction(['stu_o2'],'readwrite');
  // 连接到对象仓库
  let store = transaction.objectStore('stu_o2');
  // 需要修改的数据
  let value = {
    id:1002,
    name:'hd',
    sex:'女'
  }
  let dataRequest = store.put(value)  // 将表中对应id的值修改成我们传过去的
  dataRequest.onerror = function(){
    console.log('修改数据失败');
  }
  dataRequest.onsuccess = function(){
    console.log("修改数据成功")
  }
}
  • 清空(clear)
let request = window.indexedDB.open('stu','1.0');
request.onerror = function(){
  console.log('创建数据库失败');
}
request.onsuccess = function(e){
  // 获取IDBDatabase对象,记住一切indexedDB都是基于这个对象,所以必须先获取
  let db = e.target.result
  // 开启事务(格式:db.transaction(['对象仓库名'],'事务模式'))  事务模式有两种:1.read 只读 2.readwrite 读写
  let transaction = db.transaction(['stu_o2'],'readwrite');
  // 连接到对象仓库
  let store = transaction.objectStore('stu_o2');
  let dataRequest = store.clear();
  dataRequest.onerror = function(){
    console.log('删除数据失败');
  }
  dataRequest.onsuccess = function(){
    console.log('删除数据成功')
  }
}

7.总结

  • localStorage、sessionStorage、Cookie的区别
  • localStorage、sessionStorage的操作方法是一模一样的

setItem(key,value)

保存数据

getItem(key)

获取数据

removeItem(key)

移出数据

clear()

移出全部数据

key(n)

获取第n个值,n为整数

  • localStorage、sessionStorage是window下的子对象,所以利用 window.localStorage或者localStorage就能获取到localStorage对象,之后就可以进行操作了(sessionStorage同理)
  • indexedDB数据库
    • 获取数据库
      • window.indexedDB
    • 创建数据库(获取库下的操作)
      • open()方法创建数据库或打开数据库
        • open方法有两个参数,第一个为创建的数据库名称,第二个是版本号(版本号随意写)
      • 对应的库一般取名为request,理解为请求,请求对象有三个事件
        • onerror事件:操作错误事件
        • onsuccess事件:操作成功事件
        • onupgradeneeded事件:表示request对象更新时触发的事件
    • 获取IDBDatabase对象(一般命名为db)
      • e.target.result
    • 删除数据库(获取库下的操作)
      • deleteDatabase(数据库名)
      • 对应有两个事件
        • onerror事件
        • onsuccess事件
    • 创建"仓库对象"(表)(表一般用store来命名变量)
      • 创建表一般需要在request第三个事件upgradeneeded下进行
      • 基于IDBDatabase对象的createObjectStore(“对象仓库名”,{keyPath:'主键名'})方法来创建表,若是没有主键名,那可以省略第二个参数的书写
      • 利用 IDBDatabase对象下的 objectStoreNames.contians("对象仓库名")来判断是否有这个表
    • 基于表下的四个方法:增删查改(在事件onsuccess下进行)
      • 而增删查改都需要用到事务来解决
      • 开启事务
        • 利用transaction()方法来开启事务(得到事务对象)
        • let transaction = db.transaction(["对象仓库名称"],"事务模式") // 事务模式有两种:1.readwrite 2. read
      • 连接对象仓库(将事务与表建立连接)
        • 利用事务对象的 objectStore()方法 来连接对象仓库
        • let store = transaction.objectStore("对象仓库名称")
      • 连接完成之后,可以对表进行增删查改等操作了
        • 增:add(提前准备好的数据)
        • 删:delete(“主键名”)
        • 查:get(“主键名”)
        • 改:put(提前准备好的数据)
        • 清空:clear()

         

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

HTML5本地存储 的相关文章

  • 开发日志:微信公众号网页开发的调试工具

    在这里记录一下开发时有用到的一些工具 VConcole调试工具 手机端的H5调试工具 http debugx5 qq com
  • 兼容ios不支持的日期格式

    前段时间开发了一个关于订单展示的页面 要求根据时间筛选出离当前时间最近的订单信息进行展示 因为服务器返回的时间格式都是 YYYY MM DD 也没想那么多 直接拿过来就用了 在安卓上排序都很正常 在测试的时候发现苹果手机展示的订单根本就没有
  • navigator.mediaDevices.getUserMedia()出现NotReadableError Could not start audio source错误的解决办法

    问题是 支持了navigator mediaDevices getUserMedia 的方法 但没有权限去调起麦克风导致的问题 解决方案 手动到手机 设置 隐私 授权录音或者麦克风对该app的使用权限
  • 【HTML】用户名、身份证号、邮箱、验证

    为了使页面不是那么突兀 特地导入了这俩个bootstrap框架相关的包
  • 【H5】 svg动画 旋转属性与虚线属性

    svg 动画 旋转 transform rotate angle x y 不要写在style里面 angle 旋转角度 x y旋转中心 绘制虚线 stroke dasharray a b a b c d 旋转属性 transform rot
  • 第八站:JavaScript的数据类型、运算符、流程控制语句

    第八站 JavaScript的数据类型 运算符 流程控制语句 欢迎来到第八站 JavaScript的数据类型 运算符 流程控制语句 在这一站 我们将深入探索JavaScript中的核心概念 为你揭示这个语言的奇妙之处 准备好继续冒险了吗 让
  • 动态一键换肤实现思路和demo

    前言 浏览器切换样式无非是通过css 总共有以下三种方法 内联style 注入style 注入link 那么我们想要实现一键换肤 那么我们为了剥离干净dom和css 我们只能选择style和link这两种方法 核心思路 在html的head
  • 前端学习——JavaScript原生实现购物车案例

    一 购物车案例 1 1 案例介绍 今天我们来写另外一个购物车案例 说实话对于我来说这个是花了将近三个小时的时间然后才做出来的 里面可能还存在一些我没有发现的问题 但是能完成基本的功能 对于一些基本的需求都是可以完成的 下面照旧是案例实现的g
  • ADS2020.2安装

    双击安装包中的 exe文件 开始安装 安装结束后 直接点击退出 然后将crack文件夹中的两个文件夹 分别复制到刚刚的安装路径下 分别替换12个和2个同名文件 注意 这两个文件夹的名字要和刚刚安装的文件夹的名字一致 就是将Crack文件夹中
  • html5自带属性验证表单必填

    html5自带属性验证表单必填 2014年02月25日 Html5 共 366字 字号 小 中 大 6条评论 阅读 6 515 次 为了防止恶意注册 通常会验证表单必填 实现方法以js为主 略微麻烦 今天才发现 html5如今已自带验证表单
  • 掘金个人主页头像旋转效果

    img src https sf1 ttcdn tos pstatp com img user avatar d1d3c1b115358ea70f51edcd697b58b2 300x300 image alt 钱端挖掘机师傅的个人资料头像
  • Web前端开发概述

    Web World Wide Web 全球广域网 是指一种基于互联网的信息系统 通过超文本链接将全球各地的文档 图像 视频等资源相互关联起来 并通过Web浏览器进行交互浏览和访问 Web的发展使得人们可以方便地获取和共享各种类型的信息 成为
  • JS有小数保留两位,整数不显示小数

    在很多时候要展示数据 会有各种小数处理 碰到页面的数据要根据不同的情况展示不同格式的数据 比如得到的数据是一个小数 现在要将小数保留两位 而整数则不显示小数点 显示整数格式 使用toFixed n 方法 toFixed 2 里面的2表示保留
  • HTML5游戏实战(2):90行代码实现捕鱼达人

    捕鱼达人是一款非常流行的游戏 几年里赚取了数以千万的收入 这里借用它来介绍一下用Gamebuilder CanTK开发游戏的方法 其实赚钱的游戏未必技术就很难 今天我们就仅用90来行代码来实现这个游戏 CanTK Canvas ToolKi
  • 58同城 -- 前端一面

    面我的是一个小哥哥 面试体验挺好的 大概进行了35分钟左右 自我介绍 面试内容 为什么向做前端 怎么学习的前端 本人非科班哈 然后问我项目 直接问项目 没问笔试令我有点意外 问我印象最深的项目 印象最深的功能 遇到的难点 前端存储的区别 C
  • 通过点击按钮在页面添加图片

    点击添加按钮 在盒子中加入图片 点击图片实现删除图片效果 代码如下
  • 移动端适配-01-百分比宽度

    1 图片可以在parent中使用 1 line heigh和text align使水平和竖直居中 2 在img标签中加vertical align middle 2 3 background size 1 两个参数 background s
  • webpack5 配置&使用 文档(大全)

    一 起步 1 基本安装 首先我们创建一个目录 初始化 npm 然后 在本地安装 webpack 接着安装 webpack cli 此工具用于在命令行中运行 webpack mkdir webpack demo cd webpack demo
  • localStorage和sessionStorage和Cookie的区别

    localStorage和sessionStorage和Cookie是前端开发中三种常见的临时存储客户端会话信息或者数据的方法 它们都存储在客户端中 区别 一 三者存储的有效时期不同 1 Cookie存储的有效时期可以设置 一般在浏览器关闭
  • 【HTML】HTML5的拖放你用了吗

    HTML HTML5的拖放你用了吗 引言 github HTML HTML5的拖放你用了吗 内容速递 看了本文您能了解到的知识 在 HTML5 中 拖放是标准的一部分 任何元素都能够拖放 拖放的操作 多用在拖拽排序列表 游戏拼图等 下文中出

随机推荐

  • Ue4蓝图访问外部接口

    首先我们搭建一个服务 node express 注意电脑必须安装node mkdir test server cd test server npm init npm install express body parser chalk pat
  • 数组复制的三种方法(超详细)

    数组复制的三种方法 Arrays类 copyOf 方法 copyOfRangs 方法 System类 arraycopy Arrays类 copyOf 方法 copyOf 方法适用于从下标0开始 复制指定长度的元素到目标数组 源码如下 pu
  • jQuery实现下拉菜单[代码+详细讲解+效果图]

    文章目录 前言 一 案例功能描述 二 html代码讲解 三 css代码讲解 四 jQuery实现功能及代码讲解 五 效果图 总结 前言 下拉菜单也是每个网页基本都会用到的案例 所以知识点还是要我们掌握的 这个案例比较简单 主要还是我们的jQ
  • 基于ftp协议的文件变化主动监听

    基于ftp协议的文件变化主动监听 前言 实现思路 代码实现思路 具体代码实现 依赖引入 FTPService接口 FTPServiceImpl类 FileChangeEvent接口 FileChangeData实体类 FileChangeT
  • linux 命令行与shell脚本编程大全

    linux 命令行与shell脚本编程大全 第一章 Linux LiveCD就是从cd读取的系统 由于没法将数据写入到cd 所以一旦重启 之前操作过后的一切数据都会丢失 第二章 第三章 1 man手册使用快捷键 使用空格键翻页 2 man
  • linux(centos) cpu核心数信息汇总

    总核数 物理CPU个数 X 每颗物理CPU的核数 总逻辑CPU数 物理CPU个数 X 每颗物理CPU的核数 X 超线程数 查看物理CPU个数 cat proc cpuinfo grep physical id sort uniq wc l
  • 【论文速递】ECCV2022 - ByteTrack:通过关联每个检测盒来进行多对象跟踪

    论文速递 ECCV2022 ByteTrack 通过关联每个检测盒来进行多对象跟踪 论文原文 ByteTrack Multi Object Tracking by Associating Every Detection Box 论文地址 h
  • macos安装zsh

    https www cnblogs com xuLessReigns p 11005435 html mac下安装autojump brew install autojump 1 安装zsh 执行 sh c curl fsSL https
  • 端口扫描工具-Nmap

    Nmap是一款功能强大 功能丰富的网络扫描工具 对于网络管理员和安全专业人员来说 是一个非常有用的工具 并且被广泛应用于安全审计 网络调查 漏洞搜寻等领域 能扫描主机的端口 查看端口是否开放 端口的服务是什么 端口扫描不但可以为黑客所利用
  • 深入理解mysqldump原理 --single-transaction --lock-all-tables --master-data

    在mysqldump过程中 之前其实一直不是很理解为什么加了 single transaction就能保证innodb的数据是完全一致的 而myisam引擎无法保证 必须加 lock all tables 前段时间抽空详细地查看了整个mys
  • 宝塔linux ssh没发启用,宝塔终端面板连接SSH服务失败解决方案

    最近更新了宝塔面板的版本后 通过宝塔SSH终端 1 0工具链接时出现了SSH服务失败的问题 尝试使用云平台的SSH和XSHELL之类的工具都可以正常链接 可以排除是SSH端口或是设置错误造成的故障 通过翻看宝塔官方论坛 找到了大炮运维V58
  • PageHelper分页插件出现的异常:check the your MySQL server version for the right syntax to use near ‘LIMIT 5‘

    1 使用PageHelper分页插件时 编写测试方法 运行并测试时出现如下异常 Cause com mysql jdbc exceptions jdbc4 MySQLSyntaxErrorException You have an erro
  • [ERROR NumCPU]: the number of available CPUs 1 is less than the required 2

    出现上述错误的原因 因为物理机或者虚拟机不满足Kubernetes的基础配置造成的 而Kubernetes对GPU要求至少是2核 2G内存 W0123 08 22 23 322562 12102 validation go 28 Canno
  • 做编程题没有思路怎么办

    来信 老师您好 我是一名计算机专业大二的学生 我现在在做一系列c语言竞赛一些容易的题目 可是我发现我碰到的问题会很没有思路 不知道方向 看见网上的很多同学都能够解决 而我却不能 我不知道自己差到哪了 我不知道怎么办才好 都有很多中学生的水平
  • macOS 12 Monterey:一次全新的跨设备协作体验

    macOS 12 Monterey是苹果公司的一次重大突破 它打破了设备间的壁垒 将不同设备无缝地连接在一起 极大地提升了用户的工作效率和娱乐体验 Monterey带来了通用控制 AirPlay 捷径等新功能 以及一些实用的新小功能 安装
  • 本地项目放到服务器启动不了,spring boot在本地能启动,放服务器上就不行,

    写完代码 放到服务器上去发现启动不了 服务器的tomcat没有问题 因为上面已经有两个项目在跑 报错内容 百度过了 百度上都说是server api的问题 但是我没有引入这个包 被逼无奈才来这里请教的 java util concurren
  • 25_pre_content 阶段 mirror 模块

    文章目录 precontent 阶段的 mirror 模块 示例配置 precontent 阶段的 mirror 模块 作用 实时拷贝流量 处理请求时 生成子请求访问其他服务 对子请求的返回值不做处理 ngx http mirror mod
  • 调用接口登录禅道_Java调用禅道api接口查询以及创建任务(傻瓜式复制粘贴--旗舰版禅道页面调用)

    背景 系统需要调用禅道的接口进行工单的创建 并对工单进行附件上传等信息的操作 禅道接口为http接口 每次请求都需要带上zentaosid进行请求 由于专业版禅道升级为旗舰版禅道版本变更 请求的URL有所变化 变化最大为常量类配置 如下 实
  • Set集合

    目录 一 Set集合的特点 二 Set集合取值 三 常用实现类HashSet和TreeSet 四 Comparable和Comparator的使用 4 1 Comparable 4 2 Comparator 五 LinkedHashSet
  • HTML5本地存储

    1 背景 在HTML4 01中 想要在浏览器中存储用户的数据时 我们一般只能用Cookie来实现 不过Cookie有很多限制 大小限制 最大4KB 数量限制 每个站点只允许存储20个Cookie 如果想要存储更多Cookie 则要把旧的Co