Ajax技術(shù)核心是XMLHttpRequest對(duì)象(簡稱XHR)
ajax的使用能夠以異步的方式從服務(wù)器獲取信息,意味著用戶單擊后,可以不必刷新頁面也能取得新數(shù)據(jù)。
為保證瀏覽器對(duì)XHR的支持,使用以下方法
var xmlhttp;
if (window.XMLHttpRequest)
{
// IE7+, Firefox, Chrome, Opera, Safari 瀏覽器執(zhí)行代碼
xmlhttp=new XMLHttpRequest();
}
else
{
// IE6, IE5 瀏覽器執(zhí)行代碼
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
總的來說,我們只是使用了xhr方法來實(shí)現(xiàn)向服務(wù)端發(fā)請求,獲取返回?cái)?shù)據(jù),在實(shí)現(xiàn)頁面上的局部刷新,更改數(shù)據(jù)。
這里我們主要研究下,如何用原生js封裝一個(gè)類似jquery的ajax請求,具體的ajax細(xì)節(jié)方法,大家可以在網(wǎng)上查詢,或者高程三上講解的很詳細(xì)
//toData方法是將data傳入的數(shù)據(jù)取到并且拼接,為拼到URL上做準(zhǔn)備
function toData(obj){
if (obj == null){
return obj;
}
var arr = [];
for (var i in obj){
var str = i+"="+obj[i];
arr.push(str);
}
return arr.join("&");
}
function ajax(opts){
//創(chuàng)建ajax對(duì)象,以及一系列需要的參數(shù)
var xhr = null,
abortTimeout = null,
empty = function(){},
ajax_url = "",
opts = {
type : ( opts.type && opts.type.toUpperCase() ) || "GET",
url : opts.url || "",
data : opts.data || "",
dataType : opts.dataType || "json",
success : opts.success || empty,
err :opts.error || empty,
timeout : opts.timeout || 30000 //默認(rèn)超時(shí)時(shí)間: 30s
};
//判斷瀏覽器是否有xhr
if (window.XMLHttpRequest){
xhr = new XMLHttpRequest();
}
else{
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
//處理傳入的參數(shù)
opts.data = toData(opts.data);
//通過請求方式不同,來拼接URL
if(opts.type == "GET"){
if(opts.url.indexOf("?")>-1){
if(opts.data == ""){
ajax_url = opts.url;
}else{
ajax_url = opts.url + "&" +opts.data;
}
}else{
ajax_url = opts.url + "?" + opts.data;
}
xhr.open('GET',ajax_url,true);
xhr.send();
}else(opts.type == "POST") {
xhr.open('POST',opts.url,true);
//如果需要像html表單那樣post數(shù)據(jù),需要設(shè)置http頭
xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xhr.send(opts.data);
}
//處理返回的數(shù)據(jù)
xhr.onreadystatechange = function(){
/*
** 每當(dāng)readyState改變時(shí),就會(huì)觸發(fā)onreadystatechange事件
** readyState屬性存儲(chǔ)有XMLHttpRequest的狀態(tài)信息
** 0 :請求未初始化
** 1 :服務(wù)器連接已建立
** 2 :請求已接受
** 3 : 請求處理中
** 4 :請求已完成,且相應(yīng)就緒
*/
if(xhr.readyState == 4){
var res,
error;
xhr.onreadystatechange = empty;
clearTimeout(abortTimeout);
if((xhr.status >= 200 && xhr.status < 300) ||xhr.status ==304){
res = xhr.responseText;
try{
if(opts.type == "GET"){
if(opts.dataType == "json"){
res = JSON.parse(xhr.responseText);
}else if(opts.dataType == "script") {
eval(res);
}else if(opts.dataType == "xml"){
res = xhr.responseXML;
}
}
}catch(e) {
error = e;
}
if(error){
opts.error(error,'parsererror',xhr);
}else{
opts.success(res);
}
}else{
opts.error(xhr.statusText || 'unknown' ,'status:' +xhr.status,xhr);
}
}
};
if(opts.timeout > 0){
xhr.ontimeout = function(){
opts.error('Request.timeout','timeout',xhr);
}
}
return xhr;
}
module.exports = ajax;
下面我們將調(diào)用這個(gè)封裝的ajax請求
ajax({
url : url,
dataType : 'json',
data : {
"param1" : "111",
"param2" : "222"
},
success: function(result){
console.log(result);
},
timeout: 30000,
error : function(error,type,xhr){
console.log("error" : error,"type:",type,"xhr:",xhr);
}
});