正在加载中

最后更新于 2019年06月16日

异步监听readyState == 3

当readyState的值等于3时,此时服务器正在与浏览器传输数据,这个时候其实是可以进行获取到responseText值得,但是这个值并不完整,只有当readyState == 4时,值才是完整的。

但是如果我们需要获取的内容是极其长的字符,那么就可以通过监听这个状态,然后轮询的方式,可以在内容没有全部下载来之前就可以提前更新内容了,这样就可以避免在下载的过程中产生的等待时间。

var req = new XMLHttpRequest();
var getLastInterval =null,
    lastLength = 0;
req.open('GET','xxx.php',true);
req.onreadystatechange = readStateHandler;
req.send(null);

function readStateHandler() {
    if(red.readyStare == 3 && getLastInterval == null) {
        getLastInterval = setInterval(function(){
            getLastePacket();
        },15)
    }
    if(red.readyStare == 4) {
        clearInterval(getLastInterval);
        getLastePacket();
    }
}

function getLastePacket() {
    var length = req.responseText.length;
    var packet = req.responseText.substring(lastLength,length);
     callback(packet);
     lastLength = length;
}

当readyState等于3的时候,创建一个定时器,15ms调用一次getLastePacket函数,这个函数每次运行先得到当前req.responseText.length的字符长度,然后通过string的substring方法截取这段内容,然后下次运行的时候又从上一次的最后一个位置开始,然后回调函数callback,将packet字符串传入,这个回调函数还要根据你传入的值做判断,毕竟你需要判断目前的字符最后一项是否完整,如果不完整可以创建一个全局变量来保存,下次再续上。

通过这个方法可以在较大的内容时减少等待时间,增加用户体验。

multipart XHR

说白了就是通过php将多个地址合并成一个字符串返回给浏览器,浏览器通过js将返回的字符串解析成需要的值。

比如php返回三个img图片的地址,通过;分号连接。

if(req.readyState == 4) {
  splitImage(req.responsText);
}


function splitImage(text) {
  var imgelement = null,
      imgdata = text.split(';');
  for(var i =0,len = imgdata.length;i<len;i++){
      imgelement = document.createElement('img');
      imgelement.src = imgdata[i];
      document.getElementsByTagName('body')[0].appendChild(imgelement);
      
  }
}

以此类推,我们还可以增加更多的值,比如添加css地址,js文件,通过用不同的字符分隔,就可以判断到不同值,然后对应的获取。

发送数据

通过ajax发送数据其实有点奢侈,但是ajax支持pos方式发送,但是如果只是单方面的发送,且数据不会太大就可以使用get方式,但是ie对get方式的请求是有字符限制的,也就是说url的字符不能超过2048个字符,为此我要可以根据实际的使用情况使用对应的方法。

发送数据我们甚至可以使用动态插入script的方式,更深层的讲,我们是通过元素的src属性进行发送的。

这里暂时先不讲src的方式,这里完善一下ajax的方式

事实上我们还要考虑如果发送错误的话怎么处理,这里就要使用到error事件。

req.onerror = functuon() {
    //发生错误,我们在这个函数了再次调用封装的ajax函数,重新再运行一次,也就是递归
}

我们甚至可以使用setTimeout来增加延时机制,如果获取的数据是要等一段时间才能获取到,然后再发送给服务器,那么就可以onerror事件里面使用setTimeout。

get的方式会比post的方式发送更快,get只有一个数据包,而post至少会有两个,一个是头信息,一个是post数据。

Beacons

上面讲到发送数据使用的是src的属性,那么我们就可以通过图片的src属性来发送我们的数据,但是这个也有一点小问题,就是他会等待服务器返回信息,我们可以通过返回一个204 No Content状态码来阻止客户端继续等待返回的消息正文。

使用Beacons其实也是有限制的,他不能发送post请求,且url的长度是有限制的。

var url = 'xxx.php';
var parms = ['id=1','time=12578'];
var beacons = new Image();
beacons .src = url + '?' + parms.join('&');

beacons.onload = function() {
  //通过服务器返回一个图片,如果宽度是1表示成功,宽度为2表示错误
  if(beacons.width == 1) {
  
  }else if(beacons.width == 2) {
    
  }
}

beacons.onerror = function() {
  //如果发生错误,递归一次
}

数据的格式

XML的格式是以前比较通过的格式,但是太过于冗长,其内容书写和html类似,下面是一个标准的格式:

<?xml version="1.0" encoding='utf-8'>
<users total='2'>
  <user id="1">
    <username>alice</username>
    <realname>Alice Smith</realname>
    <email>alice@xxx.com</email>
  </user>
   <user id="2">
    <username>alice2</username>
    <realname>Alice Smith2</realname>
    <email>alice2@xxx.com</email>
  </user>
</users>

这种格式其实实质性的内容不多,为此并不是一种很好的方式,为此可以优化一下

<?xml version="1.0" encoding='utf-8'>
<users total='2'>
  <user id="1" username="alice" realname="Alice Smith" email="alice@xxx.com"/>
   <user id="2" username="alice2" realname="Alice Smith2" email="alice2@xxx.com"/>
</users>

通过属性值得方式可以将大量重复性的标签丢弃,从而减少文件的大小,并且js也可以更简便的获取内容。

JSON

json的格式相对于xml他更倾向于数据简化,因为json你不必要像xml那样写大量的标签,json他就是一个高度集中的数据格式。

那么json的优化,最简单的就是减少书写的内容,比如name的键名改为n,单个字符,或者直接省略,通过数组的方式直接保存内容,这种方式虽然对阅读不友好,但是只要按照一样的规定去写,就可以极大的提高json文件的解析和下载速度。

自定义格式

json虽然很好,但是如果文件内容庞大的话,还是有其他的优化方式,比如自定义的格式,我们可以在一个js文件里面保存一个对象,这个对象保存着自定义的string内容,然后内容之间通过字符分隔,比如不同的内容用:分号隔开,同一个分组的值多个的话用:冒号隔开,然后ajax获取或者动态script获取,由于是一个js文件,所以他没有json的解析步骤,这里就快于json了。

然后通过js的split()方法拆成分组,然后再针对每个组值再次详细拆分获取到需要的内容,最后保存在一个数组内并返回。

事实上split的速度是极快,在大量文本内容上快于json的parse。

缓存

ajax的get方式发出的请求才能被浏览器缓存,但这还不够,服务器还需要发送Expires 过期时间来控制缓存存在多久。

为此我们可以通过创建一个对象来保存获取到的信息,这种方式适用于同一个页面需要请求多次相同的内容。

  • weixiao kaixin tushetou jingkong deyi fanu liezui liuhan daku ganga bishi nanguo lihai qian yiwen numu tu yi haixiu se fadai minyan hehe henkaixin huaji biyiyan kuanghan maimeng shui xiaku penqi zhangzui pen aini ye niu laji ok chigua renshi kongbu shuai xiaoxiese touxiao huaixiao jingnu chihuai kaisang xiaoku koubi zhuangbi lianhong kanbujian shafa zhijing xiangjiao dabian yaowan redjing lazhu rizhi duocang chixigua hejiu xixi xiaopen goukun xiaobuchu shenme wusuowei guancha lajing chouyan xiaochi bie zhadanzui zhadanxiao
  1. 爸爸

    发表于:
    来自 Google Chrome 68 in windows 10

    测试

登录