• JavaScript高级程序设计(第三版)学习笔记20、21、23章


    第20章,JSON

    JSON(JavaScript Object Notation,JavaScript对象表示法),是JavaScript的一个严格的子集。
    JSON可表示一下三种类型值:
    简单值:字符串,数值,布尔值,null,不支持js特殊值:undefined
    对象:一组无序的键值对
    数组:一组有序的值的列表
    不支持变量,函数或对象实例
    注:JSON的字符串必须使用双引号,这是与JavaScript字符串最大的区别

    对象

    {
         "name":"Nicholas",
         "age":20
    }
    注:JSON中的对象要求给属性加引号
    与JavaScript不同,没有声明变量,末尾不用分号
    对象嵌入:
    {
        "name":"Nicholas",
        "age":19,
        "school":{
            "name":"school",
            "location":"location"
        }
    }

    数组

    采用js的数组字面量形式:
    [21,"hi",true]
    注:JSON数组也没有分号和变量
    数组嵌入
    [
        {
            "title":"array",
            "author":"author"
        },
        [
            "title":"book",
            "author":{
                "nameOne",
                "nameTwo"
            }
        ]
    ]

    JSON对象

    早期的JSON解析器基本上使用的是js的eval函数。ECMAScript5定义了全局对象JSON,支持的浏览器:IE8+,Firefox3.5+,Safari4+,Chrome,Opera10.5+。
    JSON对象的两个方法:stringify,parse。最简单情况,分别用于把js对象序列化为JSON字符串和把JSON字符串解析成原生js值
    var book = {
        title:"title",
        author:[
            "Nicholas C. Zakas"
        ],
        edition:3,
        year:2011
    };
    var jsonText = JSON.stringify(book);
    alert(jsonText);          //{"title":"title","author":["Nicholas C. Zakas"],"edition":3,"year":2011}
    注:默认情况下JSON.stringify输出的JSON字符串不包含任何空格字符或缩进。
    序列化时所有函数和原型成员都会被忽略,值为undefined的属性也会被跳过。
    JSON.parse过程相反,传递的字符串不是有效JSON,会抛出错误

    序列化选项

    JSON.stringify还可以接收另外两个参数:1、过滤器,可以是数组,也可以是函数。2、选项,表示是否在JSON字符串保留缩进

    1、过滤结果

    若过滤器是数组,则JSON.stringify结果将只包含数组列出的元素
    var book = {
        title:"title",
        author:[
            "Nicholas C. Zakas"
        ],
        edition:3,
        year:2011
    };
    var jsonText = JSON.stringify(book,["title","edition"]);     //{"title":"title","edition":3}

    如果是函数,则又有不同

    var jsonText = JSON.stringify(book,function(key,value){
        switch(key){
            case "author":
                return value.join(",");
               
            case "year":
                return 5000;
    
            case "edition":
                return undefined;
            default:
                return value;
        }
    });                                   //{"title":"title","author":"Nicholas C. Zakas","year":5000}

    2、字符串缩进

    JSON.stringify第三个参数用于控制缩进和空白符,若是数值,表示每个级别的缩进空格数
    var jsonText = JSON.stringify(book,null,4);
    //结果:
    {
        "title": "title",
        "author": [
            "Nicholas C. Zakas"
        ],
        "edition": 3,
        "year": 2011
    }
    注:最大缩进空格数为10,大于10的数值全部转为10
    若缩进参数是字符串,则将被用于缩进字符
    {
    - -"title": "title",
    - -"author": [
    - - - -"Nicholas C. Zakas"
    - -],
    - -"edition": 3,
    - -"year": 2011
    }
    注:最大缩进字符数不能超过10,超过的将只显示前10个字符

    3、toJSON方法

    toJSON方法可以作为函数过滤器的补充,理解序列化顺序:
    1、如果存在toJSON方法,而且能通过它取得有效值,调用该方法,否则返回对象本身
    2、若提供了第二个参数,应用这个函数过滤器,传入函数过滤器的值是第一步返回值
    3、对第二步返回值进行序列化
    4、若提供了第三个参数,执行相应格式化

    解析选项

    JSON.parse也接收另一个参数,是一个函数,将在每个键值对上调用。若返回结果为undefined,表示删除该值,返回其他值,则将该值插入到结果。
    var book = {
        title:"title",
        author:[
            "Nicholas C. Zakas"
        ],
        edition:3,
        year:2011,
        releaseDate:new Date(2011,11,1)
    };
    
    var jsonText = JSON.stringify(book);
    var bookCopy = JSON.parse(jsonText,function(key,value){
        if(key == "releaseDate"){
            return new Date(value);
        }else{
            return value;
        }
    });
    
    alert(bookCopy.releaseDate.getFullYear());               //2011

    第21章,Ajax和Comet

    Ajax核心是XMLHttpRequest对象,能够以异步的方式从服务器获取更多信息,意味着用户单击后,可以不必刷新页面也能取得数据

    XMLHttpRequest

    IE7+,Firefox,Opera,Chrome,Safari都支持原生的XHR对象,创建对象:
    var xhr = new XMLHttpRequest();
    浏览器兼容
    function createXHR(){
        if(typeof XMLHttpRequest != "undefined"){
            return new XMLHttpRequest;
        }else if(typeof ActiveXObject != "undefined"){
            if(typeof arguments.callee.activeXString != "string"){
                var versions = ["MSXML2.XMLHttp.6.0","MSXML2.XMLHttp.3.0","MSXML2.XMLHttp"],i,len;
                for(i=0,len=versions.length;i < len;i++){
                    try{
                        new ActiveXObject(versions[i]);
                        arguments.callee.activeXString = versions[i];
                        break;
                    }catch(ex){
                        //跳过
                    }
                }
            }
            return new ActiveXObject(arguments.callee.activeXString);
        }else{
            throw new Error("No XHR Object available");
        }
    }
    //使用示例
    var xhr = createXHR();

    XHR用法

    第一个方法:open,接收3个参数:
    1、要发送的请求的类型(“get”,“post”)
    2、请求的URL
    3、表示是否异步发送请求的布尔值
    xhr.open("get","example.php",false);
    说明:1、url相对于执行代码的当前页面(也可以使用绝对路径),2、并不会真正发送请求,而是启动一个请求以备发送
    使用send方法发送:
    xhr.send(null);
    send接受一个参数:作为请求主体发送的数据,不需要则要传入null。响应的数据会被填充到XHR对象的属性。属性简介:
    responseText:作为响应主体被返回的文本
    responseXML:响应内容类型若是"text/xml"或"application/xml",将保存包含着响应数据的XML DOM文档
    status:响应的HTTP状态
    statusText:HTTP状态说明
    接到响应后,首先检查status属性,可以将HTTP状态码200,作为成功的标志,状态码304表示请求资源并没有修改,可以直接使用浏览器中缓存的版本。
    xhr.open("get","example.php",false);               //同步请求
    xhr.send(null);
    
    if((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){
        alert(xhr.resopnseText);
    }else{
        alert("Request was unsuccessful: "+xhr.status);
    }
    异步请求,检查readyState属性,表示请求/响应过程的当前活动阶段,取值:
    0:未初始化,尚未调用open
    1:启动,已调用open,未调用send
    2:发送,已调用send,未收到响应
    3:接收,已接收部分数据
    4:完成,接收全部数据,已经可以在客户端使用了
    必须在调用open之前指定onreadystatechange事件处理程序才能确保跨浏览器兼容性:
    var xhr = createXHR();
    xhr.onreadystatechange = function(){                         //DOM0级方法,不是所有浏览器都支持DOM2级方法
        if(xhr.readyState == 4){
            if((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){
                alert(xhr.resopnseText);
            }else{
                alert("Request was unsuccessful: "+xhr.status);
            }
        }
    };
    xhr.open("get","example.php",true);                         //异步请求
    xhr.send(null);

    在接收到响应之前还可以调用abort方法来取消异步请求:

    xhr.abort();

    HTTP头部信息

    默认情况下,发送XHR请求的同时,还会发送下列头部信息
    Accept:浏览器能够处理的内容类型
    Accept-Charset:浏览器能够显示的字符集
    Accept-Encoding:浏览器能够处理的压缩编码
    Accept-Language:浏览器当前设置语言
    Connection:浏览器与服务器之间的链接类型
    Cookie:当前页面设置的热河Cookie
    Host:发出请求的页面所在的域
    Referer:发出请求的页面的URI。注:HTTP规范把这个头部字段拼错了,应该是referrer
    User-Agent:浏览器的用户代理字符串
    以上列出的基本上是所有浏览器都会发送的。可以通过setRequestHeader方法设置自定义的请求头部信息。接收两个参数:头部字段名称,头部字段值,要成功发送请求头部信息,必须在调用open方法之后,调用send方法之前调用setRequestHeader
    var xhr = createXHR();
    xhr.onreadystatechange = function(){
        if(xhr.readyState == 4){
            if((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){
                alert(xhr.resopnseText);
            }else{
                alert("Request was unsuccessful: "+xhr.status);
            }
        }
    };
    xhr.open("get","example.php",true);
    xhr.setRequestHeader("MyHeader","MyValue");
    xhr.send(null);
    调用XHR对象的getRequestHeader方法并传入头部字段名称,可以取得相应头部信息,调用getAllResponseHeaders()方法则可以获得一个包含所有头部信息的长字符串。

    GET请求

    使用GET请求经常发生的一个错误,就是查询字符串的格式有问题,查询字符串的每个参数的名称和值都必须使用encodeURIComponent()(第五章提到的通用资源标识符编码)进行编码,然后才能放到URL末尾,而且所有键-值对都必须使用和号(&)分隔。

    POST请求

    通常用于向服务器发送应该保存的数据,应该把数据作为请求的主体提交,可以包含非常多的数据,且格式不限。
    若需要将页面中的表单数据进行序列化,然后通过XHR放到服务器,则可以使用14章的serialize函数来创建字符串:
    function submitData(){
        var xhr = createXHR();
        xhr.onreadystatechange = function(){
            if(xhr.readyState == 4){
                if((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){
                    alert(xhr.resopnseText);
                }else{
                    alert("Request was unsuccessful: "+xhr.status);
                }
            }
        };
    
        xhr.open("post","postExample.php",true);
        xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
        var form = document.getElementById("user-info");
        xhr.send(serialize(form));
    }

    示例php文件:

    <?php
        header("Content-Type:text/plain");
        echo <<<EOF
        Name:{$_POST['user-name']}
        Email:{$_POST['user-email']}
        EOF;
    ?>
    如不设置Content-Type头部信息,要访问同样信息必须借助$HTTP_RAW_POST_DATA
    XMLHttpRequest2级
    定义FormData类型,为序列化表单以及创建与表单格式相同的数据(用于通过XHR传输)提供了便利。
    方法1、
    var data = new FormData();
    data.append("name","Nicholas");          //接收两个参数:键,值

    方法2、

    var data = new FormData(document.forms[0]);     //直接使用表单元素

    方法3、

    var form = document.getElementById("user-info");
    xhr.send(new FormData(form));
    支持的浏览器:Firefox4+,Safari5+,Chrome,Android3+,WebKit

    超时设定

    IE8为XHR添加了timeout属性,表示请求等待多少毫秒之后终止,在写作JavaScript高级程序设计第三版时,IE8+仍然是唯一支持超时设定的浏览器

    overrideMimeType方法

    Firefox最早引入overrideMimeType方法,用于重写XHR响应的MIME类型。因为返回响应的MIME类型决定了XHR如何处理它。
    支持的浏览器Firefox,Safari4+,Opera10.5,Chrome

    进度事件

    Progress Events规范是W3C的一个工作草案,定义了与客户端服务器通信有关的事件,最早针对XHR操作,目前也被其他API借鉴,6个进度事件:
    loadstart:接收到响应数据第一个字节触发
    progress:接收响应期间持续不断地触发
    error:请求错误触发
    abort:调用abort方法触发
    load:接收到完整的响应数据触发
    loadend:通信完成或触发error,abort,load事件后触发

    跨源资源共享

    IE对CORS的支持

    CORS(Cross-Origin Resource Sharing,跨源资源共享)是W3C的一个工作草案
    IE8中引入了XDR(XDomainRequest)类型,与XHR类似,但能实现安全可靠的跨域通信。与XHR不同:
    1、cookie不会随请求发送,也不会随请求返回
    2、只能设置头部信息中的Content-Type
    3、不能访问响应头部信息
    4、只支持GET和POST请求
    使用方法,也是创建一个XDomainRequest实例,调用open,调用send,open方法只接受两个参数,请求类型,URL。所有请求都是异步。

    其他浏览器对CORS的支持

    Firefox3.5+,Safari4+,Chrome,ios版Safari,Android平台中的WebKit都通过XHR对象实现了对CORS的原生支持。
    限制:
    1、不能使用setRequestHeader
    2、不能发送和接收cookie
    3、调用getAllResponseHeaders会返回空字符串

    其他跨域技术

    图像ping

    JSONP

    Comet

    Comet一种更高级的Ajax技术。Ajax是从页面向服务器请求数据的技术,Comet是服务器向页面推送数据的技术。能够让信息近乎实时的被推送到页面上。

    服务器发送事件

    SSE(Server-Sent Events,服务器发送事件)是围绕只读Comet交互推出的API或者模式

    Web Socket

    使用标准的HTTP服务器无法实现Web Socket,只有支持这种协议的专门服务器才能工作。
    支持浏览器:Firefox6+,Safari5+,Chrome,ios4+版Safari

    1、Web Socket API

    要创建Web Socket,先实例一个WebSocket对象并传入要连接的URL
    var socket = new WebSocket("ws://www.example.com/server.php");
    注:必须传入绝对URL
    表示当前状态的readyState属性:
    WebSocket.OPENING(0):正在建立连接
    WebSocket.OPEN(1):已建立连接
    WebSocket.CLOSING(1):正在关闭连接
    WebSocket.CLOSE(3):已关闭
    关闭Web Socket连接:
    socket.close();

    2、发送和接收数据

    socket.send("hello world");          //任意字符串
    只能发送纯文本数据,发杂结构的数据要经过序列化。

    3、其他事件

    open:成功建立连接触发
    error:发生错误触发,连接不能持续
    close:连接关闭触发

    第23章,离线应用与客户端存储

    离线检测

    H5定义了navigator.onLine属性,true表示能上网。
    H5还定义了两个事件:online(离线变在线触发),offline(在线变离线触发),在window对象上触发。

    应用缓存

    要在缓存中保存数据,可以使用描述文件

    数据存储

    HTTP Cookie,通常叫做cookie。

    1、限制

    在性质上是绑定在特定域名下的。

    2、cookie的构成

    cookie由浏览器保存的以下几块信息构成
    名称:唯一确定cookie的名称,不缺分大小写,实践中最好看成区分大小写。
    值:储存在cookie中的字符串值,必须被URI编码
    域:对于哪个域有效
    路径:对于域中的那个路径,应该向服务器发送cookie
    失效时间:cookie应该被删除的时间
    安全标志:指定后,cookie只有在使用ssl连接时才发送到服务器

    3、js中的cookie

    在js中处理cookie有些复杂,因为众所周知的蹩脚的接口,即BOM的document.cookie属性
    基本的cookie操作:读,写,删,在CookieUtil对象表示:
    var socket = new WebSocket("ws://www.example.com/server.php");
    var CookieUtil = {
        get:function(name){
            var cookieName = encodeURIComponent(name) + "=" ,
                cookieStart = document.cookie.indexOf(cookieName),
                cookieValue = null;
    
            if(cookieStart > -1){
                var cookieEnd = document.cookie.indexOf(";",cookieStart);
                if(cookieEnd == -1){
                    cookieEnd = document.cookie.length;
                }
                cookieValue = decodeURIComponent(document.cookie.substring(cookieStart+cookieName.length,cookieEnd));
            }
    
            return cookieValue;
        },
        set:function(name,value,expires,path,domain,secure){
            var cookieText = encodeURIComponent(name) + "=" + encodeURIComponent(value);
    
            if(expires instanceof Date){
                cookieText += "; expires=" + expires.toGMTString();
            }
            if(path){
                cookieText += "; path=" + path;
            }
            if(domain){
                cookieText =+ "; domain=" + domain;
            }
            if(secure){
                cookieText += "; secure=" + secure;
            }
            document.cookie = cookieText;
        },
        unset:function(name,path,domain,secure){
            this.set(name,"",new Date(0),path,domain,secure);
        }
    };

    使用示例:

    //设置cookie
    CookieUtil.set("name","Nicholas");
    CookieUtil.set("book","Professional JavaScript");
    
    //读取
    alert(CookieUtil.get("name"));  //"Nicholas"
    alert(CookieUtil.get("book"));  //Professional JavaScript
    
    //删除
    CookieUtil.unset("name");
    CookieUtil.unset("book");
    
    //设置cookie,包括它的路径、域、失效日期
    CookieUtil.set("name","Nicholas","/books/projs","www.wrox.com",new Date("January 1,2010"));
    
    //删除刚设置的cookie
    CookieUtil.unset("name","/books/projs","www.wrox.com");
    
    //设置安全cookie
    CookieUtil.set("name","Nicholas",null,null,null,true);

    4、子cookie

    为了绕开浏览器的单域名下cookie数量限制

    5、关于cookie的思考

    尽量少存储信息,不存敏感信息

    Web存储机制

    Web Storage目的是克服由cookie带来的一些限制。主要目的:
    1、提供一种cookie之外存储会话数据的途径;
    2、提供一种存储大量可以跨会话存在的数据的机制
    Web Storage包含了两种对象定义:sessionStorage,globalStorage,支持浏览器:IE8+,Firefox3.5+,Chrome4+,Opera10.5+

    1、Storage类型

    注:Storage类型只能存字符串,不是字符串的会被转换成字符串

    2、sessionStorage对象

    数据值保存到浏览器关闭

    3、globalStorage对象

    目的:跨越会话存储数据,有特定的访问限制。
    数据保留到js删除或用户清除浏览器缓存

    4、localStorage对象

    要访问同一个localStorage对象,页面必须来自同一域名(子域名无效),使用同一种协议,在同一个端口
    数据保留到js删除或用户清除浏览器缓存

    5、storage事件

    对Storage对象的任何修改,都会在文档上触发storage事件

    IndexedDB

    在浏览器中保存结构化数据的一种数据库
    操作完全异步
    1、数据库
    open方法,存在就打开,不存在就创建并打开
    2、对象存储空间
    3、事务
    4、使用游标查询
    在对象存储空间调用openCursor方法卡创建游标
    5、键范围
    通过游标查找方式有限,键范围为游标增添了灵活性
    6、设定游标方向
    7、索引
    8、并发问题
    9、限制
    与Web Storage类似,只能由同源(同协议,域名,端口)页面操作,不能跨域共享信息。
    空间限制
  • 相关阅读:
    CHARINDEX,REPLACE,LEFT+四大系统函数+模糊查询
    将本地的代码上传到网上SVN库
    数据可视化之DAX篇(十六)如何快速理解一个复杂的DAX?这个方法告诉你
    数据可视化之DAX篇(十五)Power BI按表筛选的思路
    数据可视化之DAX篇(十四)DAX函数:RELATED和RELATEDTABLE
    数据可视化之DAX篇(十三)熟练使用FORMAT函数,轻松自定义数据格式
    数据可视化之DAX篇(十二)掌握时间智能函数,同比环比各种比,轻松搞定!
    数据可视化之DAX篇(十一)Power BI度量值不能作为坐标轴?这个解决思路送给你
    Flask 基础组件(十):中间件
    Flask 基础组件(九):请求扩展
  • 原文地址:https://www.cnblogs.com/TwinklingZ/p/5277146.html
Copyright © 2020-2023  润新知