zoukankan      html  css  js  c++  java
  • Ajax与Comet

    一、前言

      Ajax是Asynchronous javaScript + XML的简写。这一技术能够向服务器请求额外的数据而无须卸载页面,会带来更好的用户体验。这一技术改变了自从Web诞生以来就一直沿用的'单击,等待'的交互模式。Ajax技术的核心是 XMLHttpRequest 对象(简称 XHR),在 XHR出现之前,Ajax式的通信必须借助一些 hack手段来实 现,大多数是使用隐藏的框架或内嵌框架。XHR 为向服务器发送请求和解析服务器响应提供了流畅的 接口。能够以异步方式从服务器取得更多信息,意味着用户单击后,可以不必刷新页面也能取得新数据。 也就是说,可以使用 XHR 对象取得新数据,然后再通过 DOM 将新数据插入到页面中。

    二、XMLHttpRequest 对象 

      1.IE7+、Firefox、Opera、Chrome和 Safari都支持原生的 XHR对象。

        var xhr = new XMLHttpRequest();

      2.XHR用法

        xhr.open('get',url,false);//接受三个参数 请求的类型,请求的url,是否异步发送请求,open(0方法只是打开一个请求并没有真正的发送出去

        xhr.send(null);//send()方法接受一个参数,要作为请求主体发送的数据,如果没有则传入null;

      3.HTTP的头部信息

        每个http请求和响应都会带有相应的头部信息,XHR 对象也提供了操作这两种头部(即请求头部和响应头部)信息的方法。

        默认情况下,在发送 XHR 请求的同时,还会发送下列头部信息:

         Accept:浏览器能够处理的内容类型

        Accept-Charset:浏览器能够显示的字符集

          Accept-Encoding:浏览器能够处理的压缩编码

        Accept-Language:浏览器当前设置的语言

        Connection:浏览器与服务器之间连接的类型

        Cookie:当前页面设置的任何 Cookie

        Host:发出请求的页面所在的域

        Referer:发出请求的页面的 URI

        User-Agent:浏览器的用户代理字符串

      4.setRequestHeader()方法  可以设置自定义的请求头部信息,接受两个参数‘头部字段的名称’,‘头部字段的值’,setRequestHeader()只能在open()之后,send()之前调用,例:

        xhr.open("get", url, true);

        xhr.setRequestHeader("MyHeader", "MyValue");

          xhr.send(null); 

         通过getResponseHeader()方法并传入头部字段名称,可以取得相应的响应头部信息

      5.get请求

       使用get请求经常会发生一个错误,就是查询字符串的格式有问题。url末尾参数的参数的名称-值必须以&连接。

       xhr.open('get','example.php?name1=value1&name2=value2',true);

       一个辅助函数向现有URL的末尾添加查询字符串参数:

        function addURLParam(url,name,value){

        url += (url.indexof("?") == -1 ? "?" : "&");

        url += endcodeURIComponent(name)+ '=' endcodeURIComponnet(value);

        return url;

       }

       const url = "example.php";

       url = add(url,"name","haha");

       xhr.open('get',url,false);

    三、XMLHttpRequest 2级

      1.FormData

        FormData为序列化表单以及创建表单格式相同的数据提供了便利

        var data = new FormData();

        data.append('name','haha');

      例:

        xhr.open("post",'xxx',true);

        var form = document.getElementById("xx");

        xhr.send(new FormData(form));

    四、CORS 跨域资源共享

      通过 XHR 实现 Ajax 通信的一个主要限制,来源于跨域安全策略。默认情况下,XHR 对象只能访 问与包含它的页面位于同一个域中的资源。这种安全策略可以预防某些恶意行为。但是,实现合理的跨 域请求对开发某些浏览器应用程序也是至关重要的。

      CORS(Cross-Origin Resource Sharing,跨源资源共享)是 W3C的一个工作草案,定义了在必须访 问跨源资源时,浏览器与服务器应该如何沟通。CORS背后的基本思想,就是使用自定义的 HTTP头部 让浏览器与服务器进行沟通,从而决定请求或响应是应该成功,还是应该失败。 

      1、IE对CORS的实现 微软在 IE8中引入了 XDR(XDomainRequest)类型。这个对象与 XHR类似,但能实现安全可靠 的跨域通信。

        XDR与XHR的一些不同之处

         cookie不会随请求发送,也不会随响应返回。 

         只能设置请求头部信息中的 Content-Type 字段。

         不能访问响应头部信息。

         只支持 GET 和 POST 请求。

        XDR的用法和XHR的用法类似,但XDR的请求都是异步的

      2、其他浏览器对CORS的实现 

        Firefox 3.5+、Safari 4+、Chrome、iOS版Safari和Android平台中的WebKit 都通过 XMLHttpRequest 对象实现了对 CORS 的原生支持。。要请求位于另一个域中的资源,使用标准的XHR对象并在 open()方法中传入绝对URL即可。

      3.CORS的基本原理

        浏览器将CORS分为“简单请求”和“非简单请求”

        满足一下两大条件就属于简单请求:

          1.请求方式是 :get、post、head之一

          2.http的头部信息不超过这些字段:Accept、Accept-Language、Content-Language、Last-Event-ID、Content-Type:只限于三个值application/x-www-form-urlencodedmultipart/form-datatext/plain

        3.1基本流程

          对于简单的请求,浏览器直接发送CORS请求,浏览器发现这次跨源AJAX请求是简单请求,就自动在头信息之中,添加一个Origin字段

          GET /cors HTTP/1.1

          Origin: http://api.bob.com

          Host: api.alice.com

          Accept-Language: en-US

          Connection: keep-alive

          User-Agent: Mozilla/5.0...

          上面的头信息中,Origin字段用来说明,本次请求来自哪个源(协议 + 域名 + 端口)。服务器根据这个值,决定是否同意这次请求。如果Origin指定的源,不在许可范围内,服务器会返回一个正常的HTTP回应。浏览器发现,这个回应的头信息没有包   含Access-Control-Allow-Origin字段(详见下文),就知道出错了,从而抛出一个错误,被XMLHttpRequestonerror回调函数捕获。注意,这种错误无法通过状态码识别,因为HTTP回应的状态码有可能是200。

          如果Origin指定的域名在许可范围内,服务器返回的响应,会多出几个头信息字段:

          Access-Control-Allow-Origin: http://api.bob.com

          Access-Control-Allow-Credentials: true

          Access-Control-Expose-Headers: FooBar

          Content-Type: text/html;

          charset=utf-8

          上面的头信息之中,有三个与CORS请求相关的字段,都以Access-Control-开头。

          (1)Access-Control-Allow-Origin     该字段是必须的。它的值要么是请求时Origin字段的值,要么是一个*,表示接受任意域名的请求。

          (2)Access-Control-Allow-Credentials  该字段可选。它的值是一个布尔值,表示是否允许发送Cookie。默认情况下,Cookie不包括在CORS请求之中。设为true,即表示服务器明确许可,Cookie可以包含在请求中,一起发给服务器。这个值也只能设为true,如果服务器不要浏览器发送Cookie,删除该字段即可。

          (3)Access-Control-Expose-Headers 该字段可选。CORS请求时,XMLHttpRequest对象的getResponseHeader()方法只能拿到6个基本字段:Cache-ControlContent-LanguageContent-TypeExpiresLast-ModifiedPragma。如果想拿到其他字段,就必须在Access-Control-Expose-Headers里面指定。上面的例子指定,getResponseHeader('FooBar')可以返回FooBar字段的值。

          对于非简单的请求 

            非简单请求是那种对服务器有特殊要求的请求,比如请求方法是PUTDELETE,或者Content-Type字段的类型是application/json。非简单请求的CORS请求,会在正式通信之前,增加一次HTTP查询请求,称为"预检"请求(preflight)。浏览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些HTTP动词和头信息字段。只有得到肯定答复,浏览器才会发出正式的XMLHttpRequest请求,否则就报错。

    五、其它跨域技术

      Comet 是一种更高级的Ajax技术(也有人称为‘服务器推送’),Ajax 是一种从页面向服务器请求数据的技术,而 Comet 则是一种服务器向页面推送数据的技 术。Comet能够让信息近乎实时地被推送到页面上,非常适合处理实时数据的更新

      Comet实现的两种方式:

        长轮询和流:

          长轮询是浏览器定时向服务器发送请求。页面发起一个到服务器的请求,然后服务器一直保持连接打开,直到数据可发送。无论是短轮询还是长轮询,浏览器都要在接收数据之前,先发起对服务器的连接。两者大的区别 在于服务器如何发送数据。短轮询是服务器立即发送响应,无论数据是否有效,而长轮询是等待发送响 应。

          http流,流不同于上面两种轮询,因为他在页面的整个生命周期内只使用一个http连接。就是浏览器向服务器发送一个请求,而服务器保持连接打开,然后周 期性地向浏览器发送数据

      web scoket:是一个在单独的持久连接上提供全双工、双向通信。在 JavaScript中创建了 Web Socket之后,会有一个 HTTP请求发送 到浏览器以发起连接。在取得服务器响应后,建立的连接会使用 HTTP 升级从 HTTP 协议交换为 Web Socket 协议。也就是说,使用标准的 HTTP 服务器无法实现 Web Sockets,只有支持这种协议的专门服 务器才能正常工作。由于 Web Sockets使用了自定义的协议,所以 URL模式也略有不同。未加密的连接不再是 http://, 而是 ws://;加密的连接也不是 https://,而是 wss://。在使用 Web Socket URL时,必须带着这个 模式,因为将来还有可能支持其他模式。

      1. Web Sockets API 

        var socket = new WebSocket("ws://www.example.com/server.php"); 

        WebSocket 表示当前状态的 readyState 属性:

        WebSocket.OPENING (0):正在建立连接

        WebSocket.OPEN (1):已经建立连接

        WebSocket.CLOSING (2):正在关闭连接

        WebSocket.CLOSE (3):已经关闭连接

        要关闭 Web Socket连接,可以在任何时候调用 close()方法

        socket.close(); 

      2. 发送和接收数据 

        socket.send("Hello world!"); 

        var message = {time: new Date(), text: "Hello world!", clientId: "asdfp8734rew" }; 

        socket.send(JSON.stringify(message)); //参数必须序列化

        socket.onmessage = function(event){

          var data = event.data; 

          console.log(data);

         };

        3. 其他事件 

        var socket = new WebSocket("ws://www.example.com/server.php"); 

        socket.onopen = function(){ //成功建立连接时的钩子函数

            alert("Connection established.");

        }; 


        socket.onerror = function(){ //发生错误时触发,连接不能持续

           alert("Connection error.");

        };

        socket.onclose = function(){ //在连接关闭时触发

           alert("Connection closed.");

        };

    六、Promise

      在javaScript中,所有代码执行都是单线程执行的。所以导致JavaScript的所有网络操作,浏览器事件,都必须是异步执行

      基本用法:

      const promise = new Promise(function(resolve, reject) {

        if (true){

         resolve(value); //把状态Promise对象状态从未完成变为成功

        } else {
          reject(error); //把状态Promise对象状态从未完成变为失败

    }});
    Promise.prototype.then();

      Promise 实例具有then方法,也就是说,then方法是定义在原型对象Promise.prototype上的。它的作用是为 Promise 实例添加状态改变时的回调函数。前面说过,then方法的第一个参数是resolved状态的回调函数,第二个参数(可选)是rejected状态的回调函数。

    then方法返回的是一个新的Promise实例(注意,不是原来那个Promise实例)。因此可以采用链式写法,即then方法后面再调用另一个then方法

    Promise.prototype.catch();
    Promise.prototype.catch方法是.then(null, rejection).then(undefined, rejection)的别名,用于指定发生错误时的回调函数。

    参考文章
      <<javascript 高级程序设计>> <<ECMAScript6入门-阮一峰>><<https://www.cnblogs.com/keyi/p/6726089.html>>
      
     
     
  • 相关阅读:
    linux的mount(挂载)NFS 共享,命令详解
    Ubuntu 14.04下NFS安装配置
    linux下实现ftp匿名用户的上传和下载文件功能
    ubuntu apache2配置详解(含虚拟主机配置方法)
    在Ubuntu Server下搭建LAMP环境
    RPM 命令
    阿里云主机ssh 免密码登录
    PHPMailer使用说明
    git的一些基础命令
    穿线
  • 原文地址:https://www.cnblogs.com/xufeikko/p/10643554.html
Copyright © 2011-2022 走看看