原生的Ajax实现

2,492

原生的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 string
xhr.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对象再发回前端,那么前端只要做判断就可以了。

<?php
	//header('Content-type: application/json');
	$arr = array(...);
	
	//json_encode将数组变为json对象形式
	echo json_encode($arr);
?>
  • 判断方法一:使用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另一个重要的概念是跨域的问题,等学完再专门写一篇跨域的小结。