Ajax深入学习笔记

最近在学习ajax,下面整理了一下学习的内容,以便巩固用。
先来看看为什么要用ajax,也就是同步和异步是什么:

同步和异步

同步的意思就是客户端提交表单,发起请求后需要一直等待服务器端的响应,收到服务器端的响应后需要重新载入页面
而有了ajax,则可进行异步交互,比如不会提交整个表单后等待服务器响应再刷新页面,而是填写的过程中,通过ajax的机制,就可以把已经填写的部分提交给服务器,服务器进行处理,而这个过程中可以继续填写后面的内容,服务器发送回响应只会刷新页面的部分内容(利用JavaScript操作DOM进行局部刷新),而不是重新载入整个页面
其实就是为客户机(网页中常为JavaScript)代码提供了一种发送HTTP请求的方式。通常提交请求都是以表单的形式发送,获取响应要刷新整页,而ajax则是按需发送,只刷新返回的数据。

Ajax的基本操作步骤

Ajax指异步的JavaScript和XML,JS无需等待服务器响应,而是在继续执行脚本内容,响应就绪后对响应进行处理。若是同步,则JS代码会收到服务器的响应后再继续执行。
ajax是通过XMLHttpRequest对象在客户端和服务器端进行数据交换的。

1. 创建XMLHttpRequest对象
该对象用于和服务器交换数据:

var xmlhttp;
if (window.XMLHttpRequest)
  {// code for IE7+,Firefox,Chrome,Opera,Safari
  xmlhttp=new XMLHttpRequest();
  }
else
  {// code for IE6,IE5
  xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
  }

2.向服务器发送请求
XHR.open(method,url,async):规定请求的方式、请求文件在服务 器上的URL和是否异步处理请求。启动一个请求以备发送。
XHR.send():将请求发送到服务器,参数为请求主体发送的数据,如果不需要请求主体发送数据,则必须填入null,因为对有些浏览器来说必须有一个参数。通常post方式会填入发送的数据。

3.服务器响应
在收到响应后,响应的数据会自动填充XHR对象的属性
XHR.responseText:服务器返回的文本数据
XHR.responseXML:服务器返回的XML格式的数据
status:服务器返回的状态码。响应的HTTP状态:
- 200: “OK”,响应成功返回
- 304:请求的资源未被修改,可使用浏览器中的缓存版本
- 404: 未找到页面
statusText:HTTP状态文本说明
同步的时候应当检查status的值后来决定下一步的操作:

if(xhr.status>=200 && xhr.status<300 || xhr.status=304){
    //do something
}else{
    alert("request was unsuccessful: "+xhr.status);
}

4.异步处理
onreadystatechange 事件:当async为true时,规定该事件上绑定的方法,每当readyState属性改变时,就会触发该事件。
readyState属性:表示请求-响应过程的当前活动阶段。为XHR对象的状态。异步的时候应当检查该属性。从 0 到 4 发生变化:
0: 请求未初始化,未调用open()
1: 服务器连接已建立,已调用open,未调用send
2: 请求已接收,即服务器已收到请求头信息。 已调用send,尚未收到响应
3: 已收到部分响应数据
4: 请求已完成,已收到全部响应数据,可在客户端使用
注意:需在调用open之前指定onreadystatechange事件绑定的函数才能确保跨浏览器兼容性。

xhr.onreadystatechange=function(){
     if(xhr.readyStatus==4){
        if(xhr.status>=200 && xhr.status<300 ||   xhr.status==304){
        //do something
        }else{
           alert("request was unsuccessful: "+xhr.status);
       }
     }
};

5.终止异步
xhr.abort():调用方法取消异步请求,XHR对象会停止触发事件,并且不再允许访问任何与响应有关的对象属性
在终止请求后,应对XHR对象释放引用。
6.老版本的XHR对象缺点
支持文本数据的传送,无法读取和上传二进制文件
只能访问同域中的资源。
传送和接收数据时没有进度信息,只能提示有无完成。
新版本即level2的改进:
http://www.ruanyifeng.com/blog/2012/09/xmlhttprequest_level_2.html

要想把ajax学得透彻,了解HTTP协议还是很有必要的。

HTTP头部

浏览器在发送XHR请求的同时也会默认发送一些头部信息,浏览器能够显示的字符集(Accept-charset)、当前页面设置的任何Cookie等。也可以自定义发送信息,通过调用XHR.setRequestHeader(header,value)向请求添加头部。该方法应当放在open之后send之前。
XHR对象的getResponseHeader()和getAllResponseHeaders()可用于获取响应的头部信息

1. GET请求
常用于向服务器查询某些信息,可将查询字符串参数追加到url末尾。必须对查询字符串进行encodeURIComponent()编码,具体来说必须对参数名和参数值都进行编码才能附加到url后面。
向现有url追加查询字符串参数:

function addURLPara(url,name,value){
    url += (url.indexOf("?") == -1 ? "?":"&");
    url += encodeURIComponent(name)+"="+encodeURIComponent(value);
    return url;
}

2.POST请求
用于向服务器发送应当被保存的数据(修改服务器端数据),数据是请求的主体。
使用POST方式:
- 无法使用缓存文件(get通常会使用缓存?)
- 向服务器发送大量数据
- 发送包含未知字符的用户输入
在send方法中传入要发送的数据(字符串或文档)
表单数据序列化,通过XHR发送到服务器:

function submitData(){
    var xhr = createXHR();
    xhr.onreadystatechange=function(){
    if(xhr.readyState==4){
         if(xhr.status>=200 && xhr.status<300 || xhr.status==304){
            //do something
         }else{
            alert("request was unsuccessful: "+xhr.status);
         }
        };
    }
    xhr.open("post","url",true);
    xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded"); //表单提交时的内容类型,如果提交的是表单数据必须要写这个 
    var form = document.getElementById("user-info");
    xhr.send(serialize(form));//表单序列化
}

使用该方式必须设置自定义请求头部信息Content-Type,以说明请求的内容类型。这样服务器就会根据请求的内容类型来解析表单中的数据。
在通过post方式请求表单中,在open和send之间,要添加request.setRequestHeader(“Content-Type”,”application/x-www-form-urlencoded”)
如果不设置content-type头部,那么发送给服务器的数据就不会出现在$_POST超级全局变量中。

在来看看新一代的XHR即XHR2级对象又提供了哪些方法吧。

XHR2级对象

1. FormData类型
用于将表单数据序列化和创建和表单格式相同的数据:
方式一:
var data = new FormData();
data.append(“key”,”value”);

方式二:
var data = new FormData(form对象);
以上代码应该在open和send(data)之间。

2. overrideMimeType(“text/xml”)方法
重写服务器返回的MIME类型。强迫XHR对象将响应当做XML而非纯文本来处理

3.超时设定(IE8+支持
XHR对象支持timeout属性和ontimeout事件处理程序。timeout属性用于设置请求等待响应的时间,若超出了则终止请求,然后触发timeout事件,调用ontimeout事件处理程序。
终止请求后readyState属性可能已经为4了,但是如果终止请求后再访问status属性(响应状态码)会报错,因此可将访问该属性代码用try、catch括起来。

那么我们通过XHR对象传递的数据都有哪些格式呢?下面再来看看常用的几种数据格式。

传送的数据格式

1.XML

XML是一种数据格式,在异步应用程序中常有以下两种用法
一是以XML格式从网页发送HTTP请求给服务器
二是以XML格式在网页中接收服务器的响应

客户端发送请求
XML格式的请求和响应比普通文本慢,消耗内存更多,因为要添加标签和语义。
将数据包装为XML格式其实也是使用字符串的形式,不过字符串中有相应的标签。即发送的数据都必须是文本。
以XML格式化数据时应先设置请求头部:
xhr.setRequestHeader(“Content-type”,”text/xml”)。若果是发送普通文本则类型为text/plain
最好是使用普通文本的方式发送请求数据。
发送文本格式的请求(名/值对)和发送XML格式包装后的数据例子讲解:http://www.ibm.com/developerworks/cn/xml/wa-ajaxintro7.html
服务器发送响应
比较适合用XML格式的数据,原因是若发送的响应为文本,其中包含多个名称/值对,服务器程序用某种符号连接这些对儿(没有一个标准),而客户端必须采取措施将这些响应文本(字符串)中的对儿依次解析出来。(而服务器端技术提供了多种方法来根据名称获取值,所以客户端发送请求时适合用名称/值对这种方式)。
XML响应可以是以XML格式化的纯文本,客户端中通过xhr.responseText属性获取,这时仍出现了需要解析字符串的问题,所以不应该以这种方式来发送XML响应。应当使用XML文档,客户端可通过xhr.responseXML获取,将该文档当成一个DOM Document对象,在客户端可以利用DOM来解析该文档。

2. json

**json基本概念和格式

当需要在客户端和服务器端之间传递大量数据时,使用Jason格式的数据会很灵活,便于解析。
Json是一种存储和交换文本信息的语法,采用键值对方式组织。Json是独立于语言的,可被任何语言解析和生成
json和XML相比有这样一些优点:
长度短小,读写速度更快;可以使用JavaScript内建的方法进行解析,也可以直接转换成JavaScript对象,非常方便。
json数据的书写格式为名称-值这样的对儿:

"name":value

注意名称有引号,当value为字符串时也应该加引号。
value的数据类型可为:

  • 数字
  • 字符串
  • 布尔值
  • 数组(在[]中)
  • 对象(在{}中)
  • null
    举一个json文件的例子:
{
   "staff":[ {"name":"anna","age":20},{"name":"mike","age":10},{"name":"lily","age":30} ] }

最外层的大括号{}表示这是一个json对象。

**在JS中解析json
通过下述几种方式可以把一个json字符串解析为一个JavaScript对象。

(1)使用eval()解析
可以浏览器控制台中进行如下代码测验:

var jsondata='{"staff":[{"name":"anna","age":20},{"name":"mike","age":10},{"name":"lily","age":30}]}'; //注意这个json字符串要放到同一行;服务器端的返回的数据应该写成这样一个json对象字符串
var jsonobj=eval('('+jsondata+')'); //eval使用这种方式解析
alert(jsonobj.staff[0].name);

采用eval,不仅会解析成一个JavaScript对象,还会执行json字符串中的方法,例如把”age”:20改为”age”:alert(“hello”),则会执行这个alert语句。

(2)使用JSON.parse()解析

var jsonobj=JSON.parse(jsondata);

使用这种方式解析不会执行json字符串中的方法,会报错,json字符串语法不合法。

由于eval方法不会检查语法,这样很危险,如果接收的json数据中包含恶意代码会被执行。

检查json语法的格式化校验在线工具:jsonlint.com

readyStateChange事件补充说明

该事件的作用是提供了与文档或元素的加载状态有关的信息。支持该事件的对象都有一个readyState属性。该属性有如下几个值:
uninitialized(未初始化):对象存在但尚未初始化
loading(正在加载):对象正在加载数据
loaded:对象加载数据完成
interactive:可以操作对象了,但韩没有完全加载
complete:对象已经加载完毕
并非所有的对象都会经历这几个阶段。

jQuery中的Ajax

jQuery提供了三个层次的ajax方法,位于最底层的$.ajax()、第二层的$.load()、$.get()、$.post(),以及第三层的$.getScript()、$.getJson()。
先来说明第二层的方法

1. $(‘selector’).load(url,data,function)方法
这个方法可以远程加载HTML代码并插入选中的DOM结点中。
其中data为object类型。
无论ajax请求有没有成功,请求完成后都会触发回调函数,该函数有三个参数:responseText,textStatus(sucsess,error,notmodified,timeout中的一种),XMLHttpRequest。
如果只需加载html文档中的部分元素,可在url后面传入选择器参数(第一个空格后的为选择器),指定要加载的部分:

$('#result').load('ajax/test.html #container');

调用方式为:$ele.load(url,function)即可将响应的html片段写入ele元素中。

回调函数会在HTML 已经被插入完时被调用,在每个匹配的元素上被调用一次,并且 this始终指向当前正在处理的 DOM 元素。

默认使用 GET 方式 , 如果data参数提供一个对象,那么使用 POST 方式。

2.$.get(url,function,type)和$.post()
这两个方法是全局函数,而非某个jQuery对象的函数。load方法常用于加载静态数据文件,如果要向服务器传递参数可以用这两个方法
其中data为object类型,type为期待服务器返回的数据类型(html,xml等);回调函数只有请求成功即textStatus为success时才调用函数包括两个参数:data,textStatus。data为返回的数据,可以为xml文档、json文件、html片段等。
例子:

<form id="form1" action="#">
<p>评论:</p>
 <p>姓名: <input type="text" name="username" id="username" /></p>
 <p>内容: <textarea name="content" id="content" rows="2" cols="20"></textarea></p>
 <p><input type="button" id="send" value="提交"/></p>
</form>
<div class='comment'>已有评论</div>
<div id="resText" >
</div>

//JS代码<script> $(function(){ $("#send").click(function(){ $.get("get1.PHP",{username:$('#username').val(),content:$('#content').val()},function(data){ $("#resText").html(data); }); }) }); </script>

当返回数据为XML文档时,可以像解析html文档一样解析其中的元素,先用$(data)将返回文档变成一个jQuery对象(data就相当于html DOM树中的document结点),然后可以使用jQuery中的相关方法获取到树中结点的值,再构造成html格式的字符串然后通过html()方法写入网页中。
当返回数据问json文件时,data就是一个可被JavaScript直接使用的数据,如果是一个对象,可直接使用data.proptertyname获取其中属性值,如果data是数组,则可通过data[index]访问其中的元素。

post方法与get结构相同,其区别有一下几个:
get是将参数附着在url后传递,而post则是作为请求的主体来传送。用get传递的数据会被浏览器缓存起来,不太安全。

3. $.getScript(url,[callback])和$.getJson(url,[data],[callback])

$.getScript用来加载JavaScript文件(有时候没有必要一次性加载完所有js文件,需要的时候再加载)。加载完后会自动执行。
回调函数会在成功加载js文件后执行

$.getJson用于加载json文件,和$.getScript的函数结构一样。补充一点就是回调函数的参数data是获取到的Json文件对象。可使用全局方法$.each(data,function(index/key,ele/value))来遍历集合data(可为数组或对象)中的元素。

4. $ajax()
例子:

$("#save").click(function(){
        $.ajax({
            type:"POST",url:"serverjson.PHP",data:{          //传送给服务器的数据
                name:$("#staffName").val(),number:$("#staffNumber").val(),sex:$("#staffSex").val(),job:$("#staffJob").val()
            },dataType:"json",//期望服务器发送会的数据格式
            //请求成功的回调函数,data为返回的数据
            success:function(data){   
                if(data.success){
                    $("#createResult").html(data.msg);
                }else{
                    $("#createResult").html("出现错误:"+data.msg);
                }
            },//请求失败的回调函数,参数为XHR对象
            error:function(jqXHR){
                alert("发生错误:"+jqXHR.status);
            }
        })
    })

所有jQuery的Ajax方法都返回一个XMLHTTPRequest对象的超集,
Ajax入门讲解:http://mrthink.net/ajax-starter-xmlhttpreq/

相关文章

JS原生Ajax操作(XMLHttpRequest) GET请求 POST请求 兼容性问题 利用iframe模拟ajax 实现表单提交的返回...
AJAX 每日更新前端基础,如果觉得不错,点个star吧 &#128515; https://github.com/WindrunnerMax/E...
踩坑Axios提交form表单几种格式 前后端分离的开发前后端, 前端使用的vue,后端的安全模块使用的SpringSe...
很早就听闻ajax的名声,但是却一直不知道怎么用,今天自己捣鼓了一下,竟然会用了,哈哈哈哈。 为了防止...
需要在服务器上进行哈 jquery的ajax方法: // jquery请求 $.ajax({ url: &quot;./server/slider.js...
Ajax函数封装ajax.js // Get / Post // 参数 get post // 是否异步 // 如何处理响应数据 // URL // var...