欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

AngularJS出現(xiàn)$http異步后臺無法獲取請求參數(shù)問題的解決方法

 更新時間:2016年11月03日 08:53:02   作者:kooky798  
這篇文章主要介紹了AngularJS出現(xiàn)$http異步后臺無法獲取請求參數(shù)問題的解決方法,較為詳細的分析了AngularJS出現(xiàn)異步請求后臺無法解析的原因與相應(yīng)的解決方法,需要的朋友可以參考下

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

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

原理分析(網(wǎng)上的分析):

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

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

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

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

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

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

如果你是jQuery使用者,你應(yīng)該會發(fā)現(xiàn),AngularJS和jQuery在對異步請求的處理方面非常類似。

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

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

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

一.進一步配置請求

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

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

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

$http(config)

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

$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及其他快捷方法都會自動設(shè)置method參數(shù),所以不需要手動設(shè)置。config對象會作為最后一個參數(shù)傳遞給$http.get和$http.post,所以,在所有的快捷方法內(nèi)部都可以使用這個參數(shù)。你可以傳遞config對象來修改發(fā)送的請求,config對象可以設(shè)置以下鍵值。

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

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

將會被轉(zhuǎn)換成

?key1=value&key2=value2

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

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

二.設(shè)置HTTP頭

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

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

如果想設(shè)置特殊的請求頭,可以用如下兩種方法實現(xiàn)。

第一種方法,如果你想把請求頭設(shè)置到每一個發(fā)送出去的請求上,那么你可以把需要使用的特殊請求頭設(shè)置成AngularJS的默認值。這些值可以通過$httpProvider.defaults.headers配置對象來設(shè)置,通常會在應(yīng)用的配置部分來做這件事情。所以,如果你想對所有的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請求設(shè)置DO NOT TRACK
    $httpProvider.default.headers.get['DNT'] = '1';
});

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

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

三.緩存響應(yīng)

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

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

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

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

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

四.轉(zhuǎn)換請求和響應(yīng)

對于所有通過$http服務(wù)發(fā)出的請求和收到的響應(yīng)來說,AngularJS都會進行一些基本的轉(zhuǎn)換,包括如下內(nèi)容。

1.轉(zhuǎn)換請求

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

2.轉(zhuǎn)換響應(yīng)

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

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

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

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

實列配置:

在使用中發(fā)現(xiàn)后臺程序還是無法解析angular提交的數(shù)據(jù),對比后發(fā)現(xiàn)頭部缺少‘X-Requested-With'項

所以在配置中加入:

復(fù)制代碼 代碼如下:
$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一樣的數(shù)據(jù)序列化方式 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程序設(shè)計有所幫助。

相關(guān)文章

  • 詳解封裝基礎(chǔ)的angular4的request請求方法

    詳解封裝基礎(chǔ)的angular4的request請求方法

    這篇文章主要介紹了詳解封裝基礎(chǔ)的angular4的request請求方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-06-06
  • AngularJS使用ui-route實現(xiàn)多層嵌套路由的示例

    AngularJS使用ui-route實現(xiàn)多層嵌套路由的示例

    這篇文章主要介紹了AngularJS使用ui-route實現(xiàn)多層嵌套路由的示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-01-01
  • AngularJS入門教程之模塊化操作用法示例

    AngularJS入門教程之模塊化操作用法示例

    這篇文章主要介紹了AngularJS模塊化操作用法,結(jié)合實例形式分析了AngularJS基于模塊化操作避免命名沖突的相關(guān)操作技巧,需要的朋友可以參考下
    2016-11-11
  • Angular2使用Angular-CLI快速搭建工程(二)

    Angular2使用Angular-CLI快速搭建工程(二)

    這篇文章主要介紹了Angular2使用Angular-CLI快速搭建工程(二),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-05-05
  • 詳解angular2如何手動點擊特定元素上的點擊事件

    詳解angular2如何手動點擊特定元素上的點擊事件

    這篇文章主要介紹了詳解angular2如何手動點擊特定元素上的點擊事件,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-10-10
  • AngularJS教程之MVC體系結(jié)構(gòu)詳解

    AngularJS教程之MVC體系結(jié)構(gòu)詳解

    本文主要講解AngularJS MVC體系結(jié)構(gòu),這里提供詳細的教程供大家學習參考,有需要的小伙伴可以參考下
    2016-08-08
  • AngularJS控制器繼承自另一控制器

    AngularJS控制器繼承自另一控制器

    本文給大家介紹AngularJS控制器繼承自另一控制器的相關(guān)內(nèi)容,小編認為介紹的非常不錯,具有參考借鑒價值,感興趣的朋友參考下吧
    2016-05-05
  • AngularJs頁面篩選標簽小功能

    AngularJs頁面篩選標簽小功能

    AngularJS 是一個 JavaScript 框架。它可通過 <script> 標簽添加到 HTML 頁面。本文重點給大家介紹AngularJs頁面篩選標簽小功能,非常不錯,需要的朋友可以參考下
    2016-08-08
  • 解決AngualrJS頁面刷新導(dǎo)致異常顯示問題

    解決AngualrJS頁面刷新導(dǎo)致異常顯示問題

    本篇文章主要介紹了解決AngualrJS頁面刷新導(dǎo)致異常顯示問題的方法。具有很好的參考價值。下面跟著小編一起來看下吧
    2017-04-04
  • 深入淺析Angular SSR

    深入淺析Angular SSR

    Angular Universal 主要關(guān)注將 Angular App 如何進行服務(wù)端渲染和生成靜態(tài) HTML,對于用戶交互復(fù)雜的 SPA 并不推薦使用 SSR,本文是在 Angular 14 環(huán)境中完成,有些內(nèi)容對于新的 Angular 版本可能并不適用,感興趣的朋友一起通過本文學習
    2022-11-11

最新評論