亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > JavaScript > 正文

AngularJS出現$http異步后臺無法獲取請求參數問題的解決方法

2019-11-20 08:36:24
字體:
來源:轉載
供稿:網友

本文實例講述了AngularJS出現$http異步后臺無法獲取請求參數問題的解決方法。分享給大家供大家參考,具體如下:

angular在通過異步提交數據時使用了與jQuery不一樣的請求頭部和數據序列化方式,導致部分后臺程序無法正常解析數據。

原理分析(網上的分析):

對于AJAX應用(使用XMLHttpRequests)來說,向服務器發起請求的傳統方式是:獲取一個XMLHttpRequest對象的引用、發起請求、讀取響應、檢查狀態碼,最后處理服務端的響應。整個過程示例如下:

var xmlhttp = new XMLHttpRequest();xmlhttp.onreadystatechange = function() {  if(xmlhttp.readystate == 4 && xmlhttp.status == 200) {    var response = xmlhttp.responseText;  }else if(xmlhttp.status == 400) { //或者可以是任何以4開頭的狀態碼    //優雅地處理錯誤  }};//建立連接xmlhttp.open("GET", "http://myserver/api", true);//發起請求xmlhttp.send();

對于簡單、常用而且會經常重復的任務來說,這是一種很煩瑣的工作。如果你想復用以上過程,你應該進行封裝或者使用代碼庫。

AngularJS XHR API遵守一種通常被稱為Promise的接口。由于XHR是異步調用的方法,所以服務端的響應會在未來某個不確定的時間點上返回(我們希望它立即能返回)。Promise接口規定了處理這種響應的方式,并且允許Promise的使用者以一種可預見的方式來使用它。

例如,我們要從服務端獲取一個用戶的信息,假設用來接受請求的后臺接口位于/api/user路徑上,此接口可以接受一個id屬性作為URL參數,那么使用Angular的核心$http服務發起XHR請求的方法示例如下:

$http.get('api/user', {params: {id:'5'}}).success(function(data, status, headers, config) {  //加載成功之后做一些事}).error(function(data, status, headers, config) {  //處理錯誤});

如果你是jQuery使用者,你應該會發現,AngularJS和jQuery在對異步請求的處理方面非常類似。

上面例子中使用的$http.get方法是AngularJS的核心服務$http所提供的眾多快捷方法之一。類似地,如果你想使用AngularJS向同一個URL發送POST請求,同時帶上一些POST數據,你可以像下面這樣做:

var postData = {text:'long blob of text'};//下面這一行會被當成參數附加到URL后面,所以post請求最終會變成/api/user?id=5var config = {params: {id: '5'}};$http.post('api/user', postData, config).success(function(data, status, headers, config) {  //成功之后做一些事情}).error(function(data, status, headers, config) {  //處理錯誤});

對于大多數常用的請求類型,都有類似的快捷方法,這些請求類型包括:GET、HEAD、POST、DELETE、PUT、JSONP。

一.進一步配置請求

雖然標準的請求方式使用起來比較簡單,但是,有時候會存在可配置性不佳的缺點。如果你想要實現下面這些事情就會遇到困難:

a.給請求加上一些授權頭。
b.修改對緩存的處理方式。
c.用一些特殊的方式來變換發送出去的請求,或者變換接收到的響應。

在這些情況下,你可以給請求傳遞一個可選的配置對象,從而對請求進行深度配置。在前面的例子中,我們使用config對象指定了一個可選的URL參數。但是那里的GET和POST方法是一些快捷方式。這種深度簡化之后的方法調用示例如下:

$http(config)

下面是一個基本的偽代碼模板,用來調用前面的這個方法:

$http({  method: string,  url: string,  params: object,  data: string or object,  headers: object,  transformRequest: function transform(data, headersGetter) or an array of functions,  transformResponse: function transform(data, headersGetter) or an array of functions,  cache: boolean or Cache object,  timeout: number,  withCredentials: boolean});

GET、POST及其他快捷方法都會自動設置method參數,所以不需要手動設置。config對象會作為最后一個參數傳遞給$http.get和$http.post,所以,在所有的快捷方法內部都可以使用這個參數。你可以傳遞config對象來修改發送的請求,config對象可以設置以下鍵值。

method:一個字符串,表示HTTP請求的類型,例如GET或者POST。
url:URL字符串,表示請求的絕對或者相對資源路徑。
params:一個鍵和值都是字符串的對象(確切來說是一個map),表示需要轉換成URL參數的鍵和值。例如:

[{key1: 'value1', key2: 'value2'}]

將會被轉換成

?key1=value&key2=value2

并會被附加到URL后面。如果我們使用js對象(而不是字符串或者數值)作為map中的值,那么這個js對象會被轉換成JSON字符串。

data:一個字符串或者對象,它會被當作請求數據發送。
timeout:在請求超時之前需要等待的毫秒數。

二.設置HTTP頭

AngularJS帶有一些默認的請求頭,Angular發出的所有請求上都會帶有這些默認的請求頭信息。默認請求頭包括以下兩個:

1.Accept:appliction/json,text/pain,/
2.X-Requested-With: XMLHttpRequest

如果想設置特殊的請求頭,可以用如下兩種方法實現。

第一種方法,如果你想把請求頭設置到每一個發送出去的請求上,那么你可以把需要使用的特殊請求頭設置成AngularJS的默認值。這些值可以通過$httpProvider.defaults.headers配置對象來設置,通常會在應用的配置部分來做這件事情。所以,如果你想對所有的GET請求使用“DO NOT TRACK"頭,同時對所有請求刪除Requested-With頭,可以簡單地操作如下:

angular.module('MyApp', []).  config(function($httpProvider) {    //刪除AngularJS默認的X-Request-With頭    delete $httpProvider.default.headers.common['X-Requested-With'];    //為所有GET請求設置DO NOT TRACK    $httpProvider.default.headers.get['DNT'] = '1';});

如果你只想對某些特定的請求設置請求頭,但不把它們作為默認值,那么你可以把頭信息作為配置對象的一部分傳遞給$http服務。同樣的,自定義頭信息也可以作為第二個參數的一部分傳遞給GET請求,第二個參數還可以同時接受URL參數。

$http.get('api/user', {   //設置Authorization(授權)頭。在真實的應用中,你需要到一個服務里面去獲取auth令牌   headers: {'Authorization': 'Basic Qzsda231231'},   params: {id:5}}).success(function() {//處理成功的情況 });

三.緩存響應

對于HTTP GET請求,AngularJS提供了一個開箱即用的簡單緩存機制。默認情況下它對所有請求類型都不可用,為了啟用緩存,你需要做一些配置:

$http.get('http://server/myapi', {  cache: true}).success(function() {//處理成功的情況});

這樣就可以啟用緩存,然后AngularJS將會緩存來自服務器的響應。下一次向同一個URL發送請求的時候,AngularJS將會返回緩存中的響應內容。緩存也是智能的,所以即使你向同一個URL發送多次模擬的請求,緩存也只會向服務器發送一個請求,而且在收到服務端的響應之后,響應的內容會被分發給所有請求。

但是,這樣做有些不太實用,因為用戶會先看到緩存的舊結果,然后看到新的結果突然出現。例如,當用戶即將點擊一條數據時,它可能會突然發生變化。

注意,從本質上來說,響應(即使是從緩存中讀取的)依然是異步的。換句話說,在第一次發出請求的時候,你應該使用處理異步請求的方式來編碼。

四.轉換請求和響應

對于所有通過$http服務發出的請求和收到的響應來說,AngularJS都會進行一些基本的轉換,包括如下內容。

1.轉換請求

如果請求的配置對象屬性中包含JS對象,那么就把這個對象序列化成JSON格式。

2.轉換響應

如果檢測到了XSRF(Cross Site Request Forgery的縮寫,意為跨站請求偽造,這是跨站腳本攻擊的一種方式)前綴,則直接丟棄。如果檢測到了JSON響應,則使用JSON解析器對它進行反序列化。

如果你不需要其中的某些轉換,或者想自已進行轉換,可以在配置項里面傳入自已的函數。這些函數會獲取HTTP的request/response體以及協議頭信息,然后輸出序列化、修改之后的版本??梢允褂胻ransformLRequest和transformResponse作為key來配置這些轉換函數,而這兩個函數在模塊的config函數中是用$httpProvider服務來配置的。

我們什么時候需要使用這些東西呢?假設我們有一個服務,它更適合用jQuery的方式來操作。POST數據使用key1=val1&key2=val2(也就是字符串)形式來代替{key1:val1, key2:val2}JSON格式。我們可以在每個請求中來進行這種轉換,也可以添加一個獨立transformRequest調用,對于當前這個例子來說,我們打算添加一個通用的transformRequest,這樣所有發出的請求都會進行這種從JSON到字符串的轉換。下面就是實現方式:

var module = angular.module('myApp');module.config(function($httpProvider) {  $httpProvider.defaults.transformRequest = function(data) {     //使用jQuery的param方法把JSON數據轉換成字符串形式     return $.param(data);   };});

實列配置:

在使用中發現后臺程序還是無法解析angular提交的數據,對比后發現頭部缺少‘X-Requested-With'項

所以在配置中加入:

復制代碼 代碼如下:
$httpProvider.defaults.headers.post['X-Requested-With'] = 'XMLHttpRequest'

下面貼入測試時的部分配置代碼:

angular.module('app', [  'ngAnimate',  'ngCookies',  'ngResource',  'ngRoute',  'ngSanitize',  'ngTouch'],function ($httpProvider) {  // 頭部配置  $httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=utf-8';  $httpProvider.defaults.headers.post['Accept'] = 'application/json, text/javascript, */*; q=0.01';  $httpProvider.defaults.headers.post['X-Requested-With'] = 'XMLHttpRequest';  /**   * 重寫angular的param方法,使angular使用jquery一樣的數據序列化方式 The workhorse; converts an object to x-www-form-urlencoded serialization.   * @param {Object} obj   * @return {String}   */  var param = function (obj) {    var query = '', name, value, fullSubName, subName, subValue, innerObj, i;    for (name in obj) {      value = obj[name];      if (value instanceof Array) {        for (i = 0; i < value.length; ++i) {          subValue = value[i];          fullSubName = name + '[' + i + ']';          innerObj = {};          innerObj[fullSubName] = subValue;          query += param(innerObj) + '&';        }      }      else if (value instanceof Object) {        for (subName in value) {          subValue = value[subName];          fullSubName = name + '[' + subName + ']';          innerObj = {};          innerObj[fullSubName] = subValue;          query += param(innerObj) + '&';        }      }      else if (value !== undefined && value !== null)        query += encodeURIComponent(name) + '=' + encodeURIComponent(value) + '&';    }    return query.length ? query.substr(0, query.length - 1) : query;  };  // Override $http service's default transformRequest  $httpProvider.defaults.transformRequest = [function (data) {    return angular.isObject(data) && String(data) !== '[object File]' ? param(data) : data;  }];}).config(function ($routeProvider) {    $routeProvider      .when('/', {        templateUrl: 'views/main.html',        controller: 'MainCtrl'      })      .when('/about', {        templateUrl: 'views/about.html',        controller: 'AboutCtrl'      })      .otherwise({        redirectTo: '/'      });  });

希望本文所述對大家AngularJS程序設計有所幫助。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
视频一区视频二区国产精品| 少妇高潮久久77777| 久久久久久久网站| 久久久国产精品x99av| 亚洲人成在线观| 亚洲最大成人在线| 8x海外华人永久免费日韩内陆视频| 亚洲人成电影网站| 日韩精品有码在线观看| 欧美视频免费在线观看| 国产亚洲精品美女久久久| 日韩激情片免费| 一本色道久久综合狠狠躁篇怎么玩| 欧美韩日一区二区| 最新亚洲国产精品| 亚洲精品美女在线| 中文字幕精品在线| 亚洲性线免费观看视频成熟| 欧美亚洲国产精品| 5278欧美一区二区三区| 欧美日韩国产91| 国产精品揄拍一区二区| 91久久精品国产91久久性色| 国产日韩换脸av一区在线观看| 亚洲一区二区久久久久久久| 日韩三级影视基地| 7m精品福利视频导航| 国产精品福利网站| 日韩风俗一区 二区| 成人黄色免费在线观看| 欧美性猛交xxxxx免费看| 国产亚洲成av人片在线观看桃| 97精品视频在线观看| 26uuu另类亚洲欧美日本一| 欧美在线亚洲在线| 亚洲日本aⅴ片在线观看香蕉| 亚洲电影免费观看高清完整版| 91久久精品国产91久久性色| 亚洲精品xxxx| 国色天香2019中文字幕在线观看| 永久免费精品影视网站| 欧美大片在线看| 国产成人精品免费视频| 亚洲国产女人aaa毛片在线| 欧美乱人伦中文字幕在线| 2019中文字幕全在线观看| 不卡伊人av在线播放| 日韩大陆毛片av| 国产美女精彩久久| 精品国产91久久久久久老师| 日韩精品中文字幕有码专区| 国产一区二区日韩| 国产精品色午夜在线观看| 亚洲性生活视频| 中文字幕欧美视频在线| 91精品久久久久久久久久久久久久| 国产亚洲一区精品| 国产成人aa精品一区在线播放| 91av在线免费观看视频| 国产欧美在线观看| 午夜精品视频在线| 国产精品日韩在线观看| 中文国产亚洲喷潮| 国产欧美精品在线播放| 亚洲精品美女免费| 91精品在线国产| 日韩在线观看精品| 日韩免费中文字幕| 69视频在线播放| 久久免费精品视频| 国产精品美女免费视频| 日韩av影视在线| 精品高清美女精品国产区| 亚洲视频一区二区三区| 久久精品人人爽| 亚洲精品视频在线播放| 91免费福利视频| 国产午夜精品全部视频播放| 国产在线拍揄自揄视频不卡99| 日韩精品在线播放| 久久亚洲精品成人| 精品av在线播放| 欧美午夜www高清视频| 欧美色道久久88综合亚洲精品| 久久国产天堂福利天堂| 国产精品三级美女白浆呻吟| xxxxx成人.com| 亚洲偷欧美偷国内偷| 日韩精品在线影院| www.亚洲成人| 最近2019年好看中文字幕视频| 在线亚洲国产精品网| 91精品久久久久久久久久久久久| 欧美精品一二区| 欧美精品999| 亚洲欧洲日产国产网站| 欧美日韩国产精品一区二区不卡中文| 国产精品视频免费观看www| 亚洲精品一区二区三区不| 国产精品成人国产乱一区| 日韩精品视频在线观看免费| 国产精品白嫩初高中害羞小美女| 国产成人一区二区三区小说| 精品国产拍在线观看| 日韩欧美国产激情| 日韩欧美在线视频观看| 亚洲xxx自由成熟| 欧美视频在线观看免费网址| 狠狠躁夜夜躁人人爽超碰91| 992tv成人免费视频| 亚洲欧美成人在线| 欧美性猛交xxxx免费看漫画| 日韩中文在线中文网三级| 亚洲激情免费观看| 亚洲美女精品成人在线视频| 日韩中文字幕在线视频| 久久国产精品亚洲| 成人免费观看49www在线观看| 91精品久久久久久久久久另类| 在线观看日韩www视频免费| 国产精品第10页| 高清视频欧美一级| 国产精品海角社区在线观看| 中文字幕亚洲综合久久筱田步美| 国产91在线播放| 奇门遁甲1982国语版免费观看高清| 久久伊人精品一区二区三区| 日韩成人在线观看| 热99精品只有里视频精品| 亚洲无限乱码一二三四麻| 亚洲成人激情视频| 欧美色xxxx| 亚洲精品99999| 欧美性xxxx极品hd满灌| 欧美三级欧美成人高清www| 亚洲欧美在线一区| 欧美黑人极品猛少妇色xxxxx| 日韩欧美亚洲综合| 久久视频免费在线播放| www.xxxx精品| 国产精品看片资源| 97国产成人精品视频| 欧美专区在线播放| 亚洲欧美国产va在线影院| 三级精品视频久久久久| 亚洲另类欧美自拍| 欧美高清第一页| 免费91麻豆精品国产自产在线观看| 深夜精品寂寞黄网站在线观看| 欧美精品在线网站| 久久夜色精品国产欧美乱| 精品亚洲va在线va天堂资源站| 久久久久久91香蕉国产| 黄色一区二区三区| 国产精品黄色影片导航在线观看| 91精品国产综合久久香蕉最新版| 日韩欧美亚洲范冰冰与中字| 97视频在线观看免费高清完整版在线观看| 日韩中文字幕精品视频| 久久久久久久久久久成人| 亚洲片av在线| 色多多国产成人永久免费网站| 92福利视频午夜1000合集在线观看| 成人亲热视频网站|