zoukankan      html  css  js  c++  java
  • HTML5 WebStorage

    WebStorage是HTML5中本地存储的解决方案之一,在HTML5的WebStorage概念引入之前除去IE User Data、Flash Cookie、Google Gears等看名字就不靠谱的解决方案,浏览器兼容的本地存储方案只有使用cookie。有同学可能会问,既然有了cookie本地存储,为什么还要引入WebStorage的概念?

    Cookie肿么了

    cookie的缺陷是非常明显的

    1. 数据大小:作为存储容器,cookie的大小限制在4KB左右这是非常坑爹的,尤其对于现在复杂的业务逻辑需求,4KB的容量除了存储一些配置字段还简单单值信息,对于绝大部分开发者来说真的不知指望什么了。

    2. 安全性问题:由于在HTTP请求中的cookie是明文传递的(HTTPS不是),带来的安全性问题还是很大的。

    3. 网络负担:我们知道cookie会被附加在每个HTTP请求中,在HttpRequest 和HttpResponse的header中都是要被传输的,所以无形中增加了一些不必要的流量损失。

    WebStorage

    WebStorage是HTML新增的本地存储解决方案之一,但并不是为了取代cookie而制定的标准,cookie作为HTTP协议的一部分用来处理客户端和服务器通信是不可或缺的,session正是依赖于实现的客户端状态保持。WebStorage的意图在于解决本来不应该cookie做,却不得不用cookie的本地存储。

    WebStorage提供两种类型的API:localStorage和sessionStorage,两者的区别看名字就有大概了解,localStorage在本地永久性存储数据,除非显式将其删除或清空,sessionStorage存储的数据只在会话期间有效,关闭浏览器则自动删除。两个对象都有共同的API

    复制代码
    interface Storage {
      readonly attribute unsigned long length;
      DOMString? key(unsigned long index);
      getter DOMString getItem(DOMString key);
      setter creator void setItem(DOMString key, DOMString value);
      deleter void removeItem(DOMString key);
      void clear();
    };
    复制代码
    • length:唯一的属性,只读,用来获取storage内的键值对数量。
    • key:根据index获取storage的键名
    • getItem:根据key获取storage内的对应value
    • setItem:为storage内添加键值对
    • removeItem:根据键名,删除键值对
    • clear:清空storage对象

    使用

    在实现了WebStorage的浏览器中,页面有两个全局的对象localStorage和sessionStorage

    image

    以localStorage为例,看一段简单的操作代码

    复制代码
    var ls=localStorage;
                console.log(ls.length);//0
                ls.setItem('name','Byron');
                ls.setItem('age','24');
                console.log(ls.length);//2
                
                //遍历localStorage
                for(var i=0;i<ls.length;i++){
                    /*
                        age : 24 
                        name : Byron 
                    */
                    var key=ls.key(i);
                    console.log(key+' : '+ls.getItem(key));
                }
                
                ls.removeItem('age');
                
                
                for(var i=0;i<ls.length;i++){
                    /*
                        name : Byron 
                    */
                    var key=ls.key(i);
                    console.log(key+' : '+ls.getItem(key));
                }
                ls.clear();//0
                console.log(ls.length);
    复制代码

    事件

    同时HTML5规定了一个storage事件,在WebStorage发生变化的时候触发,可以用此监视不同页面对storage的修改

    复制代码
    interface StorageEvent : Event {
      readonly attribute DOMString key;
      readonly attribute DOMString? oldValue;
      readonly attribute DOMString? newValue;
      readonly attribute DOMString url;
      readonly attribute Storage? storageArea;
    };
    复制代码
    • key:键值对的键
    • oldValue:修改之前的value
    • newValue:修改之后的value
    • url:触发改动的页面url
    • StorageArea:发生改变的Storage

    在index.php中定义

    <a href="test.php" target="_blank">Test</a>
    window.addEventListener('storage',function(e){
                    console.log(e.key+' is changed form '+e.oldValue+' to '+e.newValue+' by '+e.url );
                    console.log(e.storageArea ==localStorage);
                },false);
                
                localStorage.setItem('userName','Byron');

    test.php

    localStorage.setItem('userName','Casper');

    在index.php页面点击链接访问test.php时可以看到index.php的控制台输出log:

    userName is changed form Byron to Casper by http://localhost/test.php

    true

    为什么比cookie好

    1. 从容量上讲WebStorage一般浏览器提供5M的存储空间,用来存储视频、图片神马的不够,但对于绝大部分操作足矣

    2.安全性上WebStorage并不作为HTTP header发送的浏览器,所以相对安全

    3.从流量上讲,因为WebStorage不传送到服务器,所以不必要的流量可以节省,这样对于高频次访问或者针对手机移动设备的网页还是很不错的。

    这并不意味着WebStorage可以取代cookie,而是有了WebStorage后cookie能只做它应该做的事情了——作为客户端与服务器交互的通道,保持客户端状态。所以仅仅作为本地存储解决方案WebStorage是优于cookie的。

    注意点

    1.浏览器兼容性,这个几乎是所有HTML5新特性中最容易实施的了,因为IE8+的浏览器都支持,在IE7、IE6中可以使用IE User Data实现。

    2011052411384081

    2. 由于localStorage和sessionStorage都是对象,所以我饿每年也可以通过”.key”或”[key]”的方式获取、修改键值对,但不推荐这么做

    localStorage.userName='Frank';
    console.log(localStorage['userName']);

    3.虽然localStorage存储在本地,但不同的浏览器存储存储数据是独立的,所以在Chrome上存储的localStorage在FireFox上是获取不到的。

    4. localStorage和sessionStorage只能存储字符串类型,对于复杂的对象可以使用ECMAScript提供的JSON对象的stringify和parse来处理,低版本IE可以使用json2.js

    5.除了控制台,Chrome还为本地存储提供了非常直观的显示方式,调试的时候很方便

    image

        距离上一篇随笔过去已经太久,这一大段时间不停的做项目,多个项目中有各式各样的问题。休假归来,统一整理一下。

        今天总结的是项目中用到的一个东西,如何在系统中集成传真收发文,提供在线阅读、打印、旋转等功能。对于传真在线查看这个问题在网上还是有很多资料的,在此将拆分与查看、以及变态传真的旋转总结一下。

    1、传真管理

        这个部分很简单,写一个windows服务程序,定时监视传真机收文文件夹中的tif文件,发现一个就往数据库里面写一条记录。需要读取的时候再取出来用。

    2、传真的拆分

         对于传真的拆分需要用到image类,这个类平时用得较多的应该仅仅是绑定图片这样一个简单的操作,但是打开MSDN看看会吓一跳,还有这么多属性,这么多类,具体见http://msdn.microsoft.com/zh-cn/library/System.Drawing.Image_properties(v=vs.110).aspxhttp://msdn.microsoft.com/zh-cn/library/System.Drawing.Image_methods(v=vs.110).aspx。 对于这些类和方法很多不可知,但是在拆分tif文件的时候恰好需要用到。如下:

    拆分tif文件关键代码:

    1
    2
    3
    4
    5
    6
    7
    8
    //载入二进制流
    MemoryStream ms = new MemoryStream(imgbyte);
    System.Drawing.Image img = System.Drawing.Image.FromStream(ms);
    //获取 GUID 的数组,这些 GUID 表示此 Image 中帧的维数
    Guid guid = (Guid)img.FrameDimensionsList.GetValue(0);
    FrameDimension dimension = new FrameDimension(guid);
    //返回指定维度的帧数。
    int totalPage = img.GetFrameCount(dimension);

    如上所示,已经求到了tif图片的总帧数,也就是页数。那接下来就是一页一页的取出来另存为我们常用的jpg图片了,如下所示:

    复制代码
    //构建dt 循环拆分传真件
    DataTable dt = new DataTable();
    dt.Columns.Add("name");
    dt.Columns.Add("Url");
    for (int i = 0; i < totalPage; i++)
    {
        //选择由维度和索引指定的帧(页)。
        img.SelectActiveFrame(dimension, i);
        //开始将当前页另存到项目文件夹
    if (!System.IO.File.Exists(Server.MapPath("../Files/") + fax_name + (i + 1) + ".gif"))
    { img.Save(Server.MapPath("../Files/") + fax_name + (i + 1) + ".gif", System.Drawing.Imaging.ImageFormat.Gif);//分割图片进行存储 } dt.Rows.Add(new object[] { fax_name + (i + 1), "../Files/" + fax_name + (i + 1) + ".gif" });//往dt中添加数据 urlAll += "../Files/" + fax_name + (i + 1) + ".gif" + ","; }
    复制代码

    整个拆分过程就完毕了,目的是为了将多页tif拆分为多个连续的jgp文件,这样查看就很简单了。但是也有个问题,项目文件夹中的图片会越来越多,求高手解决此问题。

    还有一些附带等会儿要用到的代码:

    复制代码
    urlAll = urlAll.Substring(0, urlAll.Length - 1);
    string[] arrUrl = urlAll.Split(',');
    Count = arrUrl.Length;
    for (int i = 0; i <= arrUrl.Length - 1; i++)
    {
        urlFirst = arrUrl[0];
    }
    dt.AcceptChanges();
    
    //构建json对象
    StringBuilder data = new StringBuilder();
    for (int j = 0; j < dt.Rows.Count; j++)
    {
        data.Append("{id:'");
        data.Append((j + 1) + "',src:'");
        data.Append(dt.Rows[j]["Url"].ToString());
        data.Append("'},");
    }
    DataNew = data.ToString().Substring(0, data.ToString().Length - 1);
    复制代码

    这部分不需要多说,就是对字符串的一系列操作,并将第一个图片作为进入页面默认显示的页面。并将图片的id、url写到json对象中,在页面查看的时候需要这个对象。

    3、传真的查看

       页面准备,代码如下:

    复制代码
    <form id="Form1" method="post" runat="server">
        <div style="background-color: #c0c0c0;" align="center">
            <div style="margin-top: 10px;">
                <img src="<%=urlFirst %>" id="imageShow" style=" 600px; height: 800px;">
            </div>
        </div>
        <div style=" 100%; background-color: White;" align="center">
            <input type="button" class="left" id="RotateL" >&nbsp;
            <input type="button" class="last" onclick="prov()" />&nbsp;
            <label id="now">
            </label>
            /<label id="total"></label>&nbsp;
            <input type="button" class="next" onclick="next()" />
            <input type="button" class="right" id="RotateR">
        </div>
        </form>
    复制代码

    此处的urlFirst在上面那点里面已经阐述,默认第一页,这样的代码就可以显示我们拆分出来的图片了。

    接下来就是上一页、下一页了,代码如下:

    复制代码
    var list = [<%=DataNew %>];
        var this_id = "1";
        $(document).ready(function() {
            $("#now").html("1");
            $("#total").html(list.length);
        });
        //下一个图片
        function next() {
       
            var json = eval(list);
            for (var i = 0; i < json.length; i++) {
                if (parseInt(json[i].id) > parseInt(this_id)) {
                    document.getElementById("imageShow").src = json[i].src;
                    this_id = json[i].id;
                    $("#now").html(this_id);
                    return;
                }
            }
            alert("已经是最后一张了!");
        }
        //上一个图片
        function prov() {
            var json = eval(list);
            for (var i = json.length - 1; i >= 0; i--) {
                if (parseInt(json[i].id) < parseInt(this_id)) {
                    document.getElementById("imageShow").src = json[i].src;
                    this_id = json[i].id;
                    $("#now").html(this_id);
                    return;
                }
            }
            alert("已经是第一张了!");
        }    
    复制代码

    这些代码大家应该能看明白,实现上下翻页的功能。在线查看,上下翻页也就是这样,接下来应该进入如何旋转图片的问题了。

    4、图片旋转

         之所以会有这样的需求,还是因为在传真发送的过程中有很多小白会将纸张倒着放,斜着放,这种问题不可避免也颇为头痛。因此此功能人民群众需要他,所以我们这些人就要实现它。具体方法如下:

    1)、引入jQueryRotate.2.2.js文件,这个文件可以干这个事情,这个文件网上可以搜索到。

    2)、开始写翻转代码,如下:

    复制代码
    $("#RotateR").click(function(){
                    value += 90;
                    $("#imageShow").rotate({ animateTo: value });
                })
                
                $("#RotateL").click(function(){
                    value -= 90;
                    $("#imageShow").rotate({ animateTo: value });
                })
    复制代码

    这个翻转看着非常和谐,流畅。实乃写代码必备之良方。

    整个过程描述完毕,由于项目中关联性太多,不太好释放源码,关键部分已经一一注明,应该没有问题。

    预告下一篇,完美的报表如何导出到EXCEL、变态的官方公文如何在word中自动生成?

  • 相关阅读:
    linux的常用命令
    linux系统环境与文件权限
    MySQL常用数据类型
    【bzoj4641】基因改造 特殊匹配条件的KMP
    【bzoj4550】小奇的博弈 博弈论+dp
    【bzoj3991】[SDOI2015]寻宝游戏 树链的并+STL-set
    【bzoj1304】[CQOI2009]叶子的染色 树形dp
    【bzoj4715】囚人的旋律 dp
    【bzoj4008】[HNOI2015]亚瑟王 概率dp
    【bzoj4444】[Scoi2015]国旗计划 倍增
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3381583.html
Copyright © 2011-2022 走看看