最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

原生JS發(fā)送異步數(shù)據(jù)請求

 更新時間:2017年06月08日 09:18:00   作者:Corner  
這篇文章主要為大家詳細介紹了原生JS發(fā)送異步數(shù)據(jù)請求的相關(guān)資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下

在做項目的時候,有時候需要用到異步數(shù)據(jù)請求,但是如果這個時候沒有框架的依賴,就需要用到原生JS進行異步數(shù)據(jù)請求。這時候無非有兩種請求方式,一種是AJAX,另一個是JSONP。通過原生JS對異步請求進行簡單的封裝。

AJAX

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

  • 創(chuàng)建XMLHttpRequest對象(new)
  • 連接服務(wù)器(open)
  • 發(fā)送請求(send)
  • 接收響應(yīng)數(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ā)生改變,接收響應(yīng)數(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') {
  //連接服務(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);
 }
},
/**
* 格式化數(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ù)來連接服務(wù)器,主要接收三個參數(shù):請求方式、請求地址和是否異步請求(一般都是異步請求)。請求方式有兩種,GET和POST,GET是通過URL將數(shù)據(jù)提交到服務(wù)器的,POST則是通過將數(shù)據(jù)作為send方法的參數(shù)發(fā)送到服務(wù)器。

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

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

  在readystatechange事件中,先判斷響應(yīng)是否接收完成,然后判斷服務(wù)器是否成功處理請求,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標(biāo)簽可以跨域請求的特點,由其src屬性發(fā)送請求到服務(wù)器,服務(wù)器返回js代碼,網(wǎng)頁端接受響應(yīng),然后就直接執(zhí)行了,這和通過script標(biāo)簽引用外部文件的原理是一樣的。

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

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

  不說話直接貼代碼。

/**
* 通過JSONP的方式請求
* @param {[type]} params [description]
* @return {[type]}  [description]
*/
ajaxJSONP(params) {
 params.data = params.data || {};
 params.jsonp = params.jsonp || 'callback';
 // 設(shè)置傳遞給后臺的回調(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標(biāo)簽并插入到頁面中
 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);
 //為了得知此次請求是否成功,設(shè)置超時處理
 if (params.time) {
  script.timer = setTimeout(function() {
   window[callbackName] = null;
   head.removeChild(script);
   params.error && params.error({
    message: '超時'
   });
  }, params.time);
 }
}

  給script標(biāo)簽設(shè)置src屬性時瀏覽器就會去發(fā)送請求,但是只能發(fā)送一次請求,導(dǎo)致script標(biāo)簽不能復(fù)用,因此每次操作完都需要把script標(biāo)簽移除。在瀏覽器發(fā)送請求之前給全局綁定一個回調(diào)函數(shù),當(dāng)數(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';
  // 設(shè)置傳遞給后臺的回調(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標(biāo)簽并插入到頁面中
  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);
  //為了得知此次請求是否成功,設(shè)置超時處理
  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ā)生改變,接收響應(yīng)數(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') {
   //連接服務(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);
  }
 },
 /**
 * 格式化數(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)
 }
})

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • 紅黑樹的插入詳解及Javascript實現(xiàn)方法示例

    紅黑樹的插入詳解及Javascript實現(xiàn)方法示例

    這篇文章主要給大家介紹了關(guān)于紅黑樹的插入的相關(guān)資料,以及Javascript實現(xiàn)的方法,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起看看吧。
    2018-03-03
  • Javascript中正則表達式的全局匹配模式分析

    Javascript中正則表達式的全局匹配模式分析

    先看一道JavaScript題目,據(jù)說是國內(nèi)某知名互聯(lián)網(wǎng)企業(yè)的JavaScript筆試題,如果對正則的全局匹配模式不了解的話可能會對下面的輸出結(jié)果感到疑惑。
    2011-04-04
  • 純原生js實現(xiàn)table表格的增刪

    純原生js實現(xiàn)table表格的增刪

    本文主要介紹了純原生javascript實現(xiàn)table表格的增刪的方法,文章底部提供了完整的代碼。需要的朋友一起來看下吧
    2017-01-01
  • 微信小程序下拉框搜索功能的實現(xiàn)方法

    微信小程序下拉框搜索功能的實現(xiàn)方法

    這篇文章主要介紹了微信小程序下拉框搜索功能的實現(xiàn)方法,內(nèi)容比較簡單容易理解 ,需要的朋友可以參考下
    2019-07-07
  • 微信小程序自定義組件的實現(xiàn)方法及自定義組件與頁面間的數(shù)據(jù)傳遞問題

    微信小程序自定義組件的實現(xiàn)方法及自定義組件與頁面間的數(shù)據(jù)傳遞問題

    這篇文章主要介紹了微信小程序自定義組件的實現(xiàn)方法及自定義組件與頁面間的數(shù)據(jù)傳遞 ,需要的朋友可以參考下
    2018-10-10
  • 玩轉(zhuǎn)JavaScript OOP - 類的實現(xiàn)詳解

    玩轉(zhuǎn)JavaScript OOP - 類的實現(xiàn)詳解

    下面小編就為大家?guī)硪黄孓D(zhuǎn)JavaScript OOP - 類的實現(xiàn)詳解。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-06-06
  • JS模擬bootstrap下拉菜單效果實例

    JS模擬bootstrap下拉菜單效果實例

    這篇文章主要介紹了JS模擬bootstrap下拉菜單效果,結(jié)合完整實例形式分析了javascript動態(tài)操作頁面元素的相關(guān)技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2016-06-06
  • 微信小程序使用第三方庫Underscore.js步驟詳解

    微信小程序使用第三方庫Underscore.js步驟詳解

    大家都知道Underscore.js是一個 JavaScript 工具庫,它提供了一整套函數(shù)式編程的實用功能,但是沒有擴展任何 JavaScript 內(nèi)置對象。那么這篇文章我們就來學(xué)習(xí)下微信小程序如何使用第三方庫Underscore.js,有需要的可以參考學(xué)習(xí)。
    2016-09-09
  • uniapp中實現(xiàn)canvas超出屏幕滾動查看功能

    uniapp中實現(xiàn)canvas超出屏幕滾動查看功能

    親愛的小伙伴,當(dāng)你需要在uniapp中使用canvas繪制一個超長圖,就類似于橫向的流程圖時,這個canvas超出屏幕部分拖動屏幕查看會變得十分棘手,怎么解決這個問題呢,下面小編給大家介紹uniapp中實現(xiàn)canvas超出屏幕滾動查看功能,感興趣的朋友一起看看吧
    2024-03-03
  • webpack4.0打包優(yōu)化策略整理小結(jié)

    webpack4.0打包優(yōu)化策略整理小結(jié)

    這篇文章主要介紹了webpack4.0打包優(yōu)化策略整理小結(jié),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-03-03

最新評論

阳江市| 定襄县| 浦县| 巨野县| 丽水市| 图们市| 象州县| 宁国市| 无极县| 兴国县| 老河口市| 汝州市| 青龙| 涟水县| 海伦市| 南投县| 阳春市| 石台县| 凤冈县| 漳州市| 会东县| 政和县| 西乡县| 亚东县| 庄河市| 邻水| 海阳市| 任丘市| 巴南区| 连云港市| 北辰区| 墨脱县| 阳山县| 桃源县| 寿阳县| 通山县| 乐业县| 乌拉特后旗| 金堂县| 吴旗县| 富顺县|