Ajax初探(中)

上文,我们了解了网络世界是如何交换信息的,用什么方式去交互信息(http),HTTP请求过程是如何实现的,什么是http请求,什么是http响应,说了那么多,好像还没说到Ajax,不要急,下面我们就来实战Ajax。

本文梗概:

Ajax实现的核心对象

  1. 牛刀小试——向服务器发送Ajax请求
  2. 更进一步——获取服务器返回的数据
  3. 开始入门——了解异步与同步
  4. 再说POST——发送POST请求
  5. Ajax总结

Ajax实现的核心对象

Ajax即“Asynchronous Javascript And XML”(异步JavaScript和XML),实际上跟XML没多大关系,XML只是Ajax传输的一种数据形式,也可以是JSON。实现它需要用到javascript中的一个对象 XMLHttpRequest,简称XHR对象。

1. 牛刀小试——向服务器发送Ajax请求

PHP页面的准备
要学习Ajax,就需要和PHP打交道,在后台接收我们发送的请求,下面写两句PHP代码,用来接收我们发送的Ajax请求

    <?php
      header("Content-type:text/html;charset=utf-8");
          if(!empty($_GET)){
            echo '你的数据我已经接收到了,祝你生活愉快';
          }
    ?>

把这个页面另存为server.php即可。


Javascript代码的准备

    window.onload = {
        document.onclick = function (){
          var xhr = new XMLHttpRequest();        //创建XHR对象
          xhr.open('get','server.php',false);        
          xhr.send(null);
  }
}

XHR对象有一个open方法,这个方法用于启动一个请求,以备发送。此方法有两个必须的参数:
a. 第一个是指定请求方式,get还是post[此参数大小写不敏感]
b. 第二个是发送请求的url,就是你要发送请求的那个页面
c. 这里指定的第三个参数为发送异步请求还是同步请求,默认为true,异步请求。

XHR对象的send方法则是将请求数据发送到服务器上,其参数有以下规定:
a. 如果使用GET方法,则参数为null,因为GET方法使用url传参。
b. 如果使用POST方法,则参数为要发送的数据。


把html页面和server.php服务器脚本丢到本地服务器中去测试 | php本地服务器如何搭建?

使用浏览器打开你的HTML页面,注意要在本地服务器打开。然后打开开发者工具查看请求。刷新一下,就能看到面板上有一个HTML文件,点击一下页面,就可以看到一个请求发送到了服务器

Paste_Image.png
2. 更进一步——获取服务器返回的数据

请求已经发送给服务器了,如无意外,服务器很快就可以给我们作出响应并返回数据了,那如何获取服务器返回的数据呢?
使用XHR对象的responseText属性
只有在send方法后面加上下面这段代码就可以获得响应数据了。

alert(xhr.responseText);

但是实际上我们不一定都能够成功地把请求发送到服务器的,所以必须要进行判断才能使用服务器的响应数据,怎么判断?使用http状态码。
如果服务器成功接收请求,那么就会给客户端返回一个200状态码,表示已经成功接收请求,所请求的和响应头信息和数据随即返回。
如果我们发送请求的地址错误了,那么服务器就会返回一个404状态码,表示所请求资源不存在。所以在获取响应数据之前做一下判断处理可以增强用户体验

   if(xhr.status == 200){
     alert(xhr.responseText);
}else if(xhr.status == 400){
     alert('你所请求的资源不存在');
}

——但是返回的为什么是空的呢?因为我们的请求的数据都没有发送!
刚刚说了,GET方法使用url传参,那么我们在设置url的时候应该设置我们的参数
所以我们应该这样设置open方法

open('get','server.php?123',false);
//向服务器发送123这个字符串

设置之后就能功能打印出服务器返回的数据 "你的数据已经接收,祝你生活愉快",这就是简单的客户端与服务器端的交互。
这种交互是实时的,也就是说你在服务器改动数据,客户端无需刷新,依旧能得到服务器端的最新数据。(不信你自己改改那个字符串)。
但是在IE浏览器和火狐浏览器上,却不能。原因是这些浏览器默认使用了缓存数据,当我们再次发送请求的时候,浏览器不会重新从服务器上下载数据,而是使用本地缓存的数据,所以我们应该在url上加上一个生成随机数的js函数,让提交的请求url每次都不一样,浏览器就不会使用缓存数据了。

open('get','server.php?rand='+Math.random(),false);
3. 开始入门——了解异步与同步

Ajax真容易,就这样就实现了?并不是!Ajax的精妙在于异步。那什么是同步,什么是异步呢?
解决这个问题,先做一个小小的实验先。
在server.php文件中加上一个行代码

    <?php
      header("Content-type:text/html;charset=utf-8");
       sleep(5);    //加上这句
          if(!empty($_GET)){
            echo '你的数据我已经接收到了,祝你生活愉快';
          }
    ?>

然后在HTML页面上触发请求。
是不是要等5秒,提示才能弹出来?那是因为5秒后,服务器才给你返回响应数据,刚才那个代码是让服务器睡眠5秒,再执行代码。

这个睡眠5秒有什么用?
因为在天朝,上网的速度大家都明白,很多时候打开一个网站如果网络有延迟的话,可能要等待几秒才能打开,所以这个睡眠5秒其实就是模拟网络延迟。

先把sleep(5)注释掉,点击HTML页面5次,连续弹出5个提示,如果不注释那句代码,连续点击HTML页面5次,会发生什么事?很显然,需要等待25秒才能把提示全部弹出来。所以,同步[此例open方法设置同步] 请求需要等待服务器端响应后才能发起第二次请求,这个等待服务器响应的过程,客户端是什么都不能干的,甚至会出现浏览器假死的状况(卡住)


同步用户体验糟糕透了,所以一般都不会使用同步请求,那异步请求又是怎么的?
其实很简单,只需要把open方法的false,改为true就可以了!

但是我们可以发现改了之后,点击页面一次,HTML页面输出的是第一次是空字符串,第二次才是响应数据,第三次还是响应数据,这是为什么?

因为对于异步请求,浏览器将数据传输交给浏览器后台处理,我们发送了请求,就马上打印输出数据,当然为空,要等到浏览器把数据完全接收完数据才能够打印输出。而同步之所以能够打印输出,是因为它本来就必须等到客户端完全接收数据才能够对数据进行处理,期间不能进行任何操作,而异步在接收数据的同时,是可以进行其他操作的,比如说,我们在等待响应的同时,可以继续发送请求。
简单的总结就是:

同步请求必须等到服务器器完全响应了才能发起下一次请求
异步请求在客户端等待服务器响应的同时就可以发起下一次请求
5个同步请求完成需要25秒,5个异步请求完成,大概只需要6、7秒。

还有一个问题没有解决,为什么会弹出多次?
因为对于异步请求,浏览器会有一个就绪状态,表明数据接收的状态。一般我们使用就绪状态事件监听函数来捕获这些状态信息,再对数据进行处理。

        window.onload = {
        document.onclick = function (){
          var xhr = new XMLHttpRequest();        //创建XHR对象
          xhr.onreadystatechange = function (){
              alert(xhr.readyState+'\n'+xhr.responseText);
        }
          xhr.open('get','server.php?rand='+Math.random()+'&num=123',true);        
          xhr.send(null);
  }

从上面的例子可以看出来,当readyState属性的值为3和4的时候,才能接收到服务器的数据。
readystate是指客户端在接收http响应数据的时候的状态

0表示XHR对象尚未建立
1表示尚未调用open方法
2表示已经调用open方法,但是还未调用send方法发送
3.表示已经调用send方法,但是返回的数据还不完整,尚且不能使用
4.表示已经接收数据完毕,数据已经可以使用。

所以正确使用异步请求的正确姿势,应该是这样的

  window.onload = {
        document.onclick = function (){
          var xhr = new XMLHttpRequest();        //创建XHR对象
          xhr.onreadystatechange = function (){
              if(xhr.readystatechange == 4  && xhr.status == 200){
                      alert(responseText);
                }
           }
          xhr.open('get','server.php?rand='+Math.random()+'&num=123',true);        
          xhr.send(null);
  }

4. 再说POST——发送POST请求

上面一直都是使用GET方式发送请求,怎么样发送POST方式请求呢?
先看代码

  window.onload = {
        document.onclick = function (){
          var xhr = new XMLHttpRequest();        //创建XHR对象
          xhr.onreadystatechange = function (){
              if(xhr.readystatechange == 4  && xhr.status == 200){
                      alert(responseText);
                }
           }
          xhr.open('post','server.php?rand='+Math.random(),true); 
            //第一处改动,将get设置为post   
          xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');    
          // 第二处改动,设置了请求头
          xhr.send('name=123');
          //第三处改动,send方法参数添加数据。
  }

对于第二处的解析:
服务器对于POST请求的解析方式和web表单提交是不同的所以,需要模拟表单进行提交。[此处搞得不太明白。]

对于第三处的解析:
POST方法提交数据是模拟表单的形式发送的,所以需要使用键值对的方式提交服务器端才能接收。

POST请求的优点与缺点:
优点:

  1. 数据大小无限制,GET请求适合在服务器端查询获取数据,而POST请求适合发送数据
  2. 数据被存放在实体中,不直接暴露在外,较GET方法安全。

缺点:

  1. 性能上没有GET方法快,因为服务器要对POST请求做特殊的处理。
5. Ajax总结

GET请求:

  1. 新建XHR对象
  2. 使用open方法启动请求,以备发送
  3. 使用就绪状态监听函数,当数据完全接收的时候,触发函数,获取响应数据
  4. 使用send方法发送请求,参数为null

[疑问:为什么就绪状态监听函数要写在sen方法前面呢?实际上写在后面也是可以的,但是写在前面表示先把这个方法载入内存,触发时调用,是个好习惯]

POST请求:

  1. 新建XHR对象
  2. 使用open方法启动请求,以备发送
  3. 设置http头信息的Content-Type类型,模拟表单发送
  4. 使用就绪状态监听函数,当数据完全接收的时候,触发函数,获取响应数据
  5. 使用send方法发送请求,参数为要发送的数据

写了那么多好像发现文字真的是太苍白了,就算是我自己也会直接看教程而不是看这些无聊而神烦的文字,哈哈,算了,当自己总结好了……下次尽量精简一些

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,362评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,330评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,247评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,560评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,580评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,569评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,929评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,587评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,840评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,596评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,678评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,366评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,945评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,929评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,165评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,271评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,403评论 2 342

推荐阅读更多精彩内容