mackxu
子曰:学而时习之,不亦说乎?

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返回数据也数据大小受限制、不安全
posted on 2012-12-21 09:25  mackxu  阅读(828)  评论(0编辑  收藏  举报