每次利用AJAX获取同源服务器数据的时候,都需要创建XMLHTTPRequest对象、向服务器发送请求、服务器响应这几步,很多代码是重复的,因此可以考虑将这些封装到一个方法当中去。
封装一个方法,主要考虑:
1、哪些是不变的;
2、哪些是变化的; 通过参数传递的方式实现。
3、如何将结果返回给调用者;(可以通过在调用的时候传入一个方法实现)
4、怎样调用方便。
封装AJAX:
封装一:
myAjax.js
//type:请求类型"get"或"post"
//url:请求的地址
//params:username=zhangsan&age=18 这样的格式
//dataType:请求返回的数据格式
//async:true表示同步,false表示异步
function myAjax(type,url,params,dataType,callback,async){
var xhr = null;
if(window.XMLHttpRequest){
xhr = new XMLHttpRequest();
}else{
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
if(type == "get"){
if(params && params != ""){
url += "?" + params;
}
}
xhr.open(type,url,async);
if(type == "get"){
xhr.send(null);
}else if(type == "post"){
xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xhr.send(params);
}
if(async){
xhr.onreadystatechange = function(){
if(xhr.readyState == 4 && xhr.status == 200){
var result = null;
if(dataType == "json"){
result = xhr.responseText;
result = JSON.parse(result);
}else if(dataType == "xml"){
result = xhr.responseXML;
}else{
result = xhr.responseText;
}
if(callback){
callback(result);
}
}
};
}else{
if(xhr.readyState == 4 && xhr.status == 200){
var result = null;
if(dataType == "json"){
result = xhr.responseText;
result = JSON.parse(result);
}else if(dataType == "xml"){
result = xhr.responseXML;
}else{
result = xhr.responseText;
}
if(callback){
callback(result);
}
}
}
}
案例:
checkUsername.php文件代码
<?php
$username = $_GET["username"];
if($username == "admin"){
echo "username exists";
}else{
echo "username ok";
}
?>
html代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>注册界面</title>
</head>
<body>
<h1>注册界面</h1>
<form action="" method="get">
用户名:<input type="text" name="username" id="username"/>
<input type="button" value="验证用户名" id="btn"/>
<span id="result"></span>
</form>
<script src="myAjax.js"></script>
<script>
var btn = document.getElementById("btn");
btn.onclick = function(){
var username = document.getElementById("username").value;
myAjax("get","checkUsername.php","username=" + username,"text",function(result){
document.getElementById("result").innerHTML = result;
},true);
};
</script>
</body>
</html>
上面的封装使用过程中,会发现两个缺点:
1、参数顺序不可改变
2、参数较多,且参数没有默认值,每次每个参数都必须传递
解决办法:把所有参数用一个对象表示,每一个参数都是这个对象的属性
封装二:
myAjax.js
//type:请求类型"get"或"post"
//url:请求的地址
//data:{username:"zhangsan",age:18} 这样的格式
//dataType:请求返回的数据格式
//async:true表示同步,false表示异步
function myAjax(obj){
var defaults = {
type:"get",
url:"#",
data:{},
dataType:"json",
success:function(result){console.log(result);},
async:true
};
for(var key in obj){
defaults[key] = obj[key];
}
var xhr = null;
if(window.XMLHttpRequest){
xhr = new XMLHttpRequest();
}else{
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
var params = "";
for(var attr in defaults.data){
params += attr+"="+defaults.data[attr]+"&";
}
if(params){
params = params.substring(0,params.length-1);
}
if(defaults.type == "get"){
defaults.url += "?" + params;
}
xhr.open(defaults.type,defaults.url,defaults.async);
if(defaults.type == "get"){
xhr.send(null);
}else if(defaults.type == "post"){
xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xhr.send(params);
}
if(defaults.async){
xhr.onreadystatechange = function(){
if(xhr.readyState == 4 && xhr.status == 200){
var result = null;
if(defaults.dataType == "json"){
result = xhr.responseText;
result = JSON.parse(result);
}else if(defaults.dataType == "xml"){
result = xhr.responseXML;
}else{
result = xhr.responseText;
}
defaults.success(result);
}
};
}else{
if(xhr.readyState == 4 && xhr.status == 200){
var result = null;
if(defaults.dataType == "json"){
result = xhr.responseText;
result = JSON.parse(result);
}else if(defaults.dataType == "xml"){
result = xhr.responseXML;
}else{
result = xhr.responseText;
}
defaults.success(result);
}
}
}
上面方法的参数是一个对象obj,obj中的属性,覆盖到defaults 中的属性:
1、如果有一些属性只存在obj中,会给defaults中增加这个属性;
2、如果有一些属性在obj和defaults中都存在,会将defaults中的默认值覆盖;
3、如果有一些属性只在defaults中存在,在obj中不存在,defaults中的这些属性保留预定义的值。
上面的案例用这个封装的AJAX方法实现:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>注册界面</title>
</head>
<body>
<h1>注册界面</h1>
<form action="" method="get">
用户名:<input type="text" name="username" id="username"/>
<input type="button" value="验证用户名" id="btn">
<span id="result"></span>
</form>
<script src="myAjax2.js"></script>
<script>
var btn = document.getElementById("btn");
btn.onclick = function(){
var username = document.getElementById("username").value;
var obj = {
type:"get",
url:"checkUsername.php",
data:{username:username},
dataType:"text",
success:function(result){
document.getElementById("result").innerHTML = result;
},
async:true
};
myAjax(obj);
};
</script>
</body>
</html>
实现效果是一样的,并且,参数有默认值,所以有的参数可以不传递。