国产成人精品18p,天天干成人网,无码专区狠狠躁天天躁,美女脱精光隐私扒开免费观看

原生JS如何發(fā)送異步數據請求

發(fā)布時(shí)間:2021-07-27 11:48 來(lái)源:億速云 閱讀:0 作者:小新 欄目: web開(kāi)發(fā)

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

在做項目的時(shí)候,有時(shí)候需要用到異步數據請求,但是如果這個(gè)時(shí)候沒(méi)有框架的依賴(lài),就需要用到原生JS進(jìn)行異步數據請求。這時(shí)候無(wú)非有兩種請求方式,一種是AJAX,另一個(gè)是JSONP。通過(guò)原生JS對異步請求進(jìn)行簡(jiǎn)單的封裝。

AJAX

  AJAX是一種數據請求方式,不需要刷新整個(gè)頁(yè)面就能夠更新局部頁(yè)面的數據。AJAX的技術(shù)核心是XMLHttpRequest對象,主要請求過(guò)程如下:

  • 創(chuàng )建XMLHttpRequest對象(new)

  • 連接(open)

  • 發(fā)送請求(send)

  • 接收響應數據(onreadystatechange)

  不說(shuō)話(huà)直接貼代碼

/**
* 通過(guò)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ā)生改變,接收響應數據
 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') {
  //連接服務(wù)器
  xhr.open('GET', (!!formatedParams ? params.url + '?' + formatedParams : params.url), true);
  //發(fā)送請求
  xhr.send();
 } else {
  //連接服務(wù)器
  xhr.open('POST', params.url, true);
  xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
  //發(fā)送請求
  xhr.send(formatedParams);
 }
},
/**
* 格式化數據
* @param {Obj}  data 需要格式化的數據
* @param {Boolean} isCache 是否加入隨機參數
* @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對象是通過(guò)MSXML庫中的一個(gè)ActiveXObject對象實(shí)現的。

  通過(guò)xhr的open函數來(lái)連接服務(wù)器,主要接收三個(gè)參數:請求方式、請求地址和是否異步請求(一般都是異步請求)。請求方式有兩種,GET和POST,GET是通過(guò)URL將數據提交到服務(wù)器的,POST則是通過(guò)將數據作為send方法的參數發(fā)送到服務(wù)器。

  給xhr綁定狀態(tài)改變函數onreadystatechange,主要用來(lái)檢測xhr的readyState的變化,當異步發(fā)送成功后,readyState的數值會(huì )由0變成4,同時(shí)觸發(fā)onreadystatechange事件。readyState的屬性及對應狀態(tài)如下:

0 (未初始化) 對象已建立,但是尚未初始化(尚未調用open方法)
1 (初始化) 對象已建立,尚未調用send方法
2 (發(fā)送數據) send方法已調用,但是當前的狀態(tài)及http頭未知
3 (數據傳送中) 已接收部分數據,因為響應及http頭不全,這時(shí)通過(guò)responseBody和responseText獲取部分數據會(huì )出現錯誤
4 (完成) 數據接收完畢,此時(shí)可以通過(guò)通過(guò)responseBody和responseText獲取完整的回應數據

  在readystatechange事件中,先判斷響應是否接收完成,然后判斷服務(wù)器是否成功處理請求,xhr.status 是狀態(tài)碼,狀態(tài)碼以2開(kāi)頭的都是成功,304表示從緩存中獲取,上面的代碼在每次請求的時(shí)候都加入了隨機數,所以不會(huì )從緩存中取值,故該狀態(tài)不需判斷。

JSONP

  如果還是用上面的XMLHttpRequest對象來(lái)發(fā)送需要跨域的請求,雖然調用了send函數,但是xhr的狀態(tài)一直都是0,也不會(huì )觸發(fā)onreadystatechange事件,這個(gè)時(shí)候就要用到JSONP的請求方式了。

  JSONP(JSON with Padding) 是一種跨域請求方式。主要原理是利用了script標簽可以跨域請求的特點(diǎn),由其src屬性發(fā)送請求到服務(wù)器,服務(wù)器返回js代碼,網(wǎng)頁(yè)端接受響應,然后就直接執行了,這和通過(guò)script標簽引用外部文件的原理是一樣的。

  JSONP由兩部分組成:回調函數和數據,回調函數一般是由網(wǎng)頁(yè)端控制,作為參數發(fā)往服務(wù)器端,服務(wù)器端把該函數和數據拼成字符串返回。

  比如網(wǎng)頁(yè)端創(chuàng )建一個(gè)script標簽,并給其src賦值為http://www.test.com/json/?callback=process, 此時(shí)網(wǎng)頁(yè)端就發(fā)起一個(gè)請求。服務(wù)端將要返回的數據拼作為函數的參數傳入,服務(wù)端返回的數據格式類(lèi)似”process({‘name:'xieyufei'})”,網(wǎng)頁(yè)端接收到了響應值,因為請求者是 script,所以相當于直接調用process方法,并且傳入了一個(gè)參數。

  不說(shuō)話(huà)直接貼代碼。

/**
* 通過(guò)JSONP的方式請求
* @param {[type]} params [description]
* @return {[type]}  [description]
*/
ajaxJSONP(params) {
 params.data = params.data || {};
 params.jsonp = params.jsonp || 'callback';
 // 設置傳遞給后臺的回調參數名和參數值
 var callbackName = 'jsonp_' + (new Date()).getTime();
 params.data[params.jsonp] = callbackName;
 var formatedParams = this.formateParams(params.data, params.cache);
 //創(chuàng  )建script標簽并插入到頁(yè)面中
 var head = document.getElementsByTagName('head')[0];
 var script = document.createElement('script');
 head.appendChild(script);
 //創(chuàng  )建jsonp回調函數 
 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);
 //為了得知此次請求是否成功,設置超時(shí)處理
 if (params.time) {
  script.timer = setTimeout(function() {
   window[callbackName] = null;
   head.removeChild(script);
   params.error && params.error({
    message: '超時(shí)'
   });
  }, params.time);
 }
}

  給script標簽設置src屬性時(shí)瀏覽器就會(huì )去發(fā)送請求,但是只能發(fā)送一次請求,導致script標簽不能復用,因此每次操作完都需要把script標簽移除。在瀏覽器發(fā)送請求之前給全局綁定一個(gè)回調函數,當數據請求成功時(shí)就會(huì )調用這個(gè)回調函數。

總結

  將兩種發(fā)送異步數據的方式整合起來(lái),根據dataType來(lái)進(jìn)行判斷選用哪種方式。貼上完整的代碼

var xyfAjax = {
 ajax: function(params) {
  params = params || {};
  params.cache = params.cache || false;
  if (!params.url) {
   throw new Error('參數不合法');
  }
  params.dataType = (params.dataType || 'json').toLowerCase();
  if (params.dataType == 'jsonp') {
   this.ajaxJSONP(params);
  } else if (params.dataType == 'json') {
   this.ajaxJSON(params);
  }
 },
 /**
 * 通過(guò)JSONP的方式請求
 * @param {[type]} params [description]
 * @return {[type]}  [description]
 */
 ajaxJSONP(params) {
  params.data = params.data || {};
  params.jsonp = params.jsonp || 'callback';
  // 設置傳遞給后臺的回調參數名和參數值
  var callbackName = 'jsonp_' + (new Date()).getTime();
  params.data[params.jsonp] = callbackName;
  var formatedParams = this.formateParams(params.data, params.cache);
  //創(chuàng  )建script標簽并插入到頁(yè)面中
  var head = document.getElementsByTagName('head')[0];
  var script = document.createElement('script');
  head.appendChild(script);
  //創(chuàng  )建jsonp回調函數 
  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);
  //為了得知此次請求是否成功,設置超時(shí)處理
  if (params.time) {
   script.timer = setTimeout(function() {
    window[callbackName] = null;
    head.removeChild(script);
    params.error && params.error({
     message: '超時(shí)'
    });
   }, params.time);
  }
 },
 /**
 * 通過(guò)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ā)生改變,接收響應數據
  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') {
   //連接服務(wù)器
   xhr.open('GET', (!!formatedParams ? params.url + '?' + formatedParams : params.url), true);
   //發(fā)送請求
   xhr.send(null);
  } else {
   //連接服務(wù)器
   xhr.open('POST', params.url, true);
   xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
   //發(fā)送請求
   xhr.send(formatedParams);
  }
 },
 /**
 * 格式化數據
 * @param {Obj}  data 需要格式化的數據
 * @param {Boolean} isCache 是否加入隨機參數
 * @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)
 }
})

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng )、來(lái)自互聯(lián)網(wǎng)轉載和分享為主,文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權請聯(lián)系站長(cháng)郵箱:ts@56dr.com進(jìn)行舉報,并提供相關(guān)證據,一經(jīng)查實(shí),將立刻刪除涉嫌侵權內容。

js
免费中文熟妇在线影片| 最新日韩精品中文字幕| 欧美老妇大p毛茸茸| 亚洲第一区无码专区| 一本久道高清无码视频| 女人和拘做受A级毛片|