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

理解Angular的providers給Http添加默認headers

 更新時間:2017年07月04日 09:46:48   作者:Mavlarn  
本篇文章主要介紹了理解Angular的providers給Http添加默認headers,具有一定的參考價值,有興趣的同學(xué)可以了解一下

在一般的web應(yīng)用里,經(jīng)常會需要在每次發(fā)送Http請求的時候,添加header或者一些默認的參數(shù)。本文就來看看這個需求的幾種實現(xiàn)方式。通過這個實現(xiàn),我們也能夠理解Angular的服務(wù),及其providers的原理。

我們的目的是對于每個Http請求,都往Header里面添加一個token,用于在服務(wù)器端進行身份驗證。因為Http是一個服務(wù),所以我就想當(dāng)然的想到,我可以通過擴展框架提供的Http來添加。那么要怎么擴展一個框架提供的服務(wù)呢?那就是用providers。

NgModule里,有一個屬性providers,一般我們是用它來告訴框架,我們的app要用到我們定義的某些服務(wù),例如我寫了一個UserService用來進行用戶數(shù)據(jù)的讀寫操作,又比如寫一個AuthGuardService來實現(xiàn)路由的Guard。對于框架或者使用的其他組件庫的服務(wù),我們不需要在這里添加,只需要在imports里面加入相應(yīng)的模塊即可。

自定義系統(tǒng)服務(wù)

那么,如果我們想修改框架提供的某個服務(wù),例如想擴展它,該怎么實現(xiàn)呢?我們可以將擴展的這個服務(wù),添加到providers里,只是添加的方式不太一樣。需要使用下面的方式:

@NgModule({
 declarations: [
  AppComponent
 ],
 imports: [
  BrowserModule, RouterModule, HttpModule
 ],
 providers: [UserService, AuthGuardService,
  { provide: Http, useClass: BaseHttp }
 ],
 bootstrap: [ AppComponent ]
})

我們擴展了Http服務(wù),新的服務(wù)的類名是BaseHttp,然后在providers里使用{ provide: Http, useClass: BaseHttp },告訴框架,我們要使用BaseHttp這個類,來提供對Http的實現(xiàn)。然后,在Angular的容器里面的Http服務(wù)實際上是BaseHttp這個類的實現(xiàn),當(dāng)我們通過注入獲得一個Http實例的時候,也是獲得的BaseHttp的實例。

實現(xiàn)自動添加Header

接下來,我們就來看看怎么實現(xiàn)自動的Header的添加。首先,我想到的第一種方式,就是擴展Http,在它的構(gòu)造函數(shù)里設(shè)置一個默認的Header。

在構(gòu)造函數(shù)中實現(xiàn)

@Injectable()
export class BaseHttp extends Http {
 constructor (backend: XHRBackend, options: RequestOptions) {
  super(backend, options);
  let token = localStorage.getItem(AppConstants.tokenName);
  options.headers.set(AppConstants.authHeaderName, token);
 }
}

這個就是在構(gòu)造函數(shù)里面,從localStorage里拿到token,然后放到RequestOptions里??粗坪鯖]有問題,但是運行的時候發(fā)現(xiàn),這個Http服務(wù)是在app初始化的時候創(chuàng)建的,所以這個構(gòu)造函數(shù)在調(diào)用的時候,localStorage里可能還沒有token。這樣,即使用戶之后登陸了,之前的默認的options也不會更新。

在request中實現(xiàn)

所以,在構(gòu)造函數(shù)中實現(xiàn)肯定是不行的,我通過觀察Http的接口(通過你使用的IDE,可以跟蹤到接口的定義文件,來查看接口的定義),看到有很多方法get(...), post(...), put(...)等,如果我需要重新實現(xiàn)所有的這些方法,那就太麻煩了,感覺沒有必要。然后,我看到request(...)方法,看他的方法的注釋知道,所有其他方法最終都會調(diào)用這個方法來發(fā)送實際的請求。所以,我們只需要重寫這個方法就可以:

@Injectable()
export class BaseHttp extends Http {
 constructor (backend: XHRBackend, options: RequestOptions) {
  super(backend, options)
 }
 request(url: string|Request, options?: RequestOptionsArgs): Observable<Response> {
  const token = localStorage.getItem(AppConstants.tokenName)
  if (typeof url === 'string') { // meaning we have to add the token to the options, not in url
   if (!options) {
    options = new RequestOptions({})
   }
   options.headers.set(AppConstants.authHeaderName, token)
  } else {
   url.headers.set(AppConstants.authHeaderName, token)
  }
  return super.request(url, options)
 }
}

這個實現(xiàn)也很容易,唯一需要說明的是,這里的url它有可能有2種類型,string或Request,如果是string類型,說明這個url就是一個字符串,那么我們要設(shè)置的header肯定不會在它里面。

那如果url是Request類型呢?我們再來看看它的定義。通過看它的定義:

export declare class Request extends Body {
  /**
   * Http method with which to perform the request.
   */
  method: RequestMethod;
  /**
   * {@link Headers} instance
   */
  headers: Headers;
  /** Url of the remote resource */
  url: string;
  /** Type of the request body **/
  private contentType;
  /** Enable use credentials */
  withCredentials: boolean;
  /** Buffer to store the response */
  responseType: ResponseContentType;
  constructor(requestOptions: RequestArgs);
  /**
   * Returns the content type enum based on header options.
   */
  detectContentType(): ContentType;
  /**
   * Returns the content type of request's body based on its type.
   */
  detectContentTypeFromBody(): ContentType;
  /**
   * Returns the request's body according to its type. If body is undefined, return
   * null.
   */
  getBody(): any;
}

我們知道它是一個類,里面有一個成員headers,然后我們再看看Headers這個類型,看到它有一個set()方法,是用來往headers里面添加值的,這正是我們需要的。

所以,在我們實現(xiàn)的BaseHttp.request()方法里,根據(jù)url的類型,再判斷options是否為空等。通過測試,這種方法能夠?qū)崿F(xiàn)我們的需求,不管是初始化的時候在localStorage里面就有token,還是之后登陸,甚至退出后更新再登錄(會更新localStorage的token)等,都能滿足。

重新實現(xiàn) RequestOptions

雖然上面的方法以及能夠解決問題,那么,能不能再簡單一點呢?因為我們需要的只是更新Options,但是,為了這個,我們攔截了Http的請求。那我們是不是可以直接擴展RequestOptions來實現(xiàn)呢?答案是yes。而且更容易,我們可以繼承BaseRequestOptions,重寫merge(...)方法。

@Injectable()
export class AuthRequestOptions extends BaseRequestOptions {
 merge(options?: RequestOptionsArgs): RequestOptions {
  let newOptions = super.merge(options);
  let token = localStorage.getItem(AppConstants.tokenName);
  newOptions.headers.set(AppConstants.authHeaderName, token);
  return newOptions;
 }
}

這個merge(...)方法會在每次請求的時候被調(diào)用,用來把請求的時候的options和默認options進行合并。

經(jīng)過測試,這種方法也能夠完美的解決我們的需求。

總結(jié)

所以,這就是Angular強大與方便的地方,它使用了很多現(xiàn)象對象的特性,如繼承、接口、實現(xiàn)等;也用了很多服務(wù)器端Java框架的特性,例如容器等。上面說的provider也就是容器里面對象實例的提供者,本來RequestOptions類型的提供者是BaseRequestOptions,但是,我繼承了它,重寫了一個方法,把這個類型的提供者改成了我寫的類。這樣,Angular容器在初始化的時候,就會使用我提供的類來創(chuàng)建這個類型的實例。

而且,在這幾種實現(xiàn)方式的探索過程中,我完全沒有查看Angular的文檔,也沒有網(wǎng)上查什么資料。知識查看類或接口的定義,通過它的注釋,我就有了思路,然后嘗試實現(xiàn),就成功了。這也是TypeScript給我嗎帶來的遍歷。

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

相關(guān)文章

  • Angular.js初始化之ng-app的自動綁定與手動綁定詳解

    Angular.js初始化之ng-app的自動綁定與手動綁定詳解

    這篇文章主要給大家介紹了關(guān)于Angular.js初始化之ng-app的自動綁定與手動綁定的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家具有一定的參考學(xué)習(xí)價值,需要的朋友們下面跟著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-07-07
  • Angular中樣式綁定解決方案

    Angular中樣式綁定解決方案

    這篇文章主要介紹了Angular中樣式綁定解決方案,使用ngClass和ngStyle可以進行樣式的綁定,本文結(jié)合實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-08-08
  • Angular路由ui-router配置詳解

    Angular路由ui-router配置詳解

    這篇文章主要介紹了Angular路由ui-router配置詳解,非常不錯,具有一定得參考借鑒價值,需要的朋友參考下吧
    2018-08-08
  • 淺談Angular中ngModel的$render

    淺談Angular中ngModel的$render

    下面小編就為大家?guī)硪黄獪\談Angular中ngModel的$render。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-10-10
  • AngularJS基礎(chǔ)知識

    AngularJS基礎(chǔ)知識

    這篇文章主要介紹了AngularJS基礎(chǔ)知識,包括AngularJS定義和特點以及構(gòu)建AngularJS應(yīng)用的方法,推薦給大家。
    2014-12-12
  • Angular中使用Api 代理的實現(xiàn)

    Angular中使用Api 代理的實現(xiàn)

    我們對接的過程中總是遇到跨域的問題,本文使用 angualr 來講解代理api對接的話題,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-04-04
  • 解決nodejs中使用http請求返回值為html時亂碼的問題

    解決nodejs中使用http請求返回值為html時亂碼的問題

    下面小編就為大家?guī)硪黄鉀Qnodejs中使用http請求返回值為html時亂碼的問題。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-02-02
  • angular分頁指令操作

    angular分頁指令操作

    這篇文章主要為大家詳細介紹了angular分頁指令操作的相關(guān)資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-01-01
  • AngularJS 2.0新特性有哪些

    AngularJS 2.0新特性有哪些

    本文介紹了其在AtScript、改善依賴入駐、Annotations、路由方案等方面的改變。雖然不知道打破原有是否是件好事,不過由于不向后兼容,我們需要為遷移做好計劃
    2016-02-02
  • angularjs 的數(shù)據(jù)綁定實現(xiàn)原理

    angularjs 的數(shù)據(jù)綁定實現(xiàn)原理

    本篇文章主要介紹了angularjs 的數(shù)據(jù)綁定實現(xiàn)原理,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-07-07

最新評論

临潭县| 峡江县| 霍邱县| 项城市| 扬中市| 大洼县| 海丰县| 开封县| 朔州市| 农安县| 萍乡市| 瓦房店市| 嘉鱼县| 万荣县| 江阴市| 珲春市| 南京市| 双城市| 连山| 衢州市| 固阳县| 临漳县| 乐都县| 鄂伦春自治旗| 普洱| 汾西县| 中卫市| 长沙县| 太白县| 通江县| 铁岭市| 清水县| 南华县| 平江县| 祁阳县| 垦利县| 桃园市| 霍山县| 晴隆县| 城步| 石狮市|