美文网首页JavaScript < ES5、ES6、ES7、… >
JavaScript 高级程序设计(第21 Ajax 与 Com

JavaScript 高级程序设计(第21 Ajax 与 Com

作者: yinxmm | 来源:发表于2018-08-20 15:50 被阅读36次

    第21 Ajax 与 Comet

    1. XMLHttpRequest对象

    创建XHR对象

    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();
    

    (1) XHR的用法

    open()方法:

    接受 3 个参数:要发送的请求的类型("get"、"post"等)、请求的 URL 和表示是否异步发送请求的布尔值。
    xhr.open("get", "example.php", false);

    send()方法:

    发送特定的请求,send()方法接收一个参数,即要作为请求主体发送的数据。如果不需要通过请求主体发送 数据,则必须传入 null,因为这个参数对有些浏览器来说是必需的。调用 send()之后,请求就会被分 派到服务器。
    xhr.open("get", "example.txt", false);
    xhr.send(null);

    XHR 对象的属性:

    在收到响应后,响应 的数据会自动填充 XHR 对象的属性

    1. responseText:作为响应主体被返回的文本。
    2. responseXML:如果响应的内容类型是"text/xml"或"application/xml",这个属性中将保
      存包含着响应数据的 XML DOM 文档。
    3. status:响应的 HTTP 状态。
    4. statusText:HTTP 状态的说明。
    5. readyState: 表示请求 /响应过程的当前活动阶段。
    • 0:未初始化。尚未调用 open()方法。
    • 1:启动。已经调用 open()方法,但尚未调用 send()方法。
    • 2:发送。已经调用 send()方法,但尚未接收到响应。
    • 3:接收。已经接收到部分响应数据。
    • 4:完成。已经接收到全部响应数据,而且已经可以在客户端使用了。
      readyState 属性的值由一个值变成另一个值,都会触发一次 readystatechange 事件。
    var xhr = createXHR();
        xhr.onreadystatechange = function(){
            if (xhr.readyState == 4){
                if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){
                 alert(xhr.responseText);
            } else {
                 alert("Request was unsuccessful: " + xhr.status);
            }
    } };
    xhr.open("get", "example.txt", true);
    xhr.send(null);
    
    abort()方法:

    调用这个方法后,XHR 对象会停止触发事件,而且也不再允许访问任何与响应有关的对象属性。在 终止请求之后,还应该对 XHR 对象进行解引用操作。由于内存原因,不建议重用 XHR 对象。

    (2) HTTP头部信息

    1. Accept:浏览器能够处理的内容类型。
    2. Accept-Charset:浏览器能够显示的字符集。
    3. Accept-Encoding:浏览器能够处理的压缩编码。
    4. Accept-Language:浏览器当前设置的语言。
    5. Connection:浏览器与服务器之间连接的类型。
    6. Cookie:当前页面设置的任何 Cookie。
    7. Host:发出请求的页面所在的域 。
    8. Referer:发出请求的页面的 URI。注意,HTTP 规范将这个头部字段拼写错了,而为保证与规范一致,也只能将错就错了。(这个英文单词的正确拼法应该是 referrer。)
    9. User-Agent:浏览器的用户代理字符串。
    setRequestHeader()方法:

    设置自定义的请求头部信息。
    这个方法接受两个参数:头部字段 的名称和头部字段的值。要成功发送请求头部信息,必须在调用 open()方法之后且调用 send()方法 之前调用 setRequestHeader()

    getResponseHeader()方法:

    传入头部字段名称,可以取得相应的响应头部信息。

    getAllResponseHeaders()方法

    可以取得一个包含所有头部信息的长字符串。

    (3) GET请求

    可以将查询字符串参数追加 到 URL 的末尾,以便将信息发送给服务器。对 XHR 而言,位于传入 open()方法的 URL 末尾的查询字 符串必须经过正确的编码才行。

    xhr.open("get", "example.php?name1=value1&name2=value2", true);
    
    function addURLParam(url, name, value) {
            url += (url.indexOf("?") == -1 ? "?" : "&");
            url += encodeURIComponent(name) + "=" + encodeURIComponent(value);
            return url;
    }
    var url = "example.php";
    //添加参数
    url = addURLParam(url, "name", "Nicholas");
    url = addURLParam(url, "book", "Professional JavaScript");
    //初始化请求
    xhr.open("get", url, false);
    

    (4) POST请求

    用于向服务器发送应该被保存的数据,向 send()方法中传入某些数据。

    2. XMLHttpRequest 2 级

    (1) FormData

    FormData 为序列化表单以及创建与表单格式相同的数据(用于通过 XHR 传输)提供 了便利。

    var data = new FormData();
    data.append("name", "Nicholas");
    

    append()方法接收两个参数:键和值,分别对应表单字段的名字和字段中包含的值。可以像 这样添加任意多个键值对儿。而通过向 FormData 构造函数中传入表单元素,也可以用表单元素的数据 预先向其中填入键值对儿:

    var data = new FormData(document.forms[0]);
    

    (2) 超时设定

    XHR 对象添加了一个timeout 属性,表示请求在等待响应多少毫秒之后就终止。在给 timeout 设置一个数值后,如果在规定的时间内浏览器还没有接收到响应,那么就会触发 timeout 事 件,进而会调用 ontimeout 事件处理程序。

    (3) overrideMimeType()方法

    用于重写 XHR 响应的 MIME 类型。

    3. 进度操作

    6 个进度事件:

    (1) loadstart:在接收到响应数据的第一个字节时触发。
    (2) progress:在接收响应期间持续不断地触发。
    (3) error:在请求发生错误时触发。
    (4) abort:在因为调用 abort()方法而终止连接时触发。
    (5) load:在接收到完整的响应数据时触发。
    (6) loadend:在通信完成或者触发 error、abort 或 load 事件后触发。

    (1) load事件

    响应接收完毕后将触发 load 事件,因此也就没有必 要去检查 readyState 属性了。而 onload 事件处理程序会接收到一个 event 对象,其target 属性就指向 XHR 对象实例,因而可以访问到 XHR 对象的所有方法和属性。然而,并非所有浏览器都为这个事件实现了适当的事件对象。

    (2)progress 事件

    onprogress 事件处理程序会接收到一个 event 对象,其 target 属性是 XHR 对象,但 包含着三个额外的属性:lengthComputable、position 和 totalSize。其中,lengthComputable 是一个表示进度信息是否可用的布尔值,position 表示已经接收的字节数,totalSize 表示根据 Content-Length 响应头部确定的预期字节数。

    4. 跨源资源共享

    CORS(Cross-Origin Resource Sharing,跨源资源共享)

    CORS 背后的基本思想,就是使用自定义的 HTTP 头部 让浏览器与服务器进行沟通,从而决定请求或响应是应该成功,还是应该失败。

    比如一个简单的使用 GET 或 POST 发送的请求,它没有自定义的头部,而主体内容是 text/plain。在 发送该请求时,需要给它附加一个额外的 Origin 头部,其中包含请求页面的源信息(协议、域名和端 口),以便服务器根据这个头部信息来决定是否给予响应。
    Origin: http://www.nczonline.net

    如果服务器认为这个请求可以接受,就在Access-Control-Allow-Origin 头部中回发相同的源信息(如果是公共资源,可以回发"*")。
    Access-Control-Allow-Origin: http://www.nczonline.net

    如果没有这个头部,或者有这个头部但源信息不匹配,浏览器就会驳回请求。正常情况下,浏览器 会处理请求。注意,请求和响应都不包含 cookie 信息。

    (1) IE对CORS的实现

    XDR(XDomainRequest)类型。这个对象与 XHR 类似,但能实现安全可靠的跨域通信。

    XDR 与 XHR 的一些不同之处:

    1. cookie 不会随请求发送,也不会随响应返回。
    2. 只能设置请求头部信息中的 Content-Type 字段。
    3. 不能访问响应头部信息。
    4. 只支持GET和POST请求。
    5. XDR 对象的 open()方法只接收两个 参数:请求的类型和 URL。
    6. 请求返回之后,会触发 load 事件, 响应的数据也会保存在 responseText 属性中
    7. 在接收到响应后,你只能访问响应的原始文本;没有办法确定响应的状态代码。

    (2) 其他浏览器对CORS的实现

    要请求位于另一个域中的资源,使用标准的 XHR 对象并在 open()方法中传入绝对 URL 即可。
    跨域 XHR 对象限制:

    1. 不能使用 setRequestHeader()设置自定义头部。
    2. 不能发送和接收 cookie。
    3. 调用 getAllResponseHeaders()方法总会返回空字符串。

    (3) Preflighted Reqeusts

    CORS 通过一种叫做 Preflighted Requests 的透明服务器验证机制支持开发人员使用自定义的头部、 GET 或 POST 之外的方法,以及不同类型的主体内容。在使用下列高级选项来发送请求时,就会向服务 器发送一个 Preflight 请求。这种请求使用 OPTIONS 方法,发送下列头部。

    1. Origin:与简单的请求相同。
    2. Access-Control-Request-Method:请求自身使用的方法。
    3. Access-Control-Request-Headers:(可选)自定义的头部信息,多个头部以逗号分隔。
    Origin: http://www.nczonline.net
    Access-Control-Request-Method: POST
    Access-Control-Request-Headers: NCZ
    

    发送这个请求后,服务器可以决定是否允许这种类型的请求。服务器通过在响应中发送如下头部与 浏览器进行沟通。

    1. Access-Control-Allow-Origin:与简单的请求相同。
    2. Access-Control-Allow-Methods:允许的方法,多个方法以逗号分隔。
    3. Access-Control-Allow-Headers:允许的头部,多个头部以逗号分隔。
    4. Access-Control-Max-Age:应该将这个 Preflight 请求缓存多长时间(以秒表示)。
    Access-Control-Allow-Origin: http://www.nczonline.net
    Access-Control-Allow-Methods: POST, GET
    Access-Control-Allow-Headers: NCZ
    Access-Control-Max-Age: 172800016
    
    

    (4) 带凭据的请求

    默认情况下,跨源请求不提供凭据(cookie、HTTP 认证及客户端 SSL 证明等)。通过将 withCredentials 属性设置为 true,可以指定某个请求应该发送凭据。如果服务器接受带凭据的请 求,会用下面的 HTTP 头部来响应。
    Access-Control-Allow-Credentials: true

    5. 其他跨域技术

    (1) 图像Ping

    图像 Ping 是与服务器进行简单、单向的跨域通信的一种方式。 请求的数据是通过查询字符串形式发送的,而响应可以是任意内容,但通常是像素图或 204 响应。通过 图像 Ping,浏览器得不到任何具体的数据,但通过侦听 load 和 error 事件,它能知道响应是什么时 候接收到的。

    (2) JSONP

    JSONP 是 JSON with padding(填充式 JSON 或参数式 JSON)的简写,被包含在函数调用中的 JSON。
    callback({ "name": "Nicholas" });

    JSONP 由两部分组成:回调函数和数据。回调函数是当响应到来时应该在页面中调用的函数。回调 函数的名字一般是在请求中指定的。而数据就是传入回调函数中的 JSON 数据。

    JSONP 是通过动态<script>元素来使用的,使用时可以为
    src 属性指定一个跨域 URL。

    function handleResponse(response){
    alert("You’re at IP address " + response.ip + ", which is in " +
              response.city + ", " + response.region_name);
    }
    var script = document.createElement("script");
    script.src = "http://freegeoip.net/json/?callback=handleResponse";
    document.body.insertBefore(script, document.body.firstChild);
    

    (3) Comet

    Ajax 是一种从页面向服务器请求数据的技术,而Comet 则是一种服务器向页面推送数据的技术。Comet 能够让信息近乎实时地被推送到页面上,非常适合处理体育比赛的分数和股票报价。

    Comet 的实现方式:
    1. 长轮询把短轮询颠倒了一下。页面发起一个到服务器的请求,然后服务器一直保持连接打开,直到 有数据可发送。发送完数据之后,浏览器关闭连接,随即又发起一个到服务器的新请求。这一过程在页 面打开期间一直持续不断。
    1. HTTP 流它在页面的整个生命周期内只 使用一个 HTTP 连接。具体来说,就是浏览器向服务器发送一个请求,而服务器保持连接打开,然后周 期性地向浏览器发送数据。

    (4) 服务器发送事件

    SSE(Server-Sent Events,服务器发送事件)是围绕只读 Comet 交互推出的 API 或者模式。SSE API 用于创建到服务器的单向连接,服务器通过这个连接可以发送任意数量的数据。服务器响应的 MIME 类型必须是 text/event-stream,而且是浏览器中的 JavaScript API 能解析格式输出。

    * SSE API

    预订新的事件流,首先要创建一个新的 EventSource 对象,并传进一个入口点:var source = new EventSource("myevents.php");

    1. 传入的 URL 必须与创建对象的页面同源(相同的 URL 模式、域及端口)。
    2. EventSource 的 实例有一个readyState 属性,值为 0 表示正连接到服务器,值为 1 表示打开了连接,值为 2 表示关闭 了连接。
    3. 三个事件:
      (1) open:在建立连接时触发。
      (2) message:在从服务器接收到新事件时触发。
      (3) error:在无法建立连接时触发。
    source.onmessage = function(event){ 
    var data = event.data; //处理数据
    };
    //服务器发回的数据以字符串形式保存在 event.data 中
    
    1. 默认情况下,EventSource 对象会保持与服务器的活动连接。如果连接断开,还会重新连接。
    2. 调用 close() 方法强制立即断开连接并且不再重新连接。source.close();
    *事件流

    (5) Web Sockets

    相关文章

      网友评论

        本文标题:JavaScript 高级程序设计(第21 Ajax 与 Com

        本文链接:https://www.haomeiwen.com/subject/lxsliftx.html