zoukankan      html  css  js  c++  java
  • AJAX数据传输之请求与发送

    AJAX是高性能JavaScript的基础。

        它可以通过延迟下载体积较大的资源文件来使得页面加载速度更快。

        它通过异步的方式在客户端和服务端之间传输数据,从而避免页面资源持续不间断(一窝蜂)地下载。

        它甚至可以只用一个HTTP请求就获取整个页面的资源。multipart XHR

    选择合适的传输方式和最有效的数据格式,可以显著改善用户和网站的交互体验。

    1. XMLHttpRequest

    获取通用的XHR对象,并进行数据请求与获取

    View Code
    /**
      * 创建通用的XHR对象
      */
     function createXHR() {
         var msxml_progid = [
             'MSXML2.XMLHTTP.6.0',
             'MSXML3.XMLHTTP',
             'Microsoft.XMLHTTP',        //不支持readyState 3
             'MSXML2.XMLHTTP.3.0'        //不支持readyState 3
         ];
         var XHR = null;
         try {
             XHR = new XMLHttpRequest();
         }catch(e) {
             for(var i=0,j=msxml_progid.length; i<j; i++){
               try {
                   XHR = new ActiveObject(msxml_progid[i]);
                   break;        //如果上面的语句有错直接跳到catch子句中,正确的话直接跳出循环
               }catch(e2) {}
             }
         }finally {
             return XHR;
         }
     }
     
     function request() {
         var xhr = createXHR();
         var url = 'index.php';
         xhr.open('get', url, true);
         //设置请求头消息 在服务器端判断是否是AJAX请求$_SERVER[‘HTTP_X_REQUESTED_WITH’]
         xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
         xhr.setRequestHeader('anan', 'mackxu');
         xhr.send(null);
         xhr.onreadystatechange = function() {
             if (xhr.readyState == 4) {
                 if(xhr.status==200 || xhr.status==304) {
                     response(xhr.responseText);
                 }            
             }
         }
     }
     //处理服务器响应的数据
     function response(sData) {
         document.getElementById('response').innerHTML = sData;
     }

    使用XHR时,POSTGET的对比:

        Get方式:

       用get方式可传送简单数据,但大小一般限制在1KB下,数据追加到url中发送。另外最重要的一点是,它会被客户端的浏览器缓存起来,那么,别人就可以从浏览器的历史记录中,读取到此客户的数据,比如帐号和密码等。因此,在某些情况下,get方法会带来严重的安全性问题。

       Post方式:

       当使用POST方式时,浏览器把各表单字段元素及其数据作为HTTP消息的实体内容发送给Web服务器,而不是作为URL地址的参数进行传递,使用POST方式传递的数据量要比使用GET方式传送的数据量大的多。

       总之,GET方式传送数据量小,处理效率高,安全性低,会被缓存,而POST反之。

    使用get方式需要注意:

    1 对于get请求(或凡涉及到url传递参数的),被传递的参数都要先经encodeURIComponent方法处理.

    使用Post方式需注意:

    1.设置header的Context-Type为application/x-www-form-urlencode确保服务器知道实体中有参数变量.

    2.参数是名/值一一对应的键值对,每对值用&号隔开.如 var name=abc&sex=man&age=18

    3.参数在Send(参数)方法中发送,

        XHR的优点和缺点:

       

    2. 动态脚本注入JSONP

    能跨域请求数据

    只能使用GET请求

    对请求的完成情况无知直到回调函数执行或者不执行

    响应消息作为脚本标签的源码,它必须是可以执行的JavaScript代码

    将回调函数的名称作为传递服务器动态页面的数据之一

    View Code
    服务器端代码:
    <?php
        header("Content-type:text/javascript; charset=utf-8");
        $callback = $_GET['callback'];        //获取js回调函数名称
        $data = '动态加载脚本数据';
        echo $callback."('$data');";
    JS代码:
    //动态脚本加载
    function requestInfo() {
        var oScript = document.createElement('script');
        oScript.type = 'text/javascript';
        //把回调函数作为数据传递给服务器
        oScript.src = "index.php?callback=displayInfo";
        oScript.onerror = errorHandle;                //当src有误时触发
        //document.head.appendChild(oScript);        //IE7/8不支持
        document.getElementsByTagName('head')[0].appendChild(oScript);
    }
    //显示从服务器端获取的数据
    function displayInfo(data) {
        document.getElementById('response').innerHTML = data;
    }
    function errorHandle() {
        //处理请求失败情况
    }

    3. Multipart XHR

    MXHR允许客户端只用一个HTTP请求就可以从服务器端向客户端传送多个资源。

    思路:通过在服务器端将资源(css文件/js文件/HTML片段/base64编码的图片)打包成一个由双方约定的分隔符分割的长字符串,发送给客户端。然后用JS代码处理这个长字符串,并根据它的mime-type类型和传入的其他“头信息”解析出每个资源。

    图片资源 data:[<mime-type>][;base64],<data>

    View Code
    服务器端代码:
    //读取图片并将它们转换成base64编码的字符串
    $img_dir = dirname(__FILE__).'/../images/';
    //echo $img_dir;
    $images = array('password.gif', 'username.gif', 'warning.gif' );
    $img_load = array();
    //echo file_get_contents($img_dir.$images[0]);
    foreach ($images as $image) {
        $file_name = $img_dir.$image;
        $img_fh = fopen($file_name, 'r');
        //读取图片
        $img_data = fread($img_fh, filesize($file_name));
        fclose($img_fh);
        $img_load[] = base64_encode($img_data);
    }
    //把图片字符串合并成一个长字符串,然后输出
    $delimiter = chr(1);
    echo implode($delimiter, $img_load);
    客户端JS代码:
    //MXHR一次请求多张图片
    function request_imgs() {
        var oXHR = new XMLHttpRequest();
        var url = '../test/index.php';
        oXHR.open('GET', url, true);
        oXHR.send(null);
        oXHR.onreadystatechange = function() {
            if (oXHR.readyState == 4) {
                if(oXHR.status==200 || oXHR.status==304) {
                    split_images(oXHR.responseText);
                }
            }
        }
    }
    //分割图片字符串,向页面动态添加图片
    function split_images(sData) {
        var aImages = sData.split('\u0001');
        var oImage = null;
        for(var i=0, len=aImages.length; i<len; i++) {
            oImage = document.createElement('img');        //创建image元素
            //img.src = 'data:'+mimeType+';base64,'+data;
            oImage.src = 'data:image/gif;base64,'+aImages[i];
            document.body.appendChild(oImage);
        }
    }

    此技术的优缺点

    1. 以这种方式获取的资源不能被浏览器缓存。
    2. IE6、7不支持readyState=3状态和data:.
    3. 可以减少HTTP请求数量,特别是页面包含大量其他地方用不到的资源尤其是图片资源

    4. Beacons图片信标

    用JS修改图片的src属性实际上是向服务器发送一个针对该图片的请求,同时也提供了一个向客户端返回数据的机会。

    事件判断是否请求完成:onload、onerror

    根据图片大小判断请求情况:成功,1X1,失败2X1 其他3X1...

    function createImage() {
        var oImg = new Image();
        //加载成功
        oImg.onload = function() {
            //...
        };
        //加载失败
        oImg.onerror = function() {
            //...
        }
        oImg.src = '../images/username1.gif';        //指定要请求的文件的路径
    }

    图片和cookie

    cookie在性质上是绑定在特定的域名下的。当设置一个cookie后,再向创建它的域名发送请求时,都会包含这个cookie,这个限制确保了存储在cookie中的信息只能让批准的接受者访问,无法被其他域访问

    cookie的限制:

    1. 单个cookie的尺寸大小限制4096字节(加减1)

    每个域在用户机器上cookie数量有限制(IE7+ 50个)

    View Code
    function createImage() {
        var oImg = new Image();
        var oResponse = document.getElementById('response');
        oImg.onload = function() {
            //根据约定获取cookie值
            var name = getCookie('name');
            deleteCookie('name');
            oResponse.innerHTML = name;
        };
        oImg.onerror = function() {
            oResponse.innerHTML = 'this is a error!!';
        }
        oImg.src = '../test/index.php';
    }
    //获取特定的cookie值
    function getCookie(sName) {
        sName = encodeURIComponent(sName);
        //对Chrome有问题
        var sRE = "(?:;)?"+sName+"=([^;]*);?";
        var oRE = new RegExp(sRE);
        if (oRE.test(document.cookie)) {
            return decodeURIComponent(RegExp["$1"]);
        }else {
            return null;
        }
    }
    function deleteCookie(sName) {
        document.cookie = encodeURIComponent(sName)+"=0; "
            +"expires=Thu, 1 Jan 1970 00:00:00 UTC; path=/";
    }
    服务器端(PHP):
    <?php
        header("Content-type:image/gif");
        //图片和cookie传递数据
        setcookie('name', 'mackxu');
        header("Location: ../images/username.gif");

    优点和缺点:

    1. 很好的兼容性(跨浏览器)
    2. 请求执行成功和失败会有一些提示
    3. 可以跨域发送请求(对比XHR)
    4. 图片只能发送GET请求,发送的数据受限制,使用cookie返回数据也数据大小受限制、不安全
  • 相关阅读:
    【模板】2-SAT 问题
    HDU5875 Function
    Codeforces Round #380 (Div. 2)/729B Spotlights 水题
    Codeforces Round #380 (Div. 2)/729E Subordinates 贪心
    Codeforces Round #380 (Div. 2)/729D Sea Battle 思维题
    HDU 5869 Different GCD Subarray Query 树状数组+离线
    HDU 5696 区间的价值 暴力DFS
    HDU 5876 Sparse Graph BFS+set删点
    HDU 5868 Different Circle Permutation Burnside引理+矩阵快速幂+逆元
    HDU 5800 To My Girlfriend DP
  • 原文地址:https://www.cnblogs.com/mackxu/p/ajax_1.html
Copyright © 2011-2022 走看看