【高性能JavaScript】读书笔记 - Ajax(二) - 12

本文介绍了Ajax技术的基本原理,包括异步数据交互方式、数据发送方法及常用数据格式等。重点讲解了XMLHttpRequest对象的使用方法,并对比了XML、JSON、HTML等数据格式的特点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


【简介】Ajax 是高性能 JavaScript 的基础。它可以通过延迟下载体积较大的资源文件来使得页面加载速度更快。它通过异步的方式在客户端和服务端之间传输数据,从而避免了页面资源一窝蜂地下载。它甚至可以只用一个 HTTP 请求就获取整个完整的页面资源。选择适合的传输方式和最有效的数据格式,可以显著改善用户和网站的交互体验。

2. 发送数据(Sending Data)

有时候你并不关心接收数据,而只需要将数据发送到服务器。当数据只需要发送到服务器时,有两种广泛使用的技术:XHR 和信标(beacons),这里我们只讲 XHR。

2-1 XHR(XMLHttpRequest)
<script type="text/javascript">

var url = '/data.php';
var params = ['id=242', 'limit=20'];

var req = new XMLHttpRequest();

req.onerror = function() {
    // 出错
}    

req.onreadystatechange = function() {
    if (req.readyState == 4) {
        // 成功
    }
}

req.open('POST', url, true);
req.setRequestHeader('Content-Type', 'application/x-www-from-urlencoded');
req.setRequestHeader('Content-Length', params.length);
req.send(params.join('&'));

</script>

对于发送到服务器的是至关重要的数据,可以增加一些代码来实现在失败时重试:

</script>

<script type="text/javascript">

function xhrPost(url, params, callback) {
    var req = new XMLHttpRequest();

    req.onerror = function() {
        // 失败时,添加一个定时器,1 秒后重试
        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-from-urlencoded');
    req.setRequestHeader('Content-Length', params.length);
    req.send(params.join('&'));
}

</script>

3. 数据格式

当考虑数据传输技术时,需要考虑:功能集、兼容性、性能以及方向(发送给服务器还是从服务器接收)。而当考虑数据格式时,唯一的标准就是速度。

没有哪一种数据格式会始终比其他格式更好,优劣取决于要传输的数据以及它在页面上的用途,一种可能下载更快,而另一种可能解析更快。

3-1. XML

XML 是 Ajax 早期时候使用最多的数据格式。当时它有很多的优势:极佳的通用性(服务端和客户端都能完美支持)、格式严格,易于验证。那时 JSON 还没有正式作为交换格式,几乎所有服务端语言都有操作 XML 的类库。

我们来看这样一段 XML :

<?xml version='1.0' encoding='utf-8' ?>
<users total='3'>
    <user id='1'>
        <username>abc1</username>
        <userage>23</userage>
    </user>
    <user id='2'>
        <username>abc2</username>
        <userage>24</userage>
    </user>
    <user id='3'>
        <username>abc3</username>
        <userage>21</userage>
    </user>
</users>

相比其他格式,XML 及其冗长。每个单独的数据片段都依赖大量的结构。而且解析 XML 需要占用 JavaScript 程序员相当一部分的精力。除了要提前知道纤细结构之外,还必须确切的知道如何解析这个结构并费力地将它重组到 JavaScript 对象中。

下面我们来演示解析上面这段 XML 的过程:

function parseXML(responseXML) {
    var users = [];
    var userNodes = document.getElementsByTagName('user');

    var userNode, usernameNode, username, userageNode, userage;

    for (var i = 0, len=userNodes.length; i < len; i++) {
        userNode = userNodes[i];

        usernameNode = userNode.getElementsByTagName('name')[0];
        username = (usernameNode.firstChild) ? usernameNode.firstChild.nodeValue : '';

        userageNode = userNode.getElementsByTagName('age')[0];
        userage = (userageNode.firstChild) ? userageNode.firstChild.nodeValue : '';

        users[i] = {
            id:userNode.getAttribute('id'),
            username: username,
            userage:userage
        };  
    }

    return users;
}

一个更有效的方法来处理读取值,将 username、userage 都作为 user 标签的属性,这样会更容易读取。

<?xml version='1.0' encoding='utf-8' ?>
<users total='3'>
    <user id='1' username="abc1" userage="23" />
    <user id='2' username="abc2" userage="24" />
    <user id='3' username="abc3" userage="21" />
</users> 

这样子的封装,在 JavaScript 中更容易处理:

<script type="text/javascript">

function parseXML(responseXML) {
    var users = [];
    var userNodes = document.getElementsByTagName('user');

    for (var i = 0, len=userNodes.length; i < len; i++) {

        users[i] = {
            id:userNodes[i].getAttribute('id'),
            username:userNodes[i].getAttribute('username'),
            userage:userNodes[i].getAttribute('userage')
        };  
    }

    return users;
}

</script>

这样的方式,虽然更容易使用 JavaScript 读取数据,但是其数据的结构性不如第一种来的更加层次分明。

3-2. JSON

JSON 是一种使用 JavaScript 对象和数组直接编写的轻量级且易于解析的数据格式:

[
    {"id":1, "username":"abc1", "userage":23},
    {"id":2, "username":"abc2", "userage":24},
    {"id":3, "username":"abc3", "userage":21}
]

将用户表示为一个对象,用户列表表示为一个数组。这意味着当它被求值或封装在一个回调函数中时,JSON 数据就是一段可执行的 JavaScript 代码,不需要像 XML 那样通过转换,就能 JavaScript 非常方便的调用。

正如 XML 那样,它可以提炼一个更为简化的版本。这种情况下,我们可以把属性名缩短(相对的可读性会变差):

[
    {"i":1, "u":"abc1", "a":23},
    {"i":2, "u":"abc2", "a":24},
    {"i":3, "u":"abc3", "a":21}
]

它将相同的数据以更少的结构和更小的文件大小传送给浏览器。更进一步,我们可以去掉属性名,与其他两种格式相比,这种格式可读性更差,也更脆弱,但文件尺寸却小得多,大约只有标准 JSON 的一半。

[
    [ 1, "abc1", 23 ],
    [ 2, "abc2", 24 ],
    [ 3, "abc3", 21 ]
]

虽然可读性差,但只要保持数据的顺序,也能很方便的解析:

function parseJSON(responseArr) {
    var users = [];
    for (var i = 0, len = responseArr.length; i < len; i++) {
        users[i] = {
            id: responseArr[i][0],
            username: responseArr[i][1],
            userage: responseArr[i][2]
        };
    }
    return users;
}
3-3. HTML

如果请求的数据需要被转成 HTML 以显示到页面上,可以在服务器上完成数据封装,这样会比在 JavaScript 中更快。即在服务器上构件号整个 HTML 再传回客户端,JavaScript 可以很方便地通过 innerHTML 属性把它插入到页面中。

比如我们直接在服务器上构建好这样一个 HTML 片段即可:

<ul class="uses">
    <li class="user" id="1">
        <span class="username">姓名:abc1</span>
        <span class="userage">年龄:23</span>
    </li>
    <li class="user" id="2">
        <span class="username">姓名:abc2</span>
        <span class="userage">年龄:24</span>
    </li>
    <li class="user" id="3">
        <span class="username">姓名:abc3</span>
        <span class="userage">年龄:21</span>
    </li>
</ul>

这种技术的问题是 HTML 是一种臃肿的数据格式,甚至比 XML 更繁杂。作为一种数据格式,它既缓慢,又臃肿。

3-4. 小结

作为数据格式,纯文本和 HTML 只适用于特定场合,但他们可以节省客户端的 CPU 周期;XML 被广泛应用而且支持良好,但是它十分笨重且解析缓慢;JSON 是一种轻量级的,解析速度快,通用性和 XML 相当的数据格式。

附: 欢迎大家关注我的新浪微博 - 一点编程,了解最新动态 。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值