原生的Ajax实现步骤
1.原生js中的构造函数XMLHTTPRequest()构造实例;
考虑兼容问题:if(window.XMLHttpRequest){ var xhr = new XMLHTTPRequest();}else{ var xhr = new ActiveXObject();}复制代码
2.实例化为对象后,要创建一个请求,准备好一个请求的发射窗口状态;
xhr.open("get/post", "请求地址", true);复制代码
3.send方法发出请求,参数是发送的报文体,get方法时报文体为空null,post方法才有内容;
xhr.send(null);复制代码
4.JS中需要监听数据什么时候回来的机制,使用一个事件监听就绪状态,当xhr的状态改变是触发;
xhr.onreadystatechange = function(){ if(xhr.readyState == 4){ //xhr的readyState有5个数值,表示不同状态,4表示接受文件完成,{}内表示接受完成之后执行的操作 document.getElementById().innerHTML = xhr.responseText; }}复制代码
状态的监听要放在创建实例对象和open调用之间,确切的说添加事件应该是第二步,
-
readyState的属性值:
0: 未初始化,此时XMLHTTPRequest对象已经创建,还没有调用open();
1: 已经创建请求,调用open函数,但是还没有调用send发送;
2: 请求已经发送,正在处理中,此时已经接受了response的报文头部;
3: 请求处理中,此时已经接收了部分报文体,response中的部分数据已经可以使用;
4: 响应完成,可以使用报文的全部信息。
-
注意:为了防止缓存(304),调用open时,在第二个参数请求地址后添加一个随机数,保证每次访问的地址不同,避免因为缓存导致请求的文件发生改变,而页面并未随之改变(因为使用了缓存的数据)。
xhr.open("get", "demo/demo.txt?" + Math.random(), true);复制代码
post请求和get请求的区别
xhr.open("post", "请求文件", true);//设置请求头部发送时的文本格式,因为post方法只能通过表单格式发送xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");//send方法中的参数是报文体,而post方法传递是通过报文体,调用send方法传递的参数是以kv对形式的字符串,类似query stringxhr.send("k=v&k=v");复制代码
原生的post是将传递的参数放到send()中以form data形式传递,而原生的get方法是将数据放到第二个参数的路径?后面,以查询字符串的形式传递,这和jQuery的传递方法不同,jQuery中的$.get()和$.post()都是通过第二个参数以json的形式传递到接口页面的。 在接口页面中,比如PHP页面中,获取传递的数据方法
$getdata = $_GET["k值"];$postdata = $_POST["k值"];复制代码
但是通常参数是以json形式传递的,如何将json对象转换为键值对形式的字符串?
var data = { "names": "Tom", "age": 19, "sex": "男"}//封装一个格式转换函数function changeToString(JSON){ var tempArr = []; for(var k in JSON){ //url只允许英文、数字和特殊字符,当有中文或其他国家语言出现时,要通过uri(统一资源标识符)来转换 tempArr.push(k + "=" + encodeURIComponent(JSON[k])); } return temp.join("&");}//调用函数转换格式xhr.send(changeToString(data));复制代码
那么从后台发送来的数据,前端并不知道数据是什么格式,也就不能直接拿来就使用,要先进行判断:
如果负责的后台在接口文件中将数组转换为json对象再发回前端,那么前端只要做判断就可以了。
复制代码
- 判断方法一:使用JSON.parse()方法将字符串转换为json对象,但是有兼容问题存在,IE6,7,8不兼容这个方法。
使用jQuery的get方法$.get("data.php", function(data){ //data是从后台传回的response数据,要先判断是JSON对象还是JSON对象形式的字符串 var dataObj = typeof data == "object" ? data : JSON.parse(data);})复制代码
- 判断方法二:使用eval()方法,没有兼容问题,eval()可以将str变成执行语句,但是转换对象形式的字符串要注意,字符串外面必须加括号。
var dataObj = typeof data == "object" ? data : eval("("+ data +")");复制代码
- 判断方法三:使用内置构造函数Function(), 通过构造函数new的实例立即执行返回json对象。
var dataObj = typeof data == "object" ? data : (new Function("return" + data))();复制代码
构造函数的参数当有多个时,最后一个为执行语句,前面的都是参数,而当只有一个时,这个参数就是执行语句,立即调用执行可以直接返回。
原生的Ajax可能在平时用到并不多,因为有像jQuery这些提供了更方便的方法,但还是要知道是怎样实现的。Ajax另一个重要的概念是跨域的问题,等学完再专门写一篇跨域的小结。