云顶娱乐集团

当前位置:云顶娱乐集团 > 云顶娱乐集团 > 数码存储能力大概浏览,数据交互与当地存储

数码存储能力大概浏览,数据交互与当地存储

来源:http://www.clubskodakaroq.com 作者:云顶娱乐集团 时间:2019-10-07 06:55

2017前端质量优化清单

2017/04/10 · 基础手艺 · 性能

原版的书文出处: Xsu Edwan   

您从头使用渐进运行了么?是还是不是已经应用过React和Angular中tree-shakingcode-splitting五个工具?有未有用过Brotli、Zofli和HPACK那二种缩小技能,恐怕OCSP契约(在线证书情形左券)?知不知道道能源提示,客商端提醒和CSS containment一类的技能?领悟IPv6,HTTP/2和Service Worker那几个左券呢?

回首那多少个年,大家往往在成功了产品以往才会去考虑品质。平时把与性能相关的政工拖到项目标最后来做,所做的也不过是对服务器上的config文件进行部分微调、串联、优化以及一些特意小的调解。而近期,本领一度有了震天动地的转移。

贰个品类的质量是丰裕关键的,除了要在本事层面上注意,更要在类型的统一策动之初就起来思虑,这样才得以使质量的各类潜伏要求全面包车型大巴结合到项目中,随着项目协助举行带动。质量最佳具备可量化、可监测以及可转移的特征。网络特别复杂,对网络的监督也变得特别难,因为监测的历程会受到包涵设备、浏览器、合同、网络项目以及别的技艺(CDN,ISP,缓存,代理服务器,防火墙,负载均衡器和服务器对质量的熏陶都非常大)的极大影响。

下文是一份二〇一七年的前端品质优化清单,解说了作为前端开垦职员,为了保障上报速度以及浏览器包容性大家须求考虑的标题。

(你也能够下载checklist PDF或者check in Apple Pages。优化万岁!)

客商端(浏览器端)数据存款和储蓄能力概览

2017/03/09 · 基础手艺 · 2 评论 · 存储

原来的书文出处: dwqs   

在客商端(浏览器端)存款和储蓄数占领好些个益处,最首要的一点是能火速访谈(网页)数据。(未来)在顾客端有三种多少存款和储蓄方法,而近年来就唯有多样常用方法了(个中一种被废弃了):

  • Cookies
  • Local Storage
  • Session Storage
  • IndexedDB
  • WebSQL (被废弃)

前面二日品质与足够申报

2018/08/22 · 基本功手艺 · 性能

原来的作品出处: counterxing   

数量交互与本地存款和储蓄

2016/01/17 · HTML5, JavaScript · 1 评论 · 存储

初稿出处: 涂根华   

一:Iframe父页面与子页面之间的调用

正式词语解释如下:

    Iframe:iframe成分是文书档案中的文书档案。

    window对象: 浏览器会在其开辟三个HTML文书档案时创建三个对应的window对象。不过,假诺三个文书档案定义了多个恐怕多少个框架

(即:满含一个要么多个frame恐怕iframe标签),浏览器就能为本来文书档案创造贰个window对象,再为各个iframe创设额外的window对象,这几个额外的window对象是原有窗口的子窗口。

contentWindow: 是指钦定的iframe可能iframe所在的window对象。

   1. 父页面与子页面之间的调用。

明天大家能够渐渐做demo来分别授课下,如若有iframe父页面为 iframe1.html, 父页面上有2个子页面 分别为iframe2.html 和 iframe3.html。

父页面iframe1.html代码如下:

XHTML

<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <script src="jquery1.7.js"></script> </head> <body> <iframe src="" id = "iframe3"></iframe> <iframe src="" id = "iframe2"></iframe> <div class="iframe1">父页面</div> <script> function test2() { console.log(1); } </script> </body> </html>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <script src="jquery1.7.js"></script>
</head>
<body>
    <iframe src="http://localhost/iframe/iframe3.html" id = "iframe3"></iframe>
    <iframe src="http://localhost/iframe/iframe2.html" id = "iframe2"></iframe>
    <div class="iframe1">父页面</div>
   <script>
    function test2() {
        console.log(1);
    }
   </script>
</body>
</html>

子页面iframe2.html代码如下:

XHTML

<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <script src="jquery1.7.js"></script> </head> <body> <div id="test">aaa</div> <div class="iframe2">子页面</div> <script> function b() { console.log("作者是子页面"); } function iframe3Page() { console.log("iframe3页面调用iframe2页面"); } </script> </body> </html>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<!doctype html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
  <script src="jquery1.7.js"></script>
</head>
<body>
    <div id="test">aaa</div>
    <div class="iframe2">子页面</div>
       <script>
           function b() {
           console.log("我是子页面");
       }
       function iframe3Page() {
           console.log("iframe3页面调用iframe2页面");
       }
      </script>
</body>
</html>

1.  子页面iframe2.html调用父页面 iframe1.html的因素如下代码:

    console.log($(‘.iframe1’,parent.document));

2.  子页面iframe2.html调用父页面iframe1.html的函数如下代码:

    parent.test2();

潜心:父页面iframe1.html页面 中test2方法不能够放在$(function(){}), 放在里面就调用不到。

3. 子页面iframe2.html调用作者的iframe(即使父页面有过多iframe,获取自己iframe不经过id可能name属性).

    1.首先大家得以在父页面上写一个函数 用来得到页面全体的iframe,之后实行遍历,进行判断当前的window对象是还是不是同样。如下代码:

JavaScript

function getFrame(f){ var frames = document.getElementsByTagName("iframe"); for(i=0;i){ if(frames[i].contentWindow == f){ return(frames[i]) } } }

1
2
3
4
5
6
7
8
function getFrame(f){
    var frames = document.getElementsByTagName("iframe");
    for(i=0;i){
         if(frames[i].contentWindow == f){
              return(frames[i])
          }
      }
  }

    2. 在子页面iframe2.html中如下调用父页面包车型客车点子 getFrame.

JavaScript

/* 获取自己的iframe */ var aa = parent.getFrame(this); console.log(aa); $(aa).attr("flag",true);

1
2
3
4
/* 获取自身的iframe */
var aa = parent.getFrame(this);
console.log(aa);
$(aa).attr("flag",true);

给iframe2设置属性 flag: true, 如下截图:

图片 1

4. 父页面iframe1.html调用子页面 iframe2.html的要素及函数.

正如调用有误的:

console.log(document.getElementById(“iframe2”).contentWindow.b());

因为iframe2.html 有不小希望未加载成功,所以要等iframe2加载成功后再开展调用,

之所以大家须求 iframe2.onload = function(){}; 那样再开展调用。为了包容IE,咱们得以如下封装七个方法:

JavaScript

function iframeIsLoad(iframe,callback){ if(iframe.attachEvent) { iframe.attachEvent('onload',function(){ callback & callback(); }); }else { iframe.onload = function(){ callback & callback(); } } } // 调用格局如下: // 父页面调用子页面iframe2的方式 var iframe2 = document.getElementById("iframe2"); iframeIsLoad(iframe2,function(){ iframe2.contentWindow.b(); // 打字与印刷出 小编是子页面 // 父页面获取子页面iframe2的要素 var iframeDom = $(".iframe2",iframe2.contentWindow.document); console.log(iframeDom); });

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
function iframeIsLoad(iframe,callback){
    if(iframe.attachEvent) {  
         iframe.attachEvent('onload',function(){
             callback & callback();
         });
 
    }else {
         iframe.onload = function(){
              callback & callback();
         }
    }
}
// 调用方式如下:
// 父页面调用子页面iframe2的方法
var iframe2 = document.getElementById("iframe2");
iframeIsLoad(iframe2,function(){
    iframe2.contentWindow.b(); // 打印出 我是子页面  
    // 父页面获取子页面iframe2的元素
    var iframeDom = $(".iframe2",iframe2.contentWindow.document);
    console.log(iframeDom);
 
});

二:领会JSONP跨域本领的基本原理

Javascript是一种在web开垦中临时应用的前端动态脚本本领,在javascript中,有一个很要紧的平安范围,被叫作”same-Origin-Policy”同源计策,这一政策对于javascript代码能够访问的页面内容作了很注重的范围,即javascript只好访谈与分包它的文档在同契约,同域名,同端口的本子进行互动;

JSONP的基本原理是:利用在页面中开创节点的法子向差别域提交http伏乞的点子称为JSONP。

JSONP的有血有肉完成格局如下:

先是我们为了演示跨域,大家在host文件夹下绑定如下2个域名如下:

   127.0.0.1  abc.example1.com

   127.0.0.1  def.example2.com

中间在abc.example1.com域名下有叁个a.html页面;访谈页面路线如下:

   

1. 我们在域名下abc.example1.com下的a.html页面引进贰个域名称为def.example2.com下的a.js文件;如下:

  然后在a.js代码变为如下:

JavaScript

   function jsonp(){         alert(1)    }   jsonp();

1
2
3
4
   function jsonp(){
        alert(1)
   }
  jsonp();

聊到底大家在域名下abc.example1.com下的a.html页面运营下得以观察弹出对话框 “1”;大家可以看见引进不一样域名下的js文件也能跨域实践;

2. 假诺自身在域名称叫def.example2.com下的a.js文件是或不是调用a.html的情势名吧?大家后续来演示这些demo;大家在abc.example1.com下的a.html引进文件如下:

JavaScript

function jsonp(){     alert(1) }

1
2
3
4
5
function jsonp(){
 
    alert(1)
 
}

内部域名称叫def.example2.com下的a.js内容为:jsonp(); 大家三番两次来运维下页面,能够阅览,照旧得以弹出对话框 1;

3.  只要笔者在外场的调用方法是不是传递二个参数呢?大家三番五次和第二点同样,只是格局里面多了叁个参数字传送进去就可以:如下代码:

def.example2.com下的a.js内容为:jsonp(“小编是来测量试验的”);abc.example1.com下的a.html文件内容为:

JavaScript

 function jsonp(html){        alert(html)   }

1
2
3
 function jsonp(html){
       alert(html)
  }

咱俩运转下页面a.html,也可以看来弹出了对话框 “作者是来测量试验的”文案;所以,大家就能够透过这种艺术来给页面中传唱外站的数量;能够兑现JSONP的跨域数据;

明亮JSONP施行进程如下:

    首先在客商端注册三个callback(举例jsonpcallback),然后把callback名字(比方叫jsonp123456)传给服务器端,服务器端获得callback名字后,要求用jsonp123456(),把将在输出的json内容包涵起来,此时,服务器生成的json数据技能被客商摆正确接受;然后以javascript语法的不二等秘书诀,生成贰个function,function的名字正是传递回来的参数jsonp123456.然后就可以在顾客端直接运转调用jsonp123456以此函数了;

示范代码如下:

在域名下abc.example1.com下的a.html页面代码如下:

动态创设script标签,给script动态设置src值为域名def.example2.com,那样就落到实处在区别的域名下了;

如下代码:

JavaScript

<script> function jsonp123456(data){ alert(data.name); // tugenhua alert(data.age); // 28 alert(data.single); // yes } var eleScript= document.createElement("script"); eleScript.type = "text/javascript"; eleScript.src = ""; document.getElementsByTagName("HEAD")[0].appendChild(eleScript); </script> //在def.example2.com域名下的a.js代码如下: jsonp123456({"name":'tugenhua','age':'28','single':'yes'});

1
2
3
4
5
6
7
8
9
10
11
12
13
<script>
    function jsonp123456(data){
        alert(data.name); // tugenhua
        alert(data.age);  // 28
        alert(data.single); // yes
    }
    var eleScript= document.createElement("script");
    eleScript.type = "text/javascript";
    eleScript.src = "http://def.example2.com/iframe/a.js?jsonpcallback=jsonp123456";
    document.getElementsByTagName("HEAD")[0].appendChild(eleScript);
</script>
//在def.example2.com域名下的a.js代码如下:
jsonp123456({"name":'tugenhua','age':'28','single':'yes'});

分析: 在a.html下给服务器端发送央浼,並且给劳务器端传递参数 jsonpcallback=jsonp123456;服务器端获得jsonpcallback那几个参数后;要求用jsonp123456(),把就要输出的json内容囊括起来,此时,服务器生成的json数据技术被客商纠正确接受;然后以javascript语法的措施,生成多少个function,function的名字就是传递回来的参数jsonp123456.然后就足以在客户端直接运维调用jsonp123456这些函数了;

如上演示的代码; 之后分别弹出data.name;data.age;及data.single;

JSONP的优点:

它不像XMLHttpRequest对象落成ajax央浼受到同源计谋的限定,它在具有的浏览器都支持,

比如说古老的IE6也支撑,而且在央求完毕后能够透过callback的点子传回结果;

JSONP的缺点:

1. 只接济get央求,不接济post诉求,它只帮助http跨域的恳求境况,

不能够解决分化域的五个页面之间怎么进行javascript调用的主题素材; 

  1. 出于它是get央求,传递的参数都拼在url后边,因而数据安全性不高;

三:iframe之间通信难点

1. iframe通信 分为:同域通讯 和 跨域通讯。所谓同域通讯是指   下的a.html页面嵌套 iframe 譬如: 的B.html页面,那七个页面数据开展通讯,比方本身想在父页面A.html 调用子页面个中的函数 大家很轻巧想到照旧google下 ;document.getElementById(‘iframeA’).contentWindow.b(); 这种办法,个中b 是子页面B.html中的三个函数。不过那样调用下有个难题本身郁结了十分久,正是既然在火狐下报那样的谬误, 如下图所示:

图片 2

b不是个函数 可是本身在子页面明明定义了如此贰个函数,那么为何会报那样的一无可取吗?经过细心解析及google,发掘有那样一个标题亟需了解,当iframe未有加载成功后 笔者就去实施那个js会报那样的荒唐,所以就试着在火狐下 用iframe.onload 这么些函数 举办测验,果然没有报错,是没有错的 所以就鲜明是这么些主题材料。所以就想写个宽容IE和火狐 google写个函数 来明确iframe已经加载成功!,其实给个回调函数来调用大家地点的不二法门。

综述上边的思绪 A.html 就足以写个如此的代码:

JavaScript

<iframe src="" id="iframeA" name="iframeA"></iframe> <div id="topName">topNddddddddddddddddame</div> <script> function A(){ alert("A"); } var iframe = document.getElementById('iframeA'); iframeIsLoad(iframe,function(){ var obj = document.getElementById('iframeA').contentWindow; obj.b(); }); function iframeIsLoad(iframe,callback){ if(iframe.attach伊夫nt) { iframe.attachEvent('onload',function(){ callback && callback(); }); }else { iframe.onload = function(){ callback && callback(); } } } </script> B.html 代码如下: var b = function(){ alert("B"); };

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<iframe src="http://localhost/demo/iframe/iframeB.html" id="iframeA" name="iframeA"></iframe>
<div id="topName">topNddddddddddddddddame</div>
<script>
    function A(){
        alert("A");
    }
    var iframe = document.getElementById('iframeA');
    iframeIsLoad(iframe,function(){
        var obj = document.getElementById('iframeA').contentWindow;
        obj.b();
    });
     function iframeIsLoad(iframe,callback){
        if(iframe.attachEvent) {
            iframe.attachEvent('onload',function(){
                callback && callback();
            });
        }else {
            iframe.onload = function(){
                callback && callback();
            }
        }
     }
</script>
B.html 代码如下:
var b = function(){
    alert("B");
};

2.子页面调用父页面包车型大巴函数很轻巧,只要这么搞下就ok了,window.parent.A();

3. 子页面取父页面成分的值: window.parent.document.getElementById(“topName”).innerHTML等方法。

二: iframe跨域通讯。

iframe跨域访谈经常分为2种情形,第一种是同主域,不一样子域的跨域。 第三种是:不一样主域跨域。

一、 是同主域下边,未来和过去特不一致子域之间的跨域;能够经过document.domain 来安装同样的主域来消除。

如果今后自己有个域 abc.example.com 下有个页面叫abc.html, 页面上嵌套了一个iframe 如下:

XHTML

<iframe src="" id="iframe2" style="display:none;"></iframe>,

1
<iframe src="http://def.example.com/demo/def.html"  id="iframe2" style="display:none;"></iframe>,

小编想在abc域下的页面abc.html 访问 def域下的def.html  我们都精通是因为安全性 游历器的同源攻略的界定,js不能操作页面不相同域下 不一样协商下 分化端口的页面,所以将在化解跨域访谈了,假诺父页面abc.html 页面有个js函数:

 function test(){console.log(1);};

 小编想在子页面调用那么些函数 照旧依照地方的同域情势调用 parent.test();那样,通过在火狐下看 已经跨域了 解决的不二诀如若 在种种js函数顶端 加一句 document.domain = ‘example.com’,就能够解决了。

 abc.html代码如下:

XHTML

<iframe src="" id="iframe2" style="display:none;"></iframe> // 跨域 子页调用父页的 函数 (假使是下边test函数) document.domain = 'example.com'; function test(){console.log(1);};

1
2
3
4
<iframe src="http://def.example.com/demo/def.html"  id="iframe2" style="display:none;"></iframe>
  // 跨域 子页调用父页的 函数 (假设是下面test函数)
  document.domain = 'example.com';
  function test(){console.log(1);};

def.html代码如下:

JavaScript

/* * 子页调用父页的法子 */ document.domain = 'example.com'; //window.top.test(); window.parent.test();

1
2
3
4
5
6
/*
* 子页调用父页的方法
*/
document.domain = 'example.com';
//window.top.test();
window.parent.test();

要么那多少个页面 小编想父页调用子页 如下方法:

a.html代码如下:

JavaScript

/* * 跨域 父页想调用子页的的函数 */ document.domain = 'example.com'; var iframe = document.getElementById('iframe2'); iframeIsLoad(iframe,function(){ var obj = iframe.contentWindow; obj.child(); }); function iframeIsLoad(iframe,callback){ if(iframe.attachEvent) { iframe.attachEvent('onload',function(){ callback & callback(); }); }else { iframe.onload = function(){ callback & callback(); } } }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/*
* 跨域 父页想调用子页的的函数
*/
document.domain = 'example.com';
var iframe = document.getElementById('iframe2');
iframeIsLoad(iframe,function(){
    var obj = iframe.contentWindow;
         obj.child();
});
function iframeIsLoad(iframe,callback){
        if(iframe.attachEvent) {
            iframe.attachEvent('onload',function(){
                callback & callback();
            });
        }else {
            iframe.onload = function(){
                callback & callback();
            }
        }
}

假诺以后def.html页面有个child函数 代码如下:

JavaScript

document.domain = 'example.com'; function child(){console.log('笔者是子页');}

1
2
document.domain = 'example.com';
function child(){console.log('我是子页');}

就能够跨域调用了 不管是子页面调用父页面 依旧父页面调用子页面。一切ok!

三:是分化主域跨域;

就算如此google有三种情势有关差异主域上的跨域难题 有通过location.hash方法还是window.name方法照旧html5及flash等等,

然则作者以为上面iframe这种办法值得学习下,如下图所示:

图片 3

域a.com的页面request.html(即

思路:要贯彻a.com域下的request.html页面须求域b.com下的process.php,能够将诉求参数通过url传给response.html,由response.html向process.php发起真正的ajax央求(response.html与process.php都属于域b.com),然后将赶回的结果通过url传给proxy.html,最终由于proxy.html和request.html是在同个域下,所以能够在proxy.html利用window.top 将结果回到在request.html达成真正的跨域。

ok, 先看看页面结构

a.com域下有:

 request.html  proxy.html

1
2
 request.html
 proxy.html

b.com域下有:

response.html Process.php

1
2
3
response.html
 
Process.php

先来探视request.html页面如下:

XHTML

<!DOCTYPE HTML> <html> <head> <title> New Document </title> </head> <body> <p id="result">这里将会填上响应的结果</p> <a id="sendBtn" href="javascript:void(0)">点击,发送跨域乞请</a> <iframe id="serverIf" style="display:none"></iframe> <script> document.getElementById('sendBtn').onclick = function() { var url = '', fn = 'GetPerson', //那是概念在response.html的主意 reqdata = '{"id" : 24}', //那是呼吁的参数 callback = "CallBack"; //那是伸手全经过做到后实践的回调函数,试行最终的动作 CrossRequest(url, fn, reqdata, callback); //发送央求 } function CrossRequest(url,fn,reqdata,callback) { var server = document.getElementById('serverIf'); server.src = url + '?fn=' +encodeUPAJEROIComponent(fn) + "&data=" +encodeUXC60IComponent(reqdata) + "&callback="+encodeUCR-VIComponent(callback); } //回调函数 function CallBack(data) { var str = "My name is " + data.name + ". I am a " + data.sex + ". I am " + data.age + " years old."; document.getElementById("result").innerHTML = str; } </script> </body> </html>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<!DOCTYPE HTML>
<html>
<head>
  <title> New Document </title>
</head>
<body>
    <p id="result">这里将会填上响应的结果</p>
    <a id="sendBtn" href="javascript:void(0)">点击,发送跨域请求</a>
    <iframe id="serverIf" style="display:none"></iframe>
 
    <script>
        document.getElementById('sendBtn').onclick = function() {
            var url = 'http://b.com/demo/ajax/ajaxproxy/reponse.html',
                fn = 'GetPerson',          //这是定义在response.html的方法
                reqdata = '{"id" : 24}',   //这是请求的参数
                callback = "CallBack";     //这是请求全过程完成后执行的回调函数,执行最后的动作
 
            CrossRequest(url, fn, reqdata, callback);  //发送请求
        }
 
        function CrossRequest(url,fn,reqdata,callback) {
            var server = document.getElementById('serverIf');
            server.src = url + '?fn=' +encodeURIComponent(fn) + "&data=" +encodeURIComponent(reqdata) + "&callback="+encodeURIComponent(callback);
        }
        //回调函数
        function CallBack(data) {
            var str = "My name is " + data.name + ". I am a " + data.sex + ". I am " + data.age + " years old.";
             document.getElementById("result").innerHTML = str;
        }
    </script>
</body>
</html>

其一页面其实正是要告诉response.html:小编要让你施行你定义好的点子GetPerson,何况要用作者给您的参数'{“id” : 24}’。

response.html纯粹是担任将CallBack那些方法名传递给下一个人兄长proxy.html,而proxy.html得到了CallBack那些法子名就能够试行了,

因为proxy.html和request.html是同域的。

response.html代码如下:

XHTML

<!DOCTYPE HTML> <html> <head> <title> New Document </title> </head> <body> <iframe id="proxy"></iframe> <script> // 通用方法 ajax需要function _request (reqdata,url,callback) { var xmlhttp; if(window.XMLHttpRequest) { xmlhttp = new XMLHttpRequest(); }else { xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); } xmlhttp.onreadystatechange = function(){ if(xmlhttp.readyState == 4 && xmlhttp.status == 200) { var data = xmlhttp.responseText; callback(data); } } xmlhttp.open('POST',url); xmlhttp.setRequestHeader("Content-Type", "application/json; charset=utf-8"); xmlhttp.send(reqdata); } // 通用方法 获取url参数 function _getQuery(key) { var query = location.href.split('?')[1], value = decodeURIComponent(query.split(key + "=")[1].split("&")[0]); return value; } //向process.php发送ajax请求 function GetPerson(reqdata,callback) { var url = ''; var fn = function(data) { var proxy = document.getElementById('proxy'); proxy.src = "" + encodeURIComponent(data) + "&callback=" + encodeURIComponent(callback); }; _request(reqdata, url, fn); } (function(){ var fn = _getQuery('fn'), reqdata = _getQuery("data"), callback = _getQuery("callback"); eval(fn + "('" + reqdata +"', '" + callback + "')"); })(); </script> </body> </html>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
<!DOCTYPE HTML>
<html>
<head>
  <title> New Document </title>
</head>
<body>
     <iframe id="proxy"></iframe>
    <script>
        // 通用方法 ajax请求
        function _request (reqdata,url,callback) {
            var xmlhttp;
            if(window.XMLHttpRequest) {
                xmlhttp = new XMLHttpRequest();
            }else {
                xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
            }
 
            xmlhttp.onreadystatechange = function(){
                if(xmlhttp.readyState == 4 && xmlhttp.status == 200) {
                    var data = xmlhttp.responseText;
                    callback(data);
                }
            }
            xmlhttp.open('POST',url);
            xmlhttp.setRequestHeader("Content-Type", "application/json; charset=utf-8");
            xmlhttp.send(reqdata);
        }
 
        // 通用方法 获取url参数
        function _getQuery(key) {
            var query = location.href.split('?')[1],
                value = decodeURIComponent(query.split(key + "=")[1].split("&")[0]);
            return value;
        }
 
        //向process.php发送ajax请求
        function GetPerson(reqdata,callback) {
            var url = 'http://b.com/demo/ajax/ajaxproxy/process.php';
            var fn = function(data) {
                var proxy = document.getElementById('proxy');
                proxy.src = "http://a.com/demo/ajax/ajaxproxy/Proxy.html?data=" + encodeURIComponent(data) + "&callback=" + encodeURIComponent(callback);
            };
            _request(reqdata, url, fn);
        }
 
        (function(){
            var fn = _getQuery('fn'),
                reqdata = _getQuery("data"),
                callback = _getQuery("callback");
           eval(fn + "('" + reqdata +"', '" + callback + "')");
        })();
    </script>
</body>
</html>

这里其实正是抽出来自request.html的央浼获得央浼参数和章程后向服务器process.php发出真正的ajax供给,然后将从服务器再次回到的数码以及从request.html传过来的回调函数名传递给proxy.html。 

接下去看看php代码如下,其实就是想重回多少个json数据:

PHP

<?php $data = json_decode(file_get_contents("php://input")); header("Content-Type: application/json; charset=utf-8"); echo ('{"id" : ' . $data->id . ', "age" : 24, "sex" : "boy", "name" : "huangxueming"}'); ?>

1
2
3
4
5
<?php
    $data = json_decode(file_get_contents("php://input"));
    header("Content-Type: application/json; charset=utf-8");
    echo ('{"id" : ' . $data->id . ', "age" : 24, "sex" : "boy", "name" : "huangxueming"}');
?>

最终正是proxy.html代码:

XHTML

<!DOCTYPE HTML> <html> <head> <title> New Document </title> </head> <body> <script> function _getUrl(key) {//通用方法,获取UEscortL参数 var query = location.href.split("?")[1], value = decodeURIComponent(query.split(key + "=")[1].split("&")[0]); return value; } (function() { var callback = _getUrl("callback"), data = _getUrl("data"); eval("window.top." + decodeURIComponent(callback) + "(" + decodeURIComponent(data) + ")"); })(); </script> </body> </html>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<!DOCTYPE HTML>
<html>
<head>
  <title> New Document </title>
</head>
<body>
    <script>
         function _getUrl(key) {//通用方法,获取URL参数
                       var query = location.href.split("?")[1],
                value = decodeURIComponent(query.split(key + "=")[1].split("&")[0]);
                    return value;
               }
         (function() {
             var callback = _getUrl("callback"),
                 data = _getUrl("data");
             eval("window.top." + decodeURIComponent(callback) + "(" + decodeURIComponent(data) + ")");
         })();
    </script>
</body>
</html>

那边也是终极一步了,proxy终于获得了request.html透过response.html传过来的回调函数名以及从response.html直接传过来的响应数据,

行使window.top执行request.html里定义的回调函数。

四:iframe中度自适应的主题素材。

  iframe中度自适应分为2种,一种是同域下自适应  另外一种是跨域下自适应,下边大家来拜访同域下iframe高度自适应的主题材料。

   1. 同域下iframe高度自适应的标题:

     思路:获取被嵌套iframe元素,通过JavaScript获得被嵌套页面最后高度,然后在主页面举行安装来落到实处。

     假若大家demo有iframe1.html和iframe2.html 上边贴上iframe1.html代码如下:

XHTML

<!DOCTYPE HTML> <html> <head> <title> New Document </title> <style> *{margin:0;padding:0;} </style> </head> <body> <iframe src="" style="width:100%;border:1px solid #333;" frameborder="0" id="iframe"></iframe> <script> window.onload = function() { var iframeid = document.getElementById('iframe'); if(iframeid && !window.opera) { if(iframeid.contentDocument && iframeid.contentDocument.body.offsetHeight) { iframeid.height = iframeid.contentDocument.body.offsetHeight; }else if(iframeid.Document && iframeid.Document.body.scrollHeight){ iframeid.height = iframeid.Document.body.scrollHeight; } } } </script> </body> </html>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<!DOCTYPE HTML>
<html>
<head>
  <title> New Document </title>
  <style>
    *{margin:0;padding:0;}
  </style>
</head>
 
<body>
    <iframe src="http://a.com/demo/ajax/iframeheight/iframe2.html" style="width:100%;border:1px solid #333;" frameborder="0" id="iframe"></iframe>
 
    <script>
        window.onload = function() {
            var iframeid = document.getElementById('iframe');
            if(iframeid && !window.opera) {
                if(iframeid.contentDocument && iframeid.contentDocument.body.offsetHeight) {
                    iframeid.height = iframeid.contentDocument.body.offsetHeight;
                }else if(iframeid.Document && iframeid.Document.body.scrollHeight){
                    iframeid.height = iframeid.Document.body.scrollHeight;
                }
            }
        }
    </script>
</body>
</html>

iframe2.html代码如下:

XHTML

<!DOCTYPE HTML> <html> <head> <title> New Document </title> <style> *{margin:0;padding:0;} </style> </head> <body> <div style="height:500px;"></div> </body> </html>

1
2
3
4
5
6
7
8
9
10
11
12
13
<!DOCTYPE HTML>
<html>
<head>
  <title> New Document </title>
  <style>
    *{margin:0;padding:0;}
  </style>
</head>
 
<body>
    <div style="height:500px;"></div>
</body>
</html>

就能够动态设置iframe1页面的万丈为iframe2的万丈了。

2. 跨域下iframe中度自适应的难点。

先是大家精晓iframe跨域大家是无法用上边js方式来调整了,所以大家只可以用个中间键,我们能够在a.com域下iframe1.html页面嵌套三个b.com域下的iframe2.html页面,然后笔者在iframe2.html页面嵌套个和iframe1.html同样域的iframe3.html页面了,那样的话 iframe1.html和iframe3.html就足以无障碍的进展通讯了,因为页面iframe2.html嵌套iframe3.html,所以iframe2.html足以改写iframe3.html的href值。

 iframe第11中学的内容:

 iframe1.html故事情节首要收受iframe3.html页面传过来的内容还要去达成相应的操作。iframe1.html代码如下:

XHTML

<iframe src="" style="width:400px;height:200px;" id="iframe"></iframe> <script> var ifr_el = document.getElementById("iframe"); function getIfrData(data){ ifr_el.style.height = data+"px"; } </script>

1
2
3
4
5
6
7
<iframe src="http://b.com/demo/ajax/iframeheight/iframe2.html" style="width:400px;height:200px;" id="iframe"></iframe>
<script>
   var ifr_el = document.getElementById("iframe");
   function getIfrData(data){
    ifr_el.style.height = data+"px";
   }
</script>

iframe2.html中的内容:

iframe2.html故事情节是怎么把值传给iframe3.html页面,刚才说了是将值传递到iframe3.html页面包车型客车href中,所以只要修改iframe的src就足以,因为不用刷新C页面,所以能够用过hash的方法传送给iframe3.html页面.iframe2.html代码如下:

JavaScript

<!DOCTYPE HTML> <html> <head> <title> New Document </title> <style> *{margin:0;padding:0;} </style> </head> <body> <iframe id="iframe" src="" width="0" height="230px"></iframe> <script> var oldHeight = 0, ifr_el = document.getElementById("iframe"); t && clearInterval(t); var t = setInterval(function(){ var height = document.body.scrollHeight; if(oldHeight != height) { oldHeight = height; ifr_el.src += '#' +oldHeight; } },200); </script> </body> </html>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<!DOCTYPE HTML>
<html>
<head>
  <title> New Document </title>
  <style>
    *{margin:0;padding:0;}
  </style>
</head>
<body>
    <iframe id="iframe" src="http://a.com/demo/ajax/iframeheight/iframe3.html" width="0" height="230px"></iframe>
    <script>
        var oldHeight = 0,
              ifr_el = document.getElementById("iframe");
 
        t && clearInterval(t);
        var t = setInterval(function(){
            var height = document.body.scrollHeight;
            if(oldHeight != height) {
                oldHeight = height;
                ifr_el.src += '#' +oldHeight;
            }
        },200);
    </script>
</body>
</html>

能够见见 私下认可意况下 iframe1.html 页面笔者给iframe2.html的惊人是200像素, 不过在iframe2.html自家给iframe3.html中度是230像素,那么平常境况下是有滚动条的,那么今后作者是想在iframe2.html取得滚动条的中度,把高度传给通过iframe3.html的src里面去,然后在iframe3.html页面里获得那在那之中度值 传给iframe1.html(因为iframe1.html和iframe3.html是同域的),所以iframe1.html能取到那么些高度值,再安装下自家的冲天正是以此值就ok了。iframe3.html页面包车型大巴独一功能就是吸收接纳iframe2.html页面通过href传进来的值况兼传递给iframe1.html页面,可到iframe2.html页面传来的值能够通过三个反应计时器不停去查看location.href是 否被改换,不过这么感到功效十分的低,还会有个法子便是在新的浏览器中经过onhashchange事件 (IE8+,Chrome5.0+,Firefox3.6+,Safari5.0+,Opera10.6+)来监听href的转移。

iframe3.html代码如下:

JavaScript

<script> var oldHeight = 0; t && clearInterval(t); var t = setInterval(function(){ var height = location.href.split('#')[1]; if(height && height != oldHeight) { oldHeight = height; if(window.parent.parent.getIfrData) { window.parent.parent.getIfrData(oldHeight); } } },200); </script>

1
2
3
4
5
6
7
8
9
10
11
12
13
<script>
    var oldHeight = 0;
    t && clearInterval(t);
    var t = setInterval(function(){
        var height = location.href.split('#')[1];
        if(height && height != oldHeight) {
            oldHeight = height;
            if(window.parent.parent.getIfrData) {
                window.parent.parent.getIfrData(oldHeight);
            }
        }
    },200);
</script>

如此就可以缓慢解决由此跨域实现iframe自适应中度的主题素材了。

五:本地存款和储蓄cookie,sessionStorage, localStorage比较及使用

一:Cookie

1. 什么是cookie?

     Cookie是在顾客端用于存款和储蓄会话音讯的,顾客央浼页面在web服务器与浏览器之间传递。每当同一台Computer通过浏览器乞求某些页面时,就能够发送这些 cookie。

 2. cookie的限制?

     1. Cookie的多寡大小限制只好为4kb数据,要是数额长度超越4kb数据,超越后的数量将赶回空字符串。

     2. Cookie是以文件格局储存在客商端Computer中,查看和退换cookie很便利,然而安全性方面不佳,由此首要的数量毫无使用cookie来储存。

     3. Cookie是有 有效期概念的,要是想要cookie存款和储蓄多久,能够设置cookie的时间,日常的图景下,cookie的生命周期是在游历器关闭的时候失效。

     4. Cookie是有域的定义的,在分化的域下,cookie无法互相接纳,cookie对于那么些域是有效的,全数向该域发送的需要中都会蕴藏那个cookie 的新闻的,

    那几个值能够满含子域(subdomain 如www.zuixiandao.cn) ,也得以不包罗它(如.zuixiandao.cn, 对于有着的zuixiandao.cn的富有子域都使得). 

    若无显著的钦点,那么那些域会被认作来自设置cookie的那多少个域。

     5. Cookie路线的定义:对于钦定域中的那些路线,应该向服务器发送cookie,比如大家能够钦赐cookie独有从

     6. Cookie失效时间的定义:表示cookie曾几何时应有被删除,默许景况下,浏览器会话甘休时将要删除全体的cookie,但是也得以团结设置

 删除时间的。那些值是个卡那霉素T格式的日子(Wdy DD-Mon-YYYY HH:MM:SS 链霉素T),用于钦赐相应删除cookie的可相信时间,因而,

 cookie可在浏览器关闭后还是保留在客户的机械上(同贰个浏览器,分化的浏览器无法保存),如若设置的日子是晚点的日子,那么cookie立即删掉。

      7. Cookie康宁标识 钦定后,cookie只有在运用SSL连接的时候才发送到服务器。比如:cookie信息只可以发送给, 

  而

二: javascript中的cookie

 1. Javascript中的cookie是 一密密麻麻由支行隔离的名-值对,如上边包车型地铁Taobao的cookie,如下:

document.cookie = “isg=E5AA5F2CEE8AA93BB351D1601F7B218E; thw=cn; _med=dw:1920&dh:1080&pw:1920&ph:1080&ist:0; v=0; t=1292efa78d867ff6275e6c5cb971bed7”;

     2. 设置cookie的超时。

         expires;   // 设置cookie的逾期的日子

         以下设置 cookie 在 365天后超时;

         var date = new Date();

         date.setTime(date.getTime()+365*24*3600*1000);

         document.cookie = ‘key:value;expires =’ + date.toGMTString();

上边是安装cookie, 删除cookie,及 获取cookie的包装代码如下:

JavaScript

// 获取具备的cookies function getCookies() { var allCookies = document.cookie; return decodeUTiggoIComponent(allCookies); } // 获取钦赐的cookie function getOneCookie(name) { var allCookies = document.cookie.split(";"); for(var i = 0, ilen = allCookies.length; i < ilen; i++) { var temp = allCookies[i].split("="); if($.trim(decodeURIComponent(temp[0])) == name) { return decodeURIComponent(temp[1]); } } return -1; } // 加多cookie 保藏期是一年 function addCookie(name,value,expires,path,domain,secure) { var curCookie = encodeU奇骏IComponent(name) + '=' + encodeU兰德WranglerIComponent(value); if(expires instanceof Date) { curCookie += ';expires =' + expires.to土霉素TString(); }else { var date = new Date(); date.setTime(date.getTime()+365*24*3600*1000); curCookie += ';expires =' + date.toGMTString(); } if(path) { curCookie += "; path=" + path; } if(domain) { curCookie += "; domain=" +domain; } if(secure) { curCookie += "; secure"; } document.cookie = curCookie; } // 删除cookie function removeCookie(name,path,domain,secure) { addCookie(name,"",new Date(0),path,domain,secure); }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
// 获取所有的cookies
function getCookies() {
    var allCookies = document.cookie;
    return decodeURIComponent(allCookies);
}
// 获取指定的cookie
function getOneCookie(name) {
    var allCookies = document.cookie.split(";");
    for(var i = 0, ilen = allCookies.length; i < ilen; i++) {
        var temp = allCookies[i].split("=");
        if($.trim(decodeURIComponent(temp[0])) == name) {
            return decodeURIComponent(temp[1]);
         }
    }
    return -1;
}
// 添加cookie 有效期是一年
function addCookie(name,value,expires,path,domain,secure) {
    var curCookie = encodeURIComponent(name) + '=' + encodeURIComponent(value);
    if(expires instanceof Date) {
        curCookie += ';expires =' + expires.toGMTString();
    }else {
        var date = new Date();                
        date.setTime(date.getTime()+365*24*3600*1000);
        curCookie += ';expires =' + date.toGMTString();
    }
    if(path) {
        curCookie += "; path=" + path;
    }
    if(domain) {
        curCookie += "; domain=" +domain;
    }
    if(secure) {
        curCookie += "; secure";
    }
    document.cookie = curCookie;
}
// 删除cookie
function removeCookie(name,path,domain,secure) {
     addCookie(name,"",new Date(0),path,domain,secure);
}

上边大家来做一个小需要,举例贰个登录页面,有 有户名,密码,记住密码,及展现cookie和删除cookie开关。当自家点击记住密码的时候,那么当本人第重启开页面时候,只要输入客户名,密码会自动填充,当然大家也能够点击删除cookie按键进行删除,如下代码:

HTML代码:

XHTML

<h2>cookie介绍</h2> <p> <label>顾客名:</label> <input type="text" class="userName" id="userName"/> </p> <p> <label>密码:</label> <input type="password" id="password"> </p> <p> <label>记住密码:</label> <input type="checkbox" id="remember"/> </p> <input value="删除" type="button" id="delCookie"> <input type="button" value="展现cookie" id="showpassword">

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<h2>cookie介绍</h2>
<p>
     <label>用户名:</label>
     <input type="text" class="userName" id="userName"/>
</p>
<p>
     <label>密码:</label>
     <input type="password" id="password">
</p>
<p>
     <label>记住密码:</label>
     <input type="checkbox" id="remember"/>
</p>
<input value="删除" type="button" id="delCookie">  
<input type="button" value="显示cookie" id="showpassword">

JS代码如下:

JavaScript

<script> // 获取拥有的cookies function getCookies() { var all库克ies = document.cookie; return allCookies; } // 获取内定的cookie function getOneCookie(name) { var allCookies = document.cookie.split(";"); for(var i = 0, ilen = allCookies.length; i < ilen; i++) { var temp = allCookies[i].split("="); if(temp[0] == decodeURIComponent(name)) { return decodeURIComponent(temp[1]); } } return -1; } // 增多cookie 保质期是一年 function addCookie(name,value,expires,path,domain,secure) { var curCookie = encodeURubiconIComponent(name) + '=' + encodeURAV4IComponent(value); if(expires instanceof Date) { curCookie += ';expires =' + expires.to放线菌壮观素TString(); }else { var date = new Date(); date.setTime(date.get提姆e()+365*24*3600*1000); curCookie += ';expires =' + date.toGMTString(); } if(path) { curCookie += "; path=" + path; } if(domain) { curCookie += "; domain=" +domain; } if(secure) { curCookie += "; secure"; } document.cookie = curCookie; } // 删除cookie function removeCookie(name,path,domain,secure) { addCookie(name,"",new Date(0),path,domain,secure); } $("#userName").unbind('blur').bind('blur',function(){ var val = $(this).val(); if(val) { var curCookie = getOneCookie(val); if(curCookie != -1) { $("#password").val(cur库克ie); } } }); // 记住密码 $("#remember").unbind('click').bind('click',function(){ if(document.getElementById("remember").checked) { if($("#userName").val() && $("#password").val()) { addCookie($("#userName").val(),$("#password").val()); alert("Saved!"); } } }); // 删除cookie $("#delCookie").unbind('click').bind('click',function() { if($("#userName").val()) { removeCookie($("#userName").val()); alert(getCookies()); }else { alert("客户名称叫空"); } }); // 展现cookie $("#showpassword").unbind('click').bind('click',function(){ if($("#userName").val()) { var curCookie = getOneCookie($("#userName").val()); if(curCookie != -1) { alert(curCookie); }else { alert("没有cookie"); } }else { alert("没有cookie"); } }); </script>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
<script>
        // 获取所有的cookies
        function getCookies() {
            var allCookies = document.cookie;
            return allCookies;
        }
        // 获取指定的cookie
        function getOneCookie(name) {
            var allCookies = document.cookie.split(";");
            for(var i = 0, ilen = allCookies.length; i < ilen; i++) {
                var temp = allCookies[i].split("=");
                if(temp[0] == decodeURIComponent(name)) {
                    return decodeURIComponent(temp[1]);
                }
            }
            return -1;
        }
        // 添加cookie 有效期是一年
        function addCookie(name,value,expires,path,domain,secure) {
            var curCookie = encodeURIComponent(name) + '=' + encodeURIComponent(value);
            if(expires instanceof Date) {
                curCookie += ';expires =' + expires.toGMTString();
            }else {
                var date = new Date();
                date.setTime(date.getTime()+365*24*3600*1000);
                curCookie += ';expires =' + date.toGMTString();
            }
            if(path) {
                curCookie += "; path=" + path;
            }
            if(domain) {
                curCookie += "; domain=" +domain;
            }
            if(secure) {
                curCookie += "; secure";
            }
            document.cookie = curCookie;
        }
        // 删除cookie
        function removeCookie(name,path,domain,secure) {
            addCookie(name,"",new Date(0),path,domain,secure);
        }
 
        $("#userName").unbind('blur').bind('blur',function(){
              var val = $(this).val();
              if(val) {
                 var curCookie = getOneCookie(val);
                 if(curCookie != -1) {
                    $("#password").val(curCookie);
                 }
              }
        });
        // 记住密码
        $("#remember").unbind('click').bind('click',function(){
            if(document.getElementById("remember").checked) {
                if($("#userName").val() && $("#password").val()) {
                    addCookie($("#userName").val(),$("#password").val());  
                    alert("Saved!");
                }
 
            }
        });
        // 删除cookie
        $("#delCookie").unbind('click').bind('click',function() {
            if($("#userName").val()) {
                removeCookie($("#userName").val());
                alert(getCookies());
            }else {
                alert("用户名为空");
            }
        });
 
        // 显示cookie
        $("#showpassword").unbind('click').bind('click',function(){
            if($("#userName").val()) {
                var curCookie = getOneCookie($("#userName").val());
                if(curCookie != -1) {
                    alert(curCookie);
                }else {
                    alert("没有cookie");
                }
 
            }else {
                alert("没有cookie");
            }
        });
</script>

Cookie的实例demo如下:

cookie

三:IE客户数量;

在IE5.0中,微软由此一个自定义行为引进了持久化用户数量的概念,顾客数据允许每种文书档案最多128kb的数额,每一种域名最多1MB的多少,

要接纳长久化数据,首先必得如下所示,使用css在某些成分上钦命userData行为:

 

IE客商数据

 

本着IE有如下使用方式:

1. getAttribute(“key”) 获取钦点的属性值。

2. load(object) 从 userData 存款和储蓄区载入存款和储蓄的靶子数据。

3. removeAttribute(“key”) 移除对象的内定属性。

4. save(object) 将对象数据存款和储蓄到一个 userData 存款和储蓄区。

5. setAttribute(“key”,”value”) 设置钦赐的属性值。

我们三回九转做多少个demo来演示下在IE浏览器下的囤积的demo。

HTML代码如下:

XHTML

<div style="behavior:url(#default#userData)" id="dataStore">IE客商数据</div> <input value="IE下保存数据" type="button" id="IESave"> <input type="button" value="IE下获取数据" id="IEGet"> <input type="button" value="IE下删除数据" id="IERemove">

1
2
3
4
<div style="behavior:url(#default#userData)" id="dataStore">IE用户数据</div>
<input value="IE下保存数据" type="button" id="IESave">
<input type="button" value="IE下获取数据" id="IEGet">
<input type="button" value="IE下删除数据" id="IERemove">

JS代码如下:

JavaScript

var dataStore = document.getElementById("dataStore"); $("#IESave").click(function(e){ dataStore.setAttribute("name","tugenhua"); dataStore.setAttribute("book",'111111'); dataStore.save("bookInfo"); }); // IE下获取数据 $("#IEGet").click(function(){ dataStore.load("bookInfo"); alert(dataStore.getAttribute("name")); alert(dataStore.getAttribute("book")); }); // IE下删除数据 $("#IERemove").click(function(){ dataStore.removeAttribute("name"); dataStore.removeAttribute("book"); dataStore.save("bookInfo"); });

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
var dataStore = document.getElementById("dataStore");
$("#IESave").click(function(e){
    dataStore.setAttribute("name","tugenhua");
    dataStore.setAttribute("book",'111111');
    dataStore.save("bookInfo");
});
// IE下获取数据
$("#IEGet").click(function(){
    dataStore.load("bookInfo");
    alert(dataStore.getAttribute("name"));
    alert(dataStore.getAttribute("book"));
});
 
// IE下删除数据
$("#IERemove").click(function(){
    dataStore.removeAttribute("name");
    dataStore.removeAttribute("book");
    dataStore.save("bookInfo");
});

IE浏览器下的demo如下:

应用IE浏览器下查看效果 请点击自身!!

四:sessionStorage 和 localStorage 

Html5增加产量了四个地点存款和储蓄数据,分别是sessionStorage 和 localStorage.

浏览器辅助程度如下:

图片 4

留意:IE8 及 以上都帮衬 web storage。

   sessionStorage: 将数据保存在session对象中,所谓session,指顾客浏览有个别网址时,从进来网址到浏览器关闭的这段日子,也正是客商浏览那些网址所开支的小时。

       生命周期:指只在时下的窗口有效,张开三个新的同源窗口,或许说重启浏览器都失效。

       数码大小:能够保存5MB以致越来越多。

   localStorage: 将数据保存在客商端本地的硬件器械(常常是指硬盘,但也得以是任何硬件设施),即便浏览器被关门了,该数据依然留存,下一次开垦浏览器访谈网址时仍旧能够三翻五次运用。不过,数据保存是按分裂的浏览器分别张开的,也正是说,假如展开其余浏览器,是读取不到在这一个浏览器中保存的数量的。

     生命周期:数码直接保存在硬盘中。长久性保存(不过差异的浏览器保存的数量,是不能够通用的)。

     多少大小:能够保存5MB乃至更加多的多寡。

    1. cookie 与 sessionStorage 及 localStorage的区别;   

        共同点:都以在客商端存款和储蓄数据,且是同源的。

    区别:

仓库储存大小分歧样;cookie存款和储蓄数据最大不得不为4kb,而sessionStorage与localStorage能够保存5MB以至越多多少。

  库克ie数据始终在同源的http须要中引导,即cookie在浏览器与服务器之间来回传递,而sessionStorage与localStorage不会自动发给服务端,仅在本地保存。

多少有效期差别;sessionStorage仅在脚下浏览器窗口未关门以前有效(同源的新窗口不奏效),localStorage仅在时下的浏览器下恒久生效(差异的浏览器不能够分享数据),不管关闭了 重新张开的 依旧一蹴而就的。Cookie只在安装的cookie过期时间以前一向有效,尽管窗口可能浏览器关闭,可能展开新的同源窗口。

成效域差别;sessionStorage不在差异的浏览器窗口中国共产党享,正是同贰个页面,localStorage在富有的同源窗口中都以分享的(只在同一的浏览器下),cookie在有着的同源窗口都以分享的(仅在同三个浏览器中)。

      SessionStorage与LocalStorage他们都独具一致的点子;

      1. setItem存储value

         用法:.setItem( key, value),代码如下:

         localStorage.setItem(key,value):将value存储到key字段

      2. getItem获取value

          用法:.getItem(key) 代码如下:

          localStorage.getItem(key):获取钦赐key本地存款和储蓄的值

      3. removeItem删除key

          用法:.removeItem(key),代码如下:

          localStorage.removeItem(key):删除钦点key当地存款和储蓄的值

      4. clear清除全体的key/value

          用法:.clear(),代码如下:

          localStorage.clear();  清除全数的多少(firefox除却)

      它将去除全部同源的地面存款和储蓄的localStorage数据

      而对此Session Storage,它只清空当前对话存款和储蓄的多少。

      sessionStorage也是有地点同样的点子;

下边我们来行使sessionStorage及 localStorage 来练习下,来做个demo。如下:

HTML代码如下:

XHTML

<h1>web Storage实列</h1> <p id="msg"></p> <input type="text" id="input" /> <input type="button" value="保存数据" id="saveData"/> <input type="button" value="读取数据" id="readData"/> <input type="button" value="删除数据" id="removeData"/> <input type="button" value="清除全数的多少" id="clearData"/>

1
2
3
4
5
6
7
<h1>web Storage实列</h1>
<p id="msg"></p>
<input type="text" id="input" />
<input type="button" value="保存数据" id="saveData"/>
<input type="button" value="读取数据" id="readData"/>
<input type="button" value="删除数据" id="removeData"/>
<input type="button" value="清除所有的数据" id="clearData"/>

页面上二个input输入框,当小编点击 保存数据 开关后 分别使用sessionStorage和localStorage 把值保存起来,当自家点击 读取数据 按键后 读取数据,分别在分裂的浏览器如故新的同源窗口 大概关闭浏览器窗口 重新展开新窗口,来分别拜望里面包车型大巴不同,分裂上边已经总括了,下边我们来探视JS代码如下:

JavaScript

<script> // sessionStorage demo $("#saveData").unbind('click').bind('click',function(){ var inputVal = $("#input").val(); sessionStorage.setItem("message",inputVal); //localStorage.setItem("message",inputVal); }); $("#readData").unbind("click").bind('click',function(){ var msg = sessionStorage.getItem("message"); //var msg = localStorage.getItem("message"); $("#msg").html(msg); }); $("#removeData").unbind('click').bind('click',function(){ sessionStorage.removeItem("message"); //localStorage.removeItem("message"); }); $("#clearData").unbind('click').bind('click',function(){ sessionStorage.clear(); //localStorage.clear(); }); </script>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<script>
        // sessionStorage demo
        $("#saveData").unbind('click').bind('click',function(){
            var inputVal = $("#input").val();
            sessionStorage.setItem("message",inputVal);
            //localStorage.setItem("message",inputVal);
        });
        $("#readData").unbind("click").bind('click',function(){
            var msg = sessionStorage.getItem("message");
            //var msg = localStorage.getItem("message");
            $("#msg").html(msg);
        });
        $("#removeData").unbind('click').bind('click',function(){
            sessionStorage.removeItem("message");
            //localStorage.removeItem("message");
        });
        $("#clearData").unbind('click').bind('click',function(){
            sessionStorage.clear();
            //localStorage.clear();
        });
</script>

如上的代码,大家未来持续来探视效果如下:使用

sessionStorage效果请点击:

利用localStorage效果请点击:

咱俩还足以做一些复杂的采用,比如如下二个表格有局地字段,比如姓名,email,tel,及备注字段,大家先保存到地面去,然后遵照姓名这些字段进行检索就足以查找到多少到,我们能够叫做那是轻便的本土数据库,如下代码:

XHTML

<table> <tr> <td>姓名:</td> <td> <input type="text" id="name"/> </td> </tr> <tr> <td>EMALL:</td> <td> <input type="text" id="email"/> </td> </tr> <tr> <td>电话号码:</td> <td> <input type="text" id="tel"/> </td> </tr> <tr> <td>备注:</td> <td> <input type="text" id="memo"/> </td> </tr> <tr> <td>保存</td> <td> <input type="button" id="save" value="保存"/> </td> </tr> </table> <p> 检索:<input type="text" id="file"/> <input type="button" id="find" value="检索"/> </p> <p id="msg"></p>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<table>
    <tr>
        <td>姓名:</td>
        <td>
            <input type="text" id="name"/>
        </td>
    </tr>
    <tr>
        <td>EMALL:</td>
        <td>
            <input type="text" id="email"/>
        </td>
    </tr>
    <tr>
        <td>电话号码:</td>
        <td>
            <input type="text" id="tel"/>
        </td>
    </tr>
    <tr>
        <td>备注:</td>
        <td>
            <input type="text" id="memo"/>
        </td>
    </tr>
    <tr>
        <td>保存</td>
        <td>
           <input type="button" id="save" value="保存"/>
        </td>
    </tr>
</table>
<p>
     检索:<input type="text" id="file"/>
     <input type="button" id="find" value="检索"/>
</p>
<p id="msg"></p>

JS代码如下:

JavaScript

// 保存数据 $("#save").unbind('click').bind('click',function(){ var data = new Object; data.name = $("#name").val(); data.email = $("#email").val(); data.tel = $("#tel").val(); data.memo = $("#memo").val(); var str = JSON.stringify(data); localStorage.setItem(data.name,str); alert("数据已经保存"); }); // 检索数据 $("#find").unbind('click').bind('click',function(){ var find = $("#file").val(); var str = localStorage.getItem(find); var data = JSON.parse(str); var result = "姓名:" + data.name + "</br>"; result += "Email: " + data.email + "</br>"; result += "tel:" + data.tel + "</br>"; result += "备注:" + data.memo + "</br>"; $("#msg").html(result); });

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//  保存数据
$("#save").unbind('click').bind('click',function(){
     var data = new Object;
     data.name = $("#name").val();
     data.email = $("#email").val();
     data.tel = $("#tel").val();
     data.memo = $("#memo").val();
     var str = JSON.stringify(data);
     localStorage.setItem(data.name,str);
     alert("数据已经保存");
});
 
// 检索数据
$("#find").unbind('click').bind('click',function(){
      var find = $("#file").val();
      var str = localStorage.getItem(find);
      var data = JSON.parse(str);
      var result = "姓名:" + data.name + "</br>";
          result += "Email: " + data.email + "</br>";
          result += "tel:" + data.tel + "</br>";
          result += "备注:" + data.memo + "</br>";
      $("#msg").html(result);
  });

demo如下效果:

请点击查看:

六:window.name 达成跨域数据传输。

Window.name 中的name值在差别的页面(以致差异的域名)加载后仍旧存在,而且数据量能够达成2MB。

Window.name 数据传输的基本原理:

同域下:Name在浏览器情况中是贰个大局/window对象的性情,且当在ifrmae中加载页面时,name的属性值依然保持不变。

比方大家在同域下abc.example.com下 有2个页面 app.html 和 data.html

 App.html页面代码嵌套二个iframe data.html页面,代码如下:

XHTML

<iframe src="" id="iframe"/>

1
<iframe src="http://abc.example.com/demo/tugenhua0707/storage/data.html" id="iframe"/>

里面data.html 页面 使用三个window.name = “111”;来保存数据。

   现在我们接下去在app.html页面 如何来调用同域下的data.html下的window.name的数额,首先大家先要获取到那些iframe,然后判定iframe是不是加载完,加载完后就收获这么些iframe中的window.name, 

App.html JS的代码如下:

JavaScript

function iframeIsLoad(iframe,callback){ if(iframe.attachEvent) { iframe.attachEvent('onload',function(){ callback & callback(); }); }else { iframe.onload = function(){ callback & callback(); } } } var iframe = document.getElementById("iframe"); // 同域下 iframeIsLoad(iframe,function(){ var data = iframe.contentWindow.name; alert(data); });

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function iframeIsLoad(iframe,callback){
    if(iframe.attachEvent) {
         iframe.attachEvent('onload',function(){
          callback & callback();
         });
    }else {
        iframe.onload = function(){
         callback & callback();
        }
    }
}
var iframe = document.getElementById("iframe");
// 同域下
iframeIsLoad(iframe,function(){
    var data = iframe.contentWindow.name;
        alert(data);
});

2. 跨域下:

   以往大家运用hosts文件来绑定2个IP 来演示下跨域的情形,在hosts文件绑定如下:

   127.0.0.1  abc.example.com  和 127.0.0.1 def.example.com

   大家前日在 abc.example.com 新建贰个app.html页面 里面只怕嵌套多个 def.example.com域下的 data.html页面,代码如下:

   App.html代码如下:

XHTML

<iframe src="" id="iframe"/>

1
<iframe src="http://def.example.com/demo/tugenhua0707/storage/data.html" id="iframe"/>

如若我们照旧和上边的法子取多少的话 分明报错跨域了,今后大家是选拔window.name解决跨域下数据的传输,那么大家能够动用二个同域abc.example.com下的代办页面proxy.html来做管理,通过在def.example.com域下的data.html页面加载二个与abc.example.com同域下的proxy.html页面, 将该对象页面设置iframe的name属性,因为app.html 与 proxy.html是在同二个域下,所以咱们能够获获得。

在app.html页面 JS代码如下:

JavaScript

function iframeIsLoad(iframe,callback){ if(iframe.attach伊夫nt) { iframe.attachEvent('onload',function(){ callback & callback(); }); }else { iframe.onload = function(){ callback & callback(); } } } var iframe = document.getElementById("iframe"); var state = 0; // 跨域下 iframeIsLoad(iframe,function(){ if (state === 1) { var data = iframe.contentWindow.name; // 读取数据 alert(data); //弹出111 } else if (state === 0) { state = 1; iframe.contentWindow.location = ""; // 设置的代理文件 } });

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function iframeIsLoad(iframe,callback){
    if(iframe.attachEvent) {
        iframe.attachEvent('onload',function(){
             callback & callback();
        });
    }else {
        iframe.onload = function(){
             callback & callback();
         }
     }
}      
var iframe = document.getElementById("iframe");
var state = 0;
// 跨域下
iframeIsLoad(iframe,function(){
   if (state === 1) {
        var data = iframe.contentWindow.name;    // 读取数据
        alert(data);    //弹出111
   } else if (state === 0) {
        state = 1;
        iframe.contentWindow.location = "http://abc.example.com/demo/tugenhua0707/storage/proxy.html";    // 设置的代理文件
   }  
});

理当如此如上:大家只要name数据现已得到了的话,今后无需的话,大家得以销毁掉,清空等操作。

七:使用HTML5中postMessage 达成ajax中的POST跨域问题

浏览器帮忙程度:IE8+,firefox4+,chrome8+  opera10+

     1. 先是,要想接收从任何的窗口发过来的音讯,就不可能不对窗口对象的message事件举行监听,如下代码:

          window.addEventListener(“message”, function(){},false);

     2. 次要,须求运用window对象的postMessage方法向其余窗口发送音信,该措施定义如下所示:

         otherWindow.postMessage(message, targetOrigin);

该措施应用2个参数,第四个参数为所发送的新闻文本,但也能够是别的javascript对象,第一个参数是接到音讯的靶子窗口的url地址

(譬如:http:127.0.0.1:8080/) , 可是咱们也能够在url地址字符串中利用通配符”*”, 钦定全体的域下,不过大家依然建议采纳一定的域名下,

otherWindow为要发送窗口对象的援用。

Demo演示:

     假使未来自家在hosts文件下 ,绑定2 个域名如下:

     127.0.0.1       abc.example.com

     127.0.0.1        longen.example.com

当今只要在abc.example.com域下有叁个abc.html页面,在longen.example.com域下有def.html页面,今后本人是希望那2个不一致域名下的页面

能相互通讯,abc.html代码如下:

XHTML

<form> <p> <label for="message" style="color:red;font-size:24px;">给iframe子窗口发一个音信:</label> <input type="text" name="message" value="send" id="message" /> <input type="submit" value="submit" id="submit"/> </p> </form> <h4>目的iframe传来的消息:</h4> <p id="test">暂无音信</p> <iframe id="iframe" src="" style="display:none"></iframe>

1
2
3
4
5
6
7
8
9
10
<form>  
      <p>  
        <label for="message" style="color:red;font-size:24px;">给iframe子窗口发一个信息:</label>  
        <input type="text" name="message" value="send" id="message" />  
        <input type="submit" value="submit" id="submit"/>  
      </p>  
</form>  
<h4>目标iframe传来的信息:</h4>  
<p id="test">暂无信息</p>  
<iframe id="iframe" src="http://longen.example.com/webSocket/def.html" style="display:none"></iframe>

JS代码如下:

JavaScript

var win = document.getElementById("iframe").contentWindow; document.getElementById("submit").onclick = function(e){ e.preventDefault(); win.postMessage(document.getElementById("message").value,""); } window.addEventListener("message",function(e){ e.preventDefault(); document.getElementById("test").innerHTML = "从" + e.origin + "这里传过来的音信:n" + e.data; },false);

1
2
3
4
5
6
7
8
9
10
var win = document.getElementById("iframe").contentWindow;    
document.getElementById("submit").onclick = function(e){
    e.preventDefault();
    win.postMessage(document.getElementById("message").value,"http://longen.example.com");
}  
 
window.addEventListener("message",function(e){
     e.preventDefault();
     document.getElementById("test").innerHTML = "从" + e.origin + "那里传过来的消息:n" + e.data;
},false);

Def.html代码如下:

HTML代码:

XHTML

<form> <p> <label for="message">给父窗口abc.html发个音讯:</label> <input type="text" name="message" value="send" id="message" /> <input type="submit" /> </p> </form> <p id="test2">暂无消息。</p>

1
2
3
4
5
6
7
8
<form>  
      <p>  
        <label for="message">给父窗口abc.html发个信息:</label>  
        <input type="text" name="message" value="send" id="message" />  
        <input type="submit" />  
      </p>  
</form>  
<p id="test2">暂无信息。</p>

JS代码如下:

JavaScript

var parentwin = window.parent; window.addEventListener("message",function(e){ document.getElementById("test2").innerHTML = "从父窗口传来的域" +e.origin + ",和内容数据:" + e.data; parentwin.postMessage('HI!你给笔者发了"'+e.data+'"。',""); },false);

1
2
3
4
5
var parentwin = window.parent;
window.addEventListener("message",function(e){
       document.getElementById("test2").innerHTML = "从父窗口传来的域" +e.origin + ",和内容数据:" + e.data;  
       parentwin.postMessage('HI!你给我发了"'+e.data+'"。',"http://abc.example.com");
},false);

当本身点击abc.html页面后,能够看来效能如下,从def.html重回内容了。如下:

图片 5

笔者们需求领悟如下几条新闻:

1. 经过对window对象的message事件实行监听,能够采纳新闻。

2. 通过会见message事件的origin属性,能够获得消息的发送源。

3. 通过拜访message事件的data属性,能够赢得新闻内容。

4. 利用postMessage方法发送音信。

5. 透过会见message事件的source属性,能够博得音信发送源的窗口对象(正确的说,应该是窗口的代办对象)。

有了地点的主导知识点,大家得以延长为完毕ajax POST跨域的难点。

2. 施用postMessage 知识点消除 ajax中POST跨域难点。

 原理:原理也很简短,假诺大家的域名abc.example.com下的abc.html页面须求发ajax央求(跨域,域名字为longen.example.com)下,那么大家还是先跨页面文书档案的方式,和地方同样,大家能够前日longen.example.com下 创设二个页面,比如叫def.html. 那么我们未来照旧在 abc.html 页面嵌入一个掩饰域iframe src路线指向longen.example.com域下def,html页面。进度可能和跨文书档案类似,

 只是以前在def.html页面中 在window.onmessage 事件内写ajax央浼就可以,如下代码:

abc.example.com下的abc.html页面如下:

html代码和方面一样,上边是JS代码:

JavaScript

var win = document.getElementById("iframe").contentWindow; document.getElementById("submit").onclick = function(e){ e.preventDefault(); win.postMessage(document.getElementById("message").value,""); } window.addEventListener("message",function(e){ e.preventDefault(); alert(typeof e.data) var json = JSON.parse(e.data); console.log(json); alert(json.url) },false);

1
2
3
4
5
6
7
8
9
10
11
12
var win = document.getElementById("iframe").contentWindow;      
document.getElementById("submit").onclick = function(e){
      e.preventDefault();
      win.postMessage(document.getElementById("message").value,"http://longen.example.com/");
}    
window.addEventListener("message",function(e){
    e.preventDefault();
    alert(typeof e.data)
    var json = JSON.parse(e.data);
     console.log(json);
    alert(json.url)
},false);

def.html代码如下:

JS代码如下:

JavaScript

//获取跨域数据 window.onmessage = function(e){ $.ajax({ url: '', type:'POST', dataType:'text', //data: {msg:e.data}, success: function(res) { var parentwin = window.parent; parentwin.postMessage(res," } }); };

1
2
3
4
5
6
7
8
9
10
11
12
13
//获取跨域数据  
window.onmessage = function(e){  
     $.ajax({
          url: 'http://longen.example.com/webSocket/test.php',
          type:'POST',
          dataType:'text',
          //data: {msg:e.data},
          success: function(res) {
               var parentwin = window.parent;  
               parentwin.postMessage(res,"http://abc.example.com");//跨域发送数据  
          }
      });
};

test.php代码如下:

PHP

<?php $data=array( url =>1, name =>'2', 'xx-xx'=>"xx" ); echo json_encode($data); ?>

1
2
3
4
5
6
7
8
<?php
    $data=array(  
     url =>1,
      name =>'2',
      'xx-xx'=>"xx"
);
echo json_encode($data);
?>

如上完结形式 就足以兑现ajax post跨域了。

1 赞 8 收藏 1 评论

图片 6

8款浏览器对HTML5协理评测

2011/12/17 · HTML5 · 来源: Intel blog     · HTML5

来源:Intel blog

HTML的上一个版本诞生于1999年,从那以后,Web世界就发出了巨变,这几天天的HTML5炒得火热朝天,势头之猛犹有再一次创建Web历史变革的趋 势。HTML5仍居于全面内部,可是,今后多数浏览器已经上马有所对HTML5的支撑了,当然,各大浏览器的支付还在此起彼落,现在应当会全盘帮助HTML5的,今后本身选取了8款浏览器(中外各三款),对其协理HTML5的水平实行了测量试验,测量试验内容来自html5test网址。感兴趣的人能够去测验一下!!

理之当然各种浏览器的好坏不是仅凭这一个就可以定义的,而且即便浏览器的成效再壮大,分界面再优良,也不必然就是您心里中最佳的浏览器,因为本身以为浏览器的使用涉 及到一个习感觉常难题,用习于旧贯了当然就感觉好了,根本不会去考虑它功用是还是不是庞大。其他现实生活中大家选取浏览器,固然其功用极度强大,十二分圆满,可是并非各类人都能完全用到具备成效的。

就此,笔者做这么些测量检验是从未有过情感色彩的,只是测验哈!!!至于哪些浏览器好,哪个浏览器差,各位看官自身点评吧!!

笔者测验的8款浏览器分别是(外国)Chrome 15.0.874,IE 9.0.8112,Firefox 8.0.1,Opera 11.52

(国内)360浏览器 4.0.3.8,搜狗浏览器 3.1.0.3688,遨游浏览器v3.2.2.一千,QQ浏览器 6.8(10793)

那8款浏览器不出意外应该都以往天的新星版本!!!

率先贴上自家的硬件(QQ管家测的):

图片 7

现行反革命来造访8款浏览器的总分(顺序便是自身上边列的顺序哈,不意味着排行顺序):

1。Chrome

图片 8

2。IE 9

图片 9

3。Firefox

图片 10

4。Opera (笔者看齐外人测的是Opera12的分数为325,笔者是明天从Opera官方网址下的呀,怎会不是流行版的???)

图片 11

5。360浏览器

图片 12

6。搜狗浏览器

图片 13

7。遨游浏览器

图片 14

8。QQ浏览器

图片 15

这么看来还是Chrome大捷啊!嗯,搜狗浏览器在对HTML5的支撑上也很给力的!QQ浏览器有一些没跟上节奏啊!!!!

上边让大家详细看看那8种浏览器对HTML5的帮忙景况:

图片 16

图片 17

图片 18

图片 19

OK!大概就是如此了,还是Chrome对HTML5支撑的好一些,固然国外的浏览器都当先八分之四协理了HTML5,但国内的浏览器也不甘心啊,搜狗和旅游依旧很给力的!

HTML5还在前行完美,作者深信不疑在不久的今后,各样浏览器都会圆满支持HTML5的。让大家静观其变吧!!

赞 收藏 评论

图片 20

正文

微优化是保险品质最佳的章程,可是又无法有太过明显的优化目的,因为过度分明的靶子会耳濡目染在等级次序中做的每一个决定。以下是部分不一的模子,请依据本身舒服的一一阅读。

Cookies

Cookies 是一种在文书档案内囤积字符串数据最非凡的秘技。平常来说,cookies 会由服务端发送给顾客端,客户端存款和储蓄下来,然后在紧接着让诉求中再发回给服务端。那能够用于诸如管理顾客会话,追踪客商音信等事情。

另外,顾客端也用利用 cookies 存储数据。因此,cookies 常被用来存款和储蓄一些通用的多寡,如顾客的首推项设置。

概述

对于后台开采以来,记录日志是一种十分普及的开销习于旧贯,平常大家会利用try...catch代码块来积极抓获错误、对于每一趟接口调用,也会记录下每趟接口调用的光阴开支,以便我们监察和控制服务器接口质量,实行难点排查。

刚进集团时,在实行Node.js的接口开辟时,作者不太习贯每一趟排查难题都要通过跳板机登上服务器看日志,后来日渐习于旧贯了这种方法。

譬如:

JavaScript

/** * 获取列表数据 * @parma req, res */ exports.getList = async function (req, res) { //获取乞请参数 const openId = req.session.userinfo.openId; logger.info(`handler getList, user openId is ${openId}`); try { // 拿到列表数据 const startTime = new Date().getTime(); let res = await List瑟维斯.getListFromDB(openId); logger.info(`handler getList, ListService.getListFromDB cost time ${new Date().getTime() - startDate}`); // 对数码管理,再次来到给前端 // ... } catch(error) { logger.error(`handler getList is error, ${JSON.stringify(error)}`); } };

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
* 获取列表数据
* @parma req, res
*/
exports.getList = async function (req, res) {
    //获取请求参数
    const openId = req.session.userinfo.openId;
    logger.info(`handler getList, user openId is ${openId}`);
 
    try {
        // 拿到列表数据
        const startTime = new Date().getTime();
        let res = await ListService.getListFromDB(openId);
        logger.info(`handler getList, ListService.getListFromDB cost time ${new Date().getTime() - startDate}`);
        // 对数据处理,返回给前端
        // ...
    } catch(error) {
        logger.error(`handler getList is error, ${JSON.stringify(error)}`);
    }
};

以下代码平时会现出在用Node.js的接口中,在接口中会总括查询DB所耗费时间间、亦也许总计RPC劳务调用所耗费时间间,以便监测品质瓶颈,对质量做优化;又或许对格外使用try ... catch义不容辞抓获,以便随时对难点开展回想、还原难题的气象,进行bug的修复。

而对在此以前端来讲吧?能够看之下的风貌。

新近在开展三个供给开辟时,临时发现webgl渲染影象失利的动静,大概说影象会产出剖析失利的气象,大家或者平素不知晓哪张影象会分析或渲染败北;又或如近来开支的其它二个须要,我们会做贰个关于webgl渲染时间的优化和影象预加载的急需,假若贫乏品质监察和控制,该怎么计算所做的渲染优化和影像预加载优化的优化比例,如何证明自身所做的事体具备价值啊?大概是由此测验同学的黑盒测量试验,对优化前后的年华开展录屏,深入分析从进来页面到印象渲染实现到底经过了有一点帧图像。那样的数码,大概既不标准、又相比较片面,虚构测量检验同学并不是真正的顾客,也无力回天苏醒真实的客商他们所处的互联网境况。回过头来发掘,大家的种类,固然在服务端层面做好了日记和个性总括,但在前端对十分的监察和质量的计算。对于前端的属性与充足申报的方向探求是有供给的。

请打算好然后定下目的!

Cookies 的 基本CRUD 操作

经过上面包车型大巴语法,大家能够成立,读取,更新和删除 cookies:

JavaScript

// Create document.cookie = "user_name=Ire Aderinokun"; document.cookie = "user_age=25;max-age=31536000;secure"; // Read (All) console.log( document.cookie ); // Update document.cookie = "user_age=24;max-age=31536000;secure"; // Delete document.cookie = "user_name=Ire Aderinokun;expires=Thu, 01 Jan 1970 00:00:01 GMT";

1
2
3
4
5
6
7
8
9
10
11
12
// Create
document.cookie = "user_name=Ire Aderinokun";  
document.cookie = "user_age=25;max-age=31536000;secure";
 
// Read (All)
console.log( document.cookie );
 
// Update
document.cookie = "user_age=24;max-age=31536000;secure";
 
// Delete
document.cookie = "user_name=Ire Aderinokun;expires=Thu, 01 Jan 1970 00:00:01 GMT";

丰盛捕获

对在此在此之前端来讲,我们需求的要命捕获无非为以下两种:

  • 接口调用情状;
  • 页面逻辑是还是不是错误,比方,客商走入页面后页面突显白屏;

对于接口调用景况,在前面二个平时供给反映顾客端相关参数,比如:客商OS与浏览器版本、伏乞参数(如页面ID);而对此页面逻辑是不是错误难点,平日除了客户OS与浏览器版本外,供给的是报错的旅社音讯及实际报错地方。

1. 比你最强的竞争对手快33.33%

依靠二个激情学研究,你的网址起码在速度上比人家快四分之一,能力让顾客觉获得您的网址比别人的更加快。那些速度说的不是任何页面的加载时间,而是起首加载渲染的时光,第二回有效渲染时间(比方页面供给加载重要内容的时间),或然交互时间(指的是页面可能采用中任重先生而道远的页面加载成功,并主备好与客商进行相互的年华)。

在Moto G(或中端三星(Samsung)道具)和Nexus 4(相比较主流的设施)上衡量开头渲染时间(用WebPagetest)以及首页有效渲染时间(用Lighthouse),最棒是在一个怒放的实验室中,使用标准的3G,4G和Wi-Fi链接。

图片 21
Lighthouse,叁个Google开辟的新的天性核实工具

你能够透过你的剖析报告看看您的客户处于哪个阶段,选拔在那之中前十分之七的顾客体验来做测量检验。接着访谈数据,建二个表格,筛去十分四的数目并预设一个目的(如:品质预算)。未来你能够将上述五个值举行相比检查实验。假若你一向维持着你的靶子并且经过一点一点改造脚本去加快交互时间,那么上述措施正是理当如此有效的。

图片 22
由Brad Frost成立的性质拆解分析

和你的同事共享这份清单。首先要保管组织中的每一种人都熟悉那份清单。项目中每三个垄断(monopoly)都会耳熏目染属性,借使前端程序猿们都在积极的参与项目概念,UX以及视觉设计的决定,那将会给整个项目推动巨大收益。地图设计的调控违反了品质观念,所以她在那份清单内的逐个有待思考。

Cookies 的优点

  • 能用于和服务端通讯
  • 当 cookie 快要自动过期时,大家得以另行设置实际不是去除

丰裕捕获方法

2. 反应时间为100纳秒,帧数是每秒60帧

RAIL品质模型会为您提供一个不错的目的,既尽最大的全力在顾客开头操作后的100皮秒内提供报告。为了完结那些指标,页面需求扬弃权限,并将权力在50皮秒内交回给主线程。对于像动画片一样的高压点,最佳的不二秘籍便是什么样都不做,因为您恒久不能直达最小绝对值。
同理,动画的每一帧都需求在16微秒内到位,那样本事担保每秒60帧(一秒/60=16.6阿秒),倘诺得以的话最佳能(CANON)在10皮秒内成功。因为浏览器供给料定的年月去在显示器上渲染新的帧,並且你的代码需求在16.6阿秒内达成实行。要在意,上述目的应用于衡量项指标周转品质,而非加载品质。

Cookies 的缺点

  • 充实了文书档案传输的载荷
  • 只好存款和储蓄少些的多寡
  • 只能存款和储蓄字符串
  • 潜在的 平安主题素材
  • 自从有 Web Storage API (Local and Session Storage),cookies 就不再被引入用于存款和储蓄数据了

大局捕获

能够经过全局监听分外来捕获,通过window.onerror或者addEventListener,看之下例子:

JavaScript

window.onerror = function(errorMessage, scriptU福睿斯I, lineNo, columnNo, error) { console.log('errorMessage: ' + errorMessage); // 至极音信console.log('scriptU奇骏I: ' + scriptU昂科雷I); // 分外文件路径console.log('lineNo: ' + lineNo); // 格外行号 console.log('columnNo: ' + columnNo); // 相当列号 console.log('error: ' + error); // 格外客栈音信// ... // 极度上报 }; throw new Error('那是二个不当');

1
2
3
4
5
6
7
8
9
10
window.onerror = function(errorMessage, scriptURI, lineNo, columnNo, error) {
  console.log('errorMessage: ' + errorMessage); // 异常信息
  console.log('scriptURI: ' + scriptURI); // 异常文件路径
  console.log('lineNo: ' + lineNo); // 异常行号
  console.log('columnNo: ' + columnNo); // 异常列号
  console.log('error: ' + error); // 异常堆栈信息
  // ...
  // 异常上报
};
throw new Error('这是一个错误');

图片 23

通过window.onerror事件,能够获得切实的丰盛消息、非常文件的U昂CoraL、至极的行号与列号及那些的库房消息,再捕获相当后,统一举报至大家的日志服务器。

亦或是,通过window.addEventListener方法来张开极度申报,道理同理:

JavaScript

window.addEventListener('error', function() { console.log(error); // ... // 格外上报 }); throw new Error('那是多少个谬误');

1
2
3
4
5
6
window.addEventListener('error', function() {
  console.log(error);
  // ...
  // 异常上报
});
throw new Error('这是一个错误');

图片 24

3. 第二回有效渲染时间要低于1.25秒,速度指数要低于1000

不畏这几个指标落实起来出色难堪,你的最后指标也应当是让初叶渲染时间低于1秒且速度指数小于一千(在网速快的地点)。对于第一次有效渲染时间,上限最棒是1250飞秒。对于移动端,3G下活动道具第三遍渲染时间低于3秒都以足以承受的。稍微高一点也没涉及,但千万别高太多。

浏览器扶助

怀有主流浏览器均援助 Cookies.

try… catch

使用try... catch就算能够较好地扩充极度捕获,不至于使得页面由于一处错误挂掉,但try ... catch破获情势显示过分臃肿,比很多代码应用try ... catch包装,影响代码可读性。

概念你所急需的条件

Local Storage

Local Storage 是 Web Storage API 的一种档案的次序,能在浏览器端存款和储蓄键值对数码。Local Storage 因提供了越来越直观和安全的API来积攒轻松的数目,被视为取代 Cookies 的一种缓和方案。

从本事上说,固然 Local Storage 只可以存款和储蓄字符串,可是它也是足以积攒字符串化的JSON数据。那就表示,Local Storage 能比 Cookies 存款和储蓄更复杂的数量。

科学普及难题

4. 精选和装置你的成本条件

不要过多的关怀当下最盛行的工具,百折不挠选择切合自己支付条件的工具,例如Grunt、Gulp、Webpack、PostCSS,恐怕组合起来的工具。只要那几个工具运营的快慢够快,况且从不给你的护卫带来太大主题材料,那就够了。

Local Storage 的 基本CRUD 操作

经过上边包车型地铁语法,大家得以创立,读取,更新和删除 Local Storage:

JavaScript

// Create const user = { name: 'Ire Aderinokun', age: 25 } localStorage.setItem('user', JSON.stringify(user)); // Read (Single) console.log( JSON.parse(localStorage.getItem('user')) ) // Update const updatedUser = { name: 'Ire Aderinokun', age: 24 } localStorage.setItem('user', JSON.stringify(updatedUser)); // Delete localStorage.removeItem('user');

1
2
3
4
5
6
7
8
9
10
11
12
13
// Create
const user = { name: 'Ire Aderinokun', age: 25 }  
localStorage.setItem('user', JSON.stringify(user));
 
// Read (Single)
console.log( JSON.parse(localStorage.getItem('user')) )
 
// Update
const updatedUser = { name: 'Ire Aderinokun', age: 24 }  
localStorage.setItem('user', JSON.stringify(updatedUser));
 
// Delete
localStorage.removeItem('user');

跨域脚本不可能正确捕获极度

普普通通情形下,我们会把静态能源,如JavaScript本子放到特意的静态能源服务器,亦恐怕CDN,看以下例子:

<!DOCTYPE html> <html> <head> <title></title> </head> <body> <script type="text/javascript"> // 在index.html window.onerror = function(errorMessage, scriptU库罗德I, lineNo, columnNo, error) { console.log('errorMessage: ' + errorMessage); // 十分音讯console.log('scriptUKugaI: ' + scriptU奔驰M级I); // 非常文件路径console.log('lineNo: ' + lineNo); // 非常行号 console.log('columnNo: ' + columnNo); // 非凡列号 console.log('error: ' + error); // 格外宾馆新闻// ... // 分外上报 }; </script> <script src="./error.js"></script> </body> </html>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<!DOCTYPE html>
<html>
<head>
  <title></title>
</head>
<body>
  <script type="text/javascript">
    // 在index.html
    window.onerror = function(errorMessage, scriptURI, lineNo, columnNo, error) {
      console.log('errorMessage: ' + errorMessage); // 异常信息
      console.log('scriptURI: ' + scriptURI); // 异常文件路径
      console.log('lineNo: ' + lineNo); // 异常行号
      console.log('columnNo: ' + columnNo); // 异常列号
      console.log('error: ' + error); // 异常堆栈信息
      // ...
      // 异常上报
    };
 
  </script>
  <script src="./error.js"></script>
</body>
</html>

JavaScript

// error.js throw new Error('那是多个不当');

1
2
// error.js
throw new Error('这是一个错误');

图片 25

结果彰显,跨域之后window.onerror数码存储能力大概浏览,数据交互与当地存储。一向捕获不到精确的不得了音讯,而是统一再次回到二个Script error

缓和方案:对script标签增添八个crossorigin=”anonymous”,而且服务器增加Access-Control-Allow-Origin

<script src="" crossorigin="anonymous"></script>

1
<script src="http://cdn.xxx.com/index.js" crossorigin="anonymous"></script>

5. 渐进巩固(progressive enhancement)

在创设前端结构的时候,应始终将渐进巩固作为你的点拨标准。首先设计还要构建大旨体验,随后再完美那三个为高品质浏览器设计的高档次和等第特性的相关经验,制造弹性体验。如若你的网页能够在选取低速互连网、老旧显示屏的一点也不快的管理器上运转高效,那么在光导纤维高配计算机上它只会运作的越来越快。

Local Storage 的优点

相比于Cookies:

  • 其提供了越来越直观地接口来积存数据
  • 更安全
  • 能累积更比相当多据

sourceMap

平时在生产条件下的代码是因而webpack包装后减去混淆的代码,所以我们恐怕会遇上这样的主题材料,如图所示:

图片 26

大家开采具备的报错的代码行数都在率先行了,为何吧?那是因为在生育条件下,大家的代码被压缩成了一站式:

JavaScript

!function(e){var n={};function r(o){if(n[o])return n[o].exports;var t=n[o]={i:o,l:!1,exports:{}};return e[o].call(t.exports,t,t.exports,r),t.l=!0,t.exports}r.m=e,r.c=n,r.d=function(e,n,o){r.o(e,n)||Object.defineProperty(e,n,{enumerable:!0,get:o})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,n){if(1&n&&(e=r(e)),8&n)return e;if(4&n&&"object"==typeof e&&e&&e.__esModule)return e;var o=Object.create(null);if(r.r(o),Object.defineProperty(o,"default",{enumerable:!0,value:e}),2&n&&"string"!=typeof e)for(var t in e)r.d(o,t,function(n){return e[n]}.bind(null,t));return o},r.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(n,"a",n),n},r.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},r.p="",r(r.s=0)}([function(e,n){throw window.onerror=function(e,n,r,o,t){console.log("errorMessage: "+e),console.log("scriptURI: "+n),console.log("lineNo: "+r),console.log("columnNo: "+o),console.log("error: "+t);var l={errorMessage:e||null,scriptURI:n||null,lineNo:r||null,columnNo:o||null,stack:t&&t.stack?t.stack:null};if(XMLHttpRequest){var u=new XMLHttpRequest;u.open("post","/middleware/errorMsg",!0),u.setRequestHeader("Content-Type","application/json"),u.send(JSON.stringify(l))}},new Error("这是壹个不当")}]);

1
!function(e){var n={};function r(o){if(n[o])return n[o].exports;var t=n[o]={i:o,l:!1,exports:{}};return e[o].call(t.exports,t,t.exports,r),t.l=!0,t.exports}r.m=e,r.c=n,r.d=function(e,n,o){r.o(e,n)||Object.defineProperty(e,n,{enumerable:!0,get:o})},r.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},r.t=function(e,n){if(1&n&&(e=r(e)),8&n)return e;if(4&n&&"object"==typeof e&&e&&e.__esModule)return e;var o=Object.create(null);if(r.r(o),Object.defineProperty(o,"default",{enumerable:!0,value:e}),2&n&&"string"!=typeof e)for(var t in e)r.d(o,t,function(n){return e[n]}.bind(null,t));return o},r.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return r.d(n,"a",n),n},r.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},r.p="",r(r.s=0)}([function(e,n){throw window.onerror=function(e,n,r,o,t){console.log("errorMessage: "+e),console.log("scriptURI: "+n),console.log("lineNo: "+r),console.log("columnNo: "+o),console.log("error: "+t);var l={errorMessage:e||null,scriptURI:n||null,lineNo:r||null,columnNo:o||null,stack:t&&t.stack?t.stack:null};if(XMLHttpRequest){var u=new XMLHttpRequest;u.open("post","/middleware/errorMsg",!0),u.setRequestHeader("Content-Type","application/json"),u.send(JSON.stringify(l))}},new Error("这是一个错误")}]);

在本人的支付进度中也跨越过那几个难题,作者在支付八个成效组件库的时候,使用npm link了本人的零部件库,可是出于组件库被npm link后是包裹后的生育条件下的代码,全部的报错都稳定到了第一行。

化解办法是翻开webpacksource-map,大家选拔webpack装进后的更换的一份.map的台本文件就足以让浏览器对错误地点实行追踪了。此处能够参照webpack document。

事实上便是webpack.config.js中加上一行devtool: 'source-map',如下所示,为示范的webpack.config.js

JavaScript

var path = require('path'); module.exports = { devtool: 'source-map', mode: 'development', entry: './client/index.js', output: { filename: 'bundle.js', path: path.resolve(__dirname, 'client') } }

1
2
3
4
5
6
7
8
9
10
var path = require('path');
module.exports = {
    devtool: 'source-map',
    mode: 'development',
    entry: './client/index.js',
    output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'client')
    }
}

webpack包裹后变化对应的source-map,那样浏览器即可牢固到现实错误的职责:

图片 27

开启source-map的症结是包容性,近期独有Chrome浏览器和Firefox浏览器才对source-map扶助。可是大家对这一类意况也可以有消除办法。能够接纳引进npm库来扶助source-map,能够参见mozilla/source-map。这个npm库既可以够运营在客户端也能够运作在服务端,然而更为推荐的是在服务端使用Node.js对摄取到的日记音讯时使用source-map分析,避防止源代码的走漏导致危机,如下代码所示:

JavaScript

const express = require('express'); const fs = require('fs'); const router = express.Router(); const sourceMap = require('source-map'); const path = require('path'); const resolve = file => path.resolve(__dirname, file); // 定义post接口 router.get('/error/', async function(req, res) { // 获取前端传过来的报错对象 let error = JSON.parse(req.query.error); let url = error.scriptU奥迪Q5I; // 压缩文件路线if (url) { let fileUrl = url.slice(url.indexOf('client/')) + '.map'; // map文件路线 // 分析sourceMap let consumer = await new sourceMap.SourceMapConsumer(fs.readFileSync(resolve('../' + fileUrl), 'utf8')); // 再次来到三个promise对象 // 分析原始报错数据 let result = consumer.originalPositionFor({ line: error.lineNo, // 压缩后的行号 column: error.columnNo // 压缩后的列号 }); console.log(result); } }); module.exports = router;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
const express = require('express');
const fs = require('fs');
const router = express.Router();
const sourceMap = require('source-map');
const path = require('path');
const resolve = file => path.resolve(__dirname, file);
// 定义post接口
router.get('/error/', async function(req, res) {
    // 获取前端传过来的报错对象
    let error = JSON.parse(req.query.error);
    let url = error.scriptURI; // 压缩文件路径
    if (url) {
        let fileUrl = url.slice(url.indexOf('client/')) + '.map'; // map文件路径
        // 解析sourceMap
        let consumer = await new sourceMap.SourceMapConsumer(fs.readFileSync(resolve('../' + fileUrl), 'utf8')); // 返回一个promise对象
        // 解析原始报错数据
        let result = consumer.originalPositionFor({
            line: error.lineNo, // 压缩后的行号
            column: error.columnNo // 压缩后的列号
        });
        console.log(result);
    }
});
module.exports = router;

正如图所示,大家早就能够看看,在服务端已经成功深入分析出了切实可行错误的行号、列号,大家能够透过日记的办法开展记录,达到了前面贰个至极监察和控制的目标。

图片 28

本文由云顶娱乐集团发布于云顶娱乐集团,转载请注明出处:数码存储能力大概浏览,数据交互与当地存储

关键词: