zoukankan      html  css  js  c++  java
  • 高性能 AJAX

    请求数据的常用的五种方式
    1、XMLHttpRequest (XHR)
    var url = '/data.php';
    var params = [
        'id=934875',
        'limit=20'
    ];
    var req = new XMLHttpRequest();
    req.onreadystatechange = function() {
        if (req.readyState === 3) {                                                    // 只收到部分数据的情况
              var dataSoFar = req.responseText;
               ...
        }
        if (req.readyState === 4) {
            var responseHeaders = req.getAllResponseHeaders();                // Get the response  headers.
            var data = req.responseText;                                              // Get the data.
                                                                                                // Process the data here...
         }
    }
    req.open('GET', url + '?' + params.join('&'), true);
    req.setRequestHeader('X-Requested-With', 'XMLHttpRequest');           // Set a request  header.
    req.send(null);                                                                         // Send the request.
    注: 对于那些不会修改服务器状态只是拿回数据的,应该使用get方式,get是会缓存的,可以提高性能如果对同样数据多次fetch
    post应该URL长度接近或者超过2048的时候用,因为ie限制了URL的长度,超过会被切掉
    最大限制:不能跨域请求数据
     
    2、动态生成插入脚本标签
    var scriptElement = document.createElement('script');
    scriptElement.src = 'http://any-domain.com/javascript/lib.js';
    document.getElementsByTagName('head')[0].appendChild(scriptElement);
    function jsonCallback(jsonString) {
        var data = eval('(' + jsonString + ')');
        // Process the data here...
    }     
    lib.js :  jsonCallback({ "status": 1, "colors": [ "#fff", "#000", "#ff0000" ] });
    注:这种方式突破了上面XHR不允许跨域的限制,但是失去很多可控性:不能把header和请求一起发送。只能用get方式请求不能使用post。不能设置超时或者重试请求,甚至你都不知道请求失败了。需要等到全部数据接收完才能接入处理。无法把响应的header或者整个响应作为字符串接入。
    最重要的是响应是作为script标签里执行的,因此必须是可直接执行的javascript代码。
     
    3、multipart XHR
    客户端:
    var req = new XMLHttpRequest();
    req.open('GET', 'rollup_images.php', true);
    req.onreadystatechange = function() {
        if (req.readyState == 4) {
            splitImages(req.responseText);
        }
    };
    req.send(null);
     
    function splitImages(imageString) {                                 //用于处理传回来的长字符串图片数据
        var imageData = imageString.split("u0001");
        var imageElement;
        for (var i = 0, len = imageData.length; i < len; i++) {
            imageElement = document.createElement('img');
            imageElement.src = 'data:image/jpeg;base64,' + imageData[i];
            document.getElementById('container').appendChild(imageElement);
        }
    }
     
    服务器(PHP):
    $images = array('kitten.jpg', 'sunset.jpg', 'baby.jpg');                        // Read the images and convert them into base64 encoded strings.
    foreach ($images as $image) {
        $image_fh = fopen($image, 'r');
        $image_data = fread($image_fh, filesize($image));
        fclose($image_fh);
            $payloads[] = base64_encode($image_data);
        }
    }
    $newline = chr(1);                                                  // This character won't appear naturally in any base64 string.
    echo implode($newline, $payloads);                            // Roll up those strings into one long string and output it.
     
    用于把字符串还原成浏览器能识别资源的函数:
    function handleImageData(data, mimeType) {
        var img = document.createElement('img');
        img.src = 'data:' + mimeType + ';base64,' + data;
        return img;
    }
    function handleCss(data) {
        var style = document.createElement('style');
        style.type = 'text/css';
        var node = document.createTextNode(data);
        style.appendChild(node);
        document.getElementsByTagName('head')[0].appendChild(style);
    }
    function handleJavaScript(data) {
        eval(data);
    }
     
    如果数据太多例如200张图片那么不能等到整个字符串接受完才处理,应该把接收到资源一边处理掉:
    var req = new XMLHttpRequest();
    var getLatestPacketInterval, lastLength = 0;
    req.open('GET', 'rollup_images.php', true);
    req.onreadystatechange = readyStateHandler;
    req.send(null);
    function readyStateHandler {
        if (req.readyState === 3 && getLatestPacketInterval === null) {
            getLatestPacketInterval = window.setInterval(function() {                                 // Start polling.
                getLatestPacket();
            }, 15);
        }
        if (req.readyState === 4) {
            clearInterval(getLatestPacketInterval);                                                     // Stop polling.
            getLatestPacket();                                                                              // Get the last packet.
        }
    }
    function getLatestPacket() {                                                             //每15毫秒执行一次该函数,然后把响应的新数据拿下来,等到一个资源定界符出现就处理掉这个资源
        var length = req.responseText.length;
        var packet = req.responseText.substring(lastLength, length);
        processPacket(packet);
        lastLength = length;
    }
    注:这是最新的技术,允许把多个资源从服务器发送到客户端只需要一个HTTP请求。把所以资源(无论是CSS文件,HTML fragment,javascript代码或者base64图片)打包成一个长字符串,javascript在处理这个长字符串的时候会根据每种资源的mine-type来区分。缺点:拿到的资源没办法缓存在浏览器,因为资源是通过字符串的形式传到浏览器的,没有办法把文件通过程序放到浏览器缓存里。ie6、7不支持readyState3 or data:URLs。优点:减少HTTP请求,加快速度
     
    4、iframes
    5、comet
    前三种性能高,首选第一种
     
    发送数据给服务器方式:
    1、XMLHttpRequest (XHR)      
    function xhrPost(url, params, callback) {
        var req = new XMLHttpRequest();
        req.onerror = function() {
            setTimeout(function() {
               xhrPost(url, params, callback);
            }, 1000);
        };
        req.onreadystatechange = function() {
            if (req.readyState == 4) {
                if (callback && typeof callback === 'function') {
                    callback();
                }
            }
        };
        req.open('POST', url, true);
        req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
        req.setRequestHeader('Content-Length', params.length);
        req.send(params.join('&'));
    }
    注:虽然常用于从服务器请求数据,但是也能用于发送数据给服务器。当你想传回服务器的数据超过URL限制,使用post方式传回就很实用
     
    2、Beacons
    var url = '/status_tracker.php';
    var params = [
        'step=2',
        'time=1248027314'
    ];
    (new Image()).src = url + '?' + params.join('&');
     
    beacon.onload = function() {
        if (this.width == 1) {
            // Success.
        }
        else if (this.width == 2) {
            // Failure; create another beacon and try again.
        }
    };
    beacon.onerror = function() {
        // Error; wait a bit, then create another beacon and try again.
    };
    注:src的URL指向服务器上处理的PHP脚本。缺点:不能使用post方式,只能通过get传递,因此数据长度有限制。返回的响应十分有限。 优点:速度最快,最高效
  • 相关阅读:
    Dynamics CRM开发参考资料
    Sql Server存储过程和游标的配合操作
    C#字符处理的性能问题
    Windows安装完ADFS后卸载ADFS清除ADFS数据库
    C#修改AD账号及密码
    Dynamics CRM安装教程九(续):自建证书的CRM项目客户端设置CRM访问
    Kubernetes实践之深入掌握Pod——Pod健康检查和服务可用性检查
    Kuberbetes实践——镜像拉取策略、command args参数、Pod生命周期和重启策略
    Kubernetes实践之深入掌握Pod——在容器内获取Pod信息
    Kubernetes实践之深入掌握Pod——ConfigMap
  • 原文地址:https://www.cnblogs.com/chuangweili/p/5166281.html
Copyright © 2011-2022 走看看