AJAX的封装
Ajax异步的 JavaScript 和 XML,最大的优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容,通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新。这意味着可以在不重新加载整个网页的情况下,对网页的某部分进行更新。被大量用来实现交互。比较有名的使用网站有Google地图,新浪微博等等。
Ajax基本的语法
Ajax基本语法 首先创建一个xhr对象,第二步调用open ,里面输入两个参数,一个是请求方式,第二个是后端页面名称; 第三步调用send不用输入参数,最后是一个异步函数当状态码readyState等于4时,表示执行完成;
var xhr = new XMLHttpRequest();
xhr.open("GET" , "03_data.php");
xhr.send();
xhr.onreadystatechange = function(){
if(xhr.readyState === 4){
console.log(xhr.responseText);
}
}
<?php
echo '{"a": "aaaaa", "b": "bbb"}';
?>
Ajax的兼容
Ajax存在兼容问题,IE 浏览器使用 ActiveXObject,而其他的浏览器使用名为 XMLHttpRequest 的 JavaScript 内建对象,所以封装一定要考虑兼容问题;
var xhr = null;
if(typeof XMLHttpRequest === "function"){
xhr = new XMLHttpRequest();
}else{
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
xhr.open("GET","./03_data.php");
xhr.send();
xhr.onreadystatechange = function(){
if(xhr.readyState === 4){
console.log("请求成功");
}
}
Ajax带参传递
Ajax携带参数的书写非常的麻烦,需要对url进行多次操作;
var xhr = new XMLHttpRequest();
var name = "aaaa";
var password = "bbbb";
var url = "";
url += "03_data.php";
url += "?";
url += "username=" + name;
url += "&";
url += "password=" + password;
xhr.open("GET" , url);
xhr.send(null);
xhr.onreadystatechange = function(){
if(xhr.readyState === 4){
var res = JSON.parse(xhr.responseText);
console.log(res)
}
}
<?php
$username = $_REQUEST["username"];
$password = $_REQUEST["password"];
echo '{"username":"'.$username.'","password": "'.$password.'"}';
?>
封装
由于ajax的便利性,我们平常使用的可能性很高,所以进行封装是十分有必要的,第一步进行兼容性的简单封装
<?php
echo '{"username":"hello world","password": "world hello"}';
?>
function xhrGet(url , callback){
var xhr = null;
if(typeof XMLHttpRequest === "function"){
xhr = new XMLHttpRequest();
}else{
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
xhr.open("GET",url);
xhr.send(null);
xhr.onreadystatechange = function(){
if(xhr.readyState === 4&& /^2\d{2}$/.test(xhr.status)){
typeof callback === "function" ? callback(xhr.responseText) : "";
}
}
}
xhrGet("./03_data.php",function(res){
console.log(res);
})
对于需要携带的信息我们需要封装一个新的函数来进行组合
function toUrlData(obj ,url){
if(isObject(obj)){
var str = "";
for(var attr in obj){
str += "&" + attr +"="+obj[attr];
}
url += "?" + str;
return url;
}
return url;
}
将需要代入的数据以./03_data.php?”ket”=”value”&”ket1”=”value1”这种形式来进行组合;
var res =toUrlData({
key:"value",
key1:"value1"
},"./03_data.php");
console.log(res)
对数据进行简单封装后我们可以得到更加完善的函数
function isObject( data ){
return (typeof data === "object" && data !== null && data.constructor && data.constructor === Object)
}
function toUrlData(obj ,url){
if(isObject(obj)){
var str = "";
for(var attr in obj){
str += "&" + attr +"="+obj[attr];
}
url += "?" + str;
return url;
}
return url;
}
function xhrGet(url,callback , data){
var xhr = null;
if(typeof XMLHttpRequest === "function"){
xhr = new XMLHttpRequest();
}else{
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
url = toUrlData(data,url);
xhr.open("GET",url);
xhr.send(null);
xhr.onreadystatechange = function(){
if (xhr.readyState === 4 && /^2\d{2}$/.test(xhr.status)){
typeof callback === "function" ? callback(xhr.responseText) : "";
}
}
}
xhrGet( "./03_data.php" , function(res){
console.log(res);
},{
username : "hello",
password : "world"
})
这其中还有不足,因为传递方式不止get一种,还包括post这种方式,他和get又有细微的不同之处,这里我就不过多解释不同了,以下是封装完成的代码供大家参考
function isObject( data ){
return (typeof data === "object" && data !== null && data.constructor && data.constructor === Object)
}
function assign(){
var target = arguments[0];
for(var i = 1 ; i < arguments.length ; i ++){
// console.log(arguments[i]);
for(var attr in arguments[i]){
target[attr] = arguments[i][attr];
}
}
return target;
}
function toUrlData( obj , url , method){
if( isObject(obj) ){
var str = "";
for(var attr in obj){
str += "&" + attr + "=" + obj[attr]
}
str = str.slice(1);
// 如果数据发送方式是POST,那么直接返回str就可以了;
method = method || "";
if( method.toUpperCase() === "POST"){
return str;
}
url += "?" + str;
return url;
}
return url;
}
function ajax( options ){
// 默认参数;
var _default = {
type : "GET",
url : "",
data : null,
// 返回的数据类型;
dataType : "text",
status : null,
success : function(){},
complete : function(){},
error : function(){}
}
// 我们会创建一些默认参数, 如果用户传入了其他数据会对默认参数进行覆盖;
options = assign( _default , options );
options.type = options.type.toLowerCase();
// 如果存在context;
if( isObject(options.context) ){
var callback_list = ["success","complete","error"];
// 如果老版本浏览器更新成for循环;
callback_list.forEach( function( item ){
// console.log(options[item]);
options[item] = options[item].bind( options.context );
})
}
// 1. 创建shr ;
var xhr = null;
if(typeof XMLHttpRequest === "function"){
xhr = new XMLHttpRequest();
}else{
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
// 可以简化;
// 1. 如果请求方式为get,那么我们把数据拼接到url上;
if(options.type === "get"){
options.url = toUrlData( options.data , options.url , options.type)
}
// 2. 如果请求方式为post,那么我们把数据拼接到data上;
if(options.type === "post"){
options.data = toUrlData( options.data , options.url , options.type)
}
// 2. 根据数据进行方法的调用;
xhr.open( options.type , options.url , true ) ;
options.type === "post" ? xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded") : "";
// 3. 调用send方法;
xhr.send( options.type=== "get" ? null : options.data );
// 4. 调用回调函数;
xhr.onreadystatechange = function(){
// xhr程序运行结束;
if( xhr.readyState === 4 ){
options.complete();
if( /^2\d{2}$/.test(xhr.status) ){
// 5.传递数据
// 如果需要转换成json那么我们就返回json,如果不需要原样返回;
// 如果JSON.parse报错了那么我们要调用错误函数;
try{
var res = options.dataType === "json" ? JSON.parse(xhr.responseText) : xhr.responseText;
options.success(res);
}catch(e){
options.error(e,xhr.status);
}
}else{
options.error("error",xhr.status);
}
// 策略模式调用 :
if( isObject(options.status) ){
typeof options.status[xhr.status] === "function" ? options.status[xhr.status]() : "";
}
}
}
}