這篇文章主要介紹原生JS如何發(fā)送異步數(shù)據(jù)請求,文中介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們一定要看完!

成都創(chuàng)新互聯(lián)公司成立與2013年,是專業(yè)互聯(lián)網(wǎng)技術(shù)服務公司,擁有項目成都網(wǎng)站制作、成都做網(wǎng)站網(wǎng)站策劃,項目實施與項目整合能力。我們以讓每一個夢想脫穎而出為使命,1280元哈爾濱做網(wǎng)站,已為上家服務,為哈爾濱各地企業(yè)和個人服務,聯(lián)系電話:13518219792
在做項目的時候,有時候需要用到異步數(shù)據(jù)請求,但是如果這個時候沒有框架的依賴,就需要用到原生JS進行異步數(shù)據(jù)請求。這時候無非有兩種請求方式,一種是AJAX,另一個是JSONP。通過原生JS對異步請求進行簡單的封裝。
AJAX
AJAX是一種數(shù)據(jù)請求方式,不需要刷新整個頁面就能夠更新局部頁面的數(shù)據(jù)。AJAX的技術(shù)核心是XMLHttpRequest對象,主要請求過程如下:
創(chuàng)建XMLHttpRequest對象(new)
連接服務器(open)
發(fā)送請求(send)
接收響應數(shù)據(jù)(onreadystatechange)
不說話直接貼代碼
/**
* 通過JSON的方式請求
* @param {[type]} params [description]
* @return {[type]} [description]
*/
ajaxJSON(params) {
params.type = (params.type || 'GET').toUpperCase();
params.data = params.data || {};
var formatedParams = this.formateParams(params.data, params.cache);
var xhr;
//創(chuàng)建XMLHttpRequest對象
if (window.XMLHttpRequest) {
//非IE6
xhr = new XMLHttpRequest();
} else {
xhr = new ActiveXObject('Microsoft.XMLHTTP');
}
//異步狀態(tài)發(fā)生改變,接收響應數(shù)據(jù)
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
if (!!params.success) {
if (typeof xhr.responseText == 'string') {
params.success(JSON.parse(xhr.responseText));
} else {
params.success(xhr.responseText);
}
}
} else {
params.error && params.error(status);
}
}
if (params.type == 'GET') {
//連接服務器
xhr.open('GET', (!!formatedParams ? params.url + '?' + formatedParams : params.url), true);
//發(fā)送請求
xhr.send();
} else {
//連接服務器
xhr.open('POST', params.url, true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
//發(fā)送請求
xhr.send(formatedParams);
}
},
/**
* 格式化數(shù)據(jù)
* @param {Obj} data 需要格式化的數(shù)據(jù)
* @param {Boolean} isCache 是否加入隨機參數(shù)
* @return {String} 返回的字符串
*/
formateParams: function(data, isCache) {
var arr = [];
for (var name in data) {
arr.push(encodeURIComponent(name) + '=' + encodeURIComponent(data[name]));
}
if (isCache) {
arr.push('v=' + (new Date()).getTime());
}
return arr.join('&');
}IE7及其以上版本中支持原生的 XHR 對象,因此可以直接用:var oAjax = new XMLHttpRequest();。IE6及其之前的版本中,XHR對象是通過MSXML庫中的一個ActiveXObject對象實現(xiàn)的。
通過xhr的open函數(shù)來連接服務器,主要接收三個參數(shù):請求方式、請求地址和是否異步請求(一般都是異步請求)。請求方式有兩種,GET和POST,GET是通過URL將數(shù)據(jù)提交到服務器的,POST則是通過將數(shù)據(jù)作為send方法的參數(shù)發(fā)送到服務器。
給xhr綁定狀態(tài)改變函數(shù)onreadystatechange,主要用來檢測xhr的readyState的變化,當異步發(fā)送成功后,readyState的數(shù)值會由0變成4,同時觸發(fā)onreadystatechange事件。readyState的屬性及對應狀態(tài)如下:
0 (未初始化) 對象已建立,但是尚未初始化(尚未調(diào)用open方法)
1 (初始化) 對象已建立,尚未調(diào)用send方法
2 (發(fā)送數(shù)據(jù)) send方法已調(diào)用,但是當前的狀態(tài)及http頭未知
3 (數(shù)據(jù)傳送中) 已接收部分數(shù)據(jù),因為響應及http頭不全,這時通過responseBody和responseText獲取部分數(shù)據(jù)會出現(xiàn)錯誤
4 (完成) 數(shù)據(jù)接收完畢,此時可以通過通過responseBody和responseText獲取完整的回應數(shù)據(jù)
在readystatechange事件中,先判斷響應是否接收完成,然后判斷服務器是否成功處理請求,xhr.status 是狀態(tài)碼,狀態(tài)碼以2開頭的都是成功,304表示從緩存中獲取,上面的代碼在每次請求的時候都加入了隨機數(shù),所以不會從緩存中取值,故該狀態(tài)不需判斷。
JSONP
如果還是用上面的XMLHttpRequest對象來發(fā)送需要跨域的請求,雖然調(diào)用了send函數(shù),但是xhr的狀態(tài)一直都是0,也不會觸發(fā)onreadystatechange事件,這個時候就要用到JSONP的請求方式了。
JSONP(JSON with Padding) 是一種跨域請求方式。主要原理是利用了script標簽可以跨域請求的特點,由其src屬性發(fā)送請求到服務器,服務器返回js代碼,網(wǎng)頁端接受響應,然后就直接執(zhí)行了,這和通過script標簽引用外部文件的原理是一樣的。
JSONP由兩部分組成:回調(diào)函數(shù)和數(shù)據(jù),回調(diào)函數(shù)一般是由網(wǎng)頁端控制,作為參數(shù)發(fā)往服務器端,服務器端把該函數(shù)和數(shù)據(jù)拼成字符串返回。
比如網(wǎng)頁端創(chuàng)建一個script標簽,并給其src賦值為http://www.test.com/json/?callback=process, 此時網(wǎng)頁端就發(fā)起一個請求。服務端將要返回的數(shù)據(jù)拼作為函數(shù)的參數(shù)傳入,服務端返回的數(shù)據(jù)格式類似”process({‘name:'xieyufei'})”,網(wǎng)頁端接收到了響應值,因為請求者是 script,所以相當于直接調(diào)用process方法,并且傳入了一個參數(shù)。
不說話直接貼代碼。
/**
* 通過JSONP的方式請求
* @param {[type]} params [description]
* @return {[type]} [description]
*/
ajaxJSONP(params) {
params.data = params.data || {};
params.jsonp = params.jsonp || 'callback';
// 設置傳遞給后臺的回調(diào)參數(shù)名和參數(shù)值
var callbackName = 'jsonp_' + (new Date()).getTime();
params.data[params.jsonp] = callbackName;
var formatedParams = this.formateParams(params.data, params.cache);
//創(chuàng)建script標簽并插入到頁面中
var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
head.appendChild(script);
//創(chuàng)建jsonp回調(diào)函數(shù)
window[callbackName] = function(json) {
head.removeChild(script);
clearTimeout(script.timer);
window[callbackName] = null;
params.success && params.success(json);
};
//發(fā)送請求
script.src = (!!formatedParams ? params.url + '?' + formatedParams : params.url);
//為了得知此次請求是否成功,設置超時處理
if (params.time) {
script.timer = setTimeout(function() {
window[callbackName] = null;
head.removeChild(script);
params.error && params.error({
message: '超時'
});
}, params.time);
}
}給script標簽設置src屬性時瀏覽器就會去發(fā)送請求,但是只能發(fā)送一次請求,導致script標簽不能復用,因此每次操作完都需要把script標簽移除。在瀏覽器發(fā)送請求之前給全局綁定一個回調(diào)函數(shù),當數(shù)據(jù)請求成功時就會調(diào)用這個回調(diào)函數(shù)。
總結(jié)
將兩種發(fā)送異步數(shù)據(jù)的方式整合起來,根據(jù)dataType來進行判斷選用哪種方式。貼上完整的代碼
var xyfAjax = {
ajax: function(params) {
params = params || {};
params.cache = params.cache || false;
if (!params.url) {
throw new Error('參數(shù)不合法');
}
params.dataType = (params.dataType || 'json').toLowerCase();
if (params.dataType == 'jsonp') {
this.ajaxJSONP(params);
} else if (params.dataType == 'json') {
this.ajaxJSON(params);
}
},
/**
* 通過JSONP的方式請求
* @param {[type]} params [description]
* @return {[type]} [description]
*/
ajaxJSONP(params) {
params.data = params.data || {};
params.jsonp = params.jsonp || 'callback';
// 設置傳遞給后臺的回調(diào)參數(shù)名和參數(shù)值
var callbackName = 'jsonp_' + (new Date()).getTime();
params.data[params.jsonp] = callbackName;
var formatedParams = this.formateParams(params.data, params.cache);
//創(chuàng)建script標簽并插入到頁面中
var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
head.appendChild(script);
//創(chuàng)建jsonp回調(diào)函數(shù)
window[callbackName] = function(json) {
head.removeChild(script);
clearTimeout(script.timer);
window[callbackName] = null;
params.success && params.success(json);
};
//發(fā)送請求
script.src = (!!formatedParams ? params.url + '?' + formatedParams : params.url);
//為了得知此次請求是否成功,設置超時處理
if (params.time) {
script.timer = setTimeout(function() {
window[callbackName] = null;
head.removeChild(script);
params.error && params.error({
message: '超時'
});
}, params.time);
}
},
/**
* 通過JSON的方式請求
* @param {[type]} params [description]
* @return {[type]} [description]
*/
ajaxJSON(params) {
params.type = (params.type || 'GET').toUpperCase();
params.data = params.data || {};
var formatedParams = this.formateParams(params.data, params.cache);
var xhr;
//創(chuàng)建XMLHttpRequest對象
if (window.XMLHttpRequest) {
//非IE6
xhr = new XMLHttpRequest();
} else {
xhr = new ActiveXObject('Microsoft.XMLHTTP');
}
//異步狀態(tài)發(fā)生改變,接收響應數(shù)據(jù)
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
if (!!params.success) {
if (typeof xhr.responseText == 'string') {
params.success(JSON.parse(xhr.responseText));
} else {
params.success(xhr.responseText);
}
}
} else {
params.error && params.error(status);
}
}
if (params.type == 'GET') {
//連接服務器
xhr.open('GET', (!!formatedParams ? params.url + '?' + formatedParams : params.url), true);
//發(fā)送請求
xhr.send(null);
} else {
//連接服務器
xhr.open('POST', params.url, true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
//發(fā)送請求
xhr.send(formatedParams);
}
},
/**
* 格式化數(shù)據(jù)
* @param {Obj} data 需要格式化的數(shù)據(jù)
* @param {Boolean} isCache 是否加入隨機參數(shù)
* @return {String} 返回的字符串
*/
formateParams: function(data, isCache) {
var arr = [];
for (var name in data) {
arr.push(encodeURIComponent(name) + '=' + encodeURIComponent(data[name]));
}
if (isCache) {
arr.push('v=' + (new Date()).getTime());
}
return arr.join('&');
}
}
xyfAjax.ajax({
url:'http://www.xieyufei.com',
type:'get', //or post
dataType:'json', //or jsonp
data:{
name:'xyf'
},
success: function(data){
console.log(data)
}
})以上是“原生JS如何發(fā)送異步數(shù)據(jù)請求”這篇文章的所有內(nèi)容,感謝各位的閱讀!希望分享的內(nèi)容對大家有幫助,更多相關(guān)知識,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道!
網(wǎng)站標題:原生JS如何發(fā)送異步數(shù)據(jù)請求
文章來源:http://chinadenli.net/article14/gossge.html
成都網(wǎng)站建設公司_創(chuàng)新互聯(lián),為您提供App開發(fā)、手機網(wǎng)站建設、關(guān)鍵詞優(yōu)化、全網(wǎng)營銷推廣、品牌網(wǎng)站建設、云服務器
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)