zoukankan      html  css  js  c++  java
  • 大熊君学习html5系列之------XHR2(XMLHttpRequest Level 2)

    一,开篇分析

    Hi,大家好!大熊君又和大家见面了,(*^__^*) 嘻嘻……,这系列文章主要是学习Html5相关的知识点,以学习API知识点为入口,由浅入深的引入实例,

    让大家一步一步的体会"h5"能够做什么,以及在实际项目中如何去合理的运用达到使用自如,完美驾驭O(∩_∩)O~,好了,废话不多说,直接进入今天的主题,

    今天主要讲的是“XMLHttpRequest Level 2 API”及在客户端浏览器中的作用,并且会引入一个实际的例子做为讲解的原型范例,让我们先来看看“XHR API”:

    HTML5 世界中有这样一位无名英雄:"XMLHttpRequest"。严格地说,XHR2 并不属于 HTML5。不过,它是浏览器供应商对于核心平台不断做出的改进中的一部分。

    我之所以将" XHR2 "加入到"h5"系列中,就是因为它在如今复杂的网络应用中扮演了不可或缺的角色,引入了大量的新功能(例如跨源请求、上传进度事件以及对上传/下载二进制数据的支持等)。

          

    二,温故而知新

      我们先来一个简单的回顾:

      (1),XMLHttpRequest Level 1 对象创建

    var xhr = new XMLHttpRequest() ;
    

      (2),建立与Server主机的链接并且发出请求

    xhr.open('GET', 'bb.jsp') ;
    xhr.send() ;
    

      (3),等待Server主机做出回应,监听XMLHttpRequest对象的状态变化,指定回调函数

    xhr.onreadystatechange = function(){
        if( xhr.readyState == 4 && xhr.status == 200 ) {
         alert( xhr.responseText ) ;
     } 
        else{
         alert( xhr.statusText ) ;
        }
    } ;
    

      

     总结一下:相对于新版本"XMLHttpRequest Level 2"来说有一些不足

     只支持文本数据的传送,无法用来读取和上传二进制文件。

     传送和接收数据时,没有进度信息,只能提示有没有完成。

     受到"同域限制"(Same Origin Policy),只能向同一域名的服务器请求数据。

     新版本的一些功能扩充:

     可以设置HTTP请求的时限。 

    xhr.timeout = 3000 ;
    xhr.ontimeout = function(event){
        alert('请求超时!');
    } ;

      (最长等待时间设为3000毫秒。过了这个时限,就自动停止HTTP请求。与之配套的还有一个timeout事件,用来指定回调函数。)

      

       可以使用FormData对象管理表单数据。(后面会有详细的介绍。)

     可以上传文件。(后面会有详细的介绍。)

     可以请求不同域名下的数据(跨域请求)。

     HTML 5 以前的标准由于考虑到浏览器安全问题并不允许直接跨域通信,于是为了达到跨域通信的目的各种蛋疼的解决办法出现了,

    常用的有:jsonp,使用代理文件,地址栏hash等等,这些办法的出现在达到解决跨域问题的同时,也增加了前端页面的性能开销和维护成本。

    HTML5新的标准中,增加了” Cross-Origin Resource Sharing”特性,这个特性的出现使得跨域通信只需通过配置http协议头来即可解决。

      (Cross-Origin Resource Sharing实现的最重要的一点就是对参数” Access-Control-Allow-Origin”的配置,即通过 次参数检查该跨域请求是否可以被通过。
    如:Access-Control-Allow-Origin:http://a.com表示允许a.com下的域名跨域访问;
    Access-Control-Allow-Origin:*表示允许所有的域名跨域访问。)

      

      如果需要读取读取cookie:
      需要配置参数:Access-Control-Allow-Credentials:true
      同时在xhr发起请求的时候设置参数withCredentials为true:
      

        

    var xhr = new XMLHttpRequest() ;
    xhr.open() ;
    xhr.withCredentials = true ;  //这个放在xhr.open后面执行,否则有些浏览器部分版本会异常,导致设置无效。
    

      以下为参考实例:

      

     可以获取服务器端的二进制数据。

       老版本的XMLHttpRequest对象,只能从服务器取回文本数据,新版则可以取回二进制数据。分成两种做法。较老的做法是改写数据的MIMEType,

    将服务器返回的二进制数据伪装成文本数据,并且告诉浏览器这是用户自定义的字符集。

    xhr.overrideMimeType("text/plain; charset=x-user-defined") ;
    

      新版本处理方式:

    var xhr = new XMLHttpRequest() ;
    xhr.open('GET', '/path/bb.png') ;
    xhr.responseType = 'blob' ;
    

      

    可以获得数据传输的进度信息。

      新版本的XMLHttpRequest对象,传送数据的时候,有一个progress事件,用来返回进度信息。

      它分成上传和下载两种情况。下载的progress事件属于XMLHttpRequest对象,上传的progress事件属于XMLHttpRequest.upload对象。

      我们先定义progress事件的回调函数。

        

    xhr.onprogress = updateProgress ;
    xhr.upload.onprogress = updateProgress ;
    
    function updateProgress(event) {
        if (event.lengthComputable) {
          var percentComplete = event.loaded / event.total ;
      }
    } ;
    

      与progress事件相关的,还有其他五个事件,可以分别指定回调函数:

      

        * load事件:传输成功完成。
      * abort事件:传输被用户取消。
      * error事件:传输中出现错误。
      * loadstart事件:传输开始。
      * loadEnd事件:传输结束,但是不知道成功还是失败。
    

      

    三,实例引入

      

    <!DOCTYPE HTML>
    <html>
        <head>
            <meta charset="utf-8">
            <title>File Upload</title>
            <script src="jquery.min.js"></script>
        </head>
        <body>
            <form id="form">
                <input type="file" name="file" id="file" />
                <input type="text" name="name" id="" value="大熊君{{bb}}}}" />
                <input type="text" name="blog" id="" value="http://www.cnblogs.com/bigbearbb/" />
                <input type="submit" name="do" id="do" value="submit" />
            </form>
            <script>
            $("form").submit(function(e){
                e.preventDefault();
                
                //空对象然后添加
                var fd = new FormData();
                fd.append("name", "大熊君{{bb}}");
                fd.append("blog", "http://www.cnblogs.com/bigbearbb/");
                fd.append("file", document.getElementById("file"));
                //fd.append("file", $(":file")[0].files[0]); //jQuery 方式
                fd.append("do", "submit");
                
                //通过表单对象创建 FormData
                var fd = new FormData(document.getElementById("form"));
                //var fd = new FormData($("form:eq(0)")[0]); //jquery 方式
                
                //XMLHttpRequest 原生方式发送请求
                var xhr = new XMLHttpRequest();       
                xhr.open("POST" ,"" , true);
                xhr.send(fd);
                xhr.onload = function(e) {
                    if (this.status == 200) {
                       alert(this.responseText);
                    };
                };
                return;
                //jQuery 方式发送请求
                $.ajax({
                    type:"post",
                    //url:"",
                    data: fd,
                    processData: false,
                    contentType: false
                }).done(function(res){
                    console.log(res);
                });  
                return false;
            });
            </script>
        </body>
    </html>
    

      

      

      效果如下:

      

      

      知识补充:”FormData“ 对象

        初始化一个FormData对象

    var oMyForm = new FormData();
    oMyForm.append("username", "bigbear");
    oMyForm.append("accountnum", 123456); // 数字123456被立即转换成字符串"123456"
    // fileInputElement中已经包含了用户所选择的文件
    oMyForm.append("userfile", fileInputElement.files[0]);
    var oFileBody = "<a id="a"><b id="b">hey!</b></a>"; // Blob对象包含的文件内容
    var oBlob = new Blob([oFileBody], { type: "text/xml"});
    oMyForm.append("webmasterfile", oBlob);
    

       使用HTML表单来初始化一个FormData对象

    var formElement = document.getElementById("myFormElement");
    var oReq = new XMLHttpRequest();
    oReq.open("POST", "submitform.php");
    oReq.send(new FormData(formElement));
    
    你还可以在已有表单数据的基础上,继续添加新的键值对,如下:
    
    var formElement = document.getElementById("myFormElement");
    formData = new FormData(formElement);
    formData.append("nick","bb");
    oReq.send(formData);
    

     

      

    (四),最后总结

      (1),理解XMLHttpRequest Level 2 Api的使用方式以及具体实例中使用的目的是为了解决哪些问题。

      (2),XMLHttpRequest Level 2 与 之前老版本的不同之处在哪。

      (3),熟练使用FormData对象,不断实践与重构文章中的栗子。

                       哈哈哈,本篇结束,未完待续,希望和大家多多交流够沟通,共同进步。。。。。。呼呼呼……(*^__^*)    

  • 相关阅读:
    leetcode Power of Two
    leetcode Merge Two Sorted Lists
    Mac linux 安装memcached服务 用法
    Vsftp配置都没有问题 连接不上 530 Login incorrect 解决方法
    mysql 远程连接不上 %用户已经添加了
    Centos yum 安装mysql报错 No package mysql-server available.
    Linux 查询程序安装路径 是否安装
    php报错 Call to undefined function mb_stripos()
    mac编译openssl扩展报错 openssl.c:44:10: fatal error: 'openssl/evp.h' file not found
    在安装mysqli的时候,出现error: ext/mysqlnd/mysql_float_to_double.h: No such file or direc
  • 原文地址:https://www.cnblogs.com/bigbearbb/p/4274470.html
Copyright © 2011-2022 走看看